]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Implement receive of valid small byte stuffed frames
authorFred Sundvik <fsundvik@gmail.com>
Sun, 14 Feb 2016 12:04:51 +0000 (14:04 +0200)
committerFred Sundvik <fsundvik@gmail.com>
Sun, 14 Feb 2016 12:04:51 +0000 (14:04 +0200)
serial_link/protocol/byte_stuffer.c
serial_link/protocol/byte_stuffer.h
serial_link/tests/byte_stuffer_tests.c

index 95ce86524f1fe9fc42d4c867e330fc159dd9193f..7ce01a96ab19355ba1677cb80f85acef24202231 100644 (file)
@@ -25,5 +25,39 @@ SOFTWARE.
 #include "protocol/byte_stuffer.h"
 #include "protocol/frame_validator.h"
 
-void recv_byte(uint8_t data) {
+// This implements the "Consistent overhead byte stuffing protocol"
+// https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing
+// http://www.stuartcheshire.org/papers/COBSforToN.pdf
+
+typedef struct byte_stuffer_state {
+    uint16_t next_zero;
+    uint16_t data_pos;
+    uint8_t data[256];
+}byte_stuffer_state_t;
+
+void init_byte_stuffer_state(byte_stuffer_state_t* state) {
+    state->next_zero = 0;
+    state->data_pos = 0;
+}
+
+void recv_byte(byte_stuffer_state_t* state, uint8_t data) {
+    if (state->next_zero == 0) {
+        state->next_zero = data;
+        state->data_pos = 0;
+        return;
+    }
+
+    state->next_zero--;
+    if (data == 0) {
+        recv_frame(state->data, state->data_pos);
+    }
+    else {
+        if (state->next_zero == 0) {
+            state->next_zero = data;
+            state->data[state->data_pos++] = 0;
+        }
+        else {
+            state->data[state->data_pos++] = data;
+        }
+    }
 }
index 3b9f9ea5d4899bfbb0af7e1f53a145d1ded47588..9a5551fab583de886617d957242fab47c53d6409 100644 (file)
@@ -22,4 +22,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 */
 
-void recv_byte(uint8_t data);
+typedef struct byte_stuffer_state byte_stuffer_state_t;
+void init_byte_stuffer_state(byte_stuffer_state_t* state);
+void recv_byte(byte_stuffer_state_t* state, uint8_t data);
index 418d48f6a4e79fc554503f6d59372453552ab4de..2fc7a0b26c83d1776f339b0cee236220d7adac53 100644 (file)
@@ -28,8 +28,12 @@ SOFTWARE.
 #include "protocol/byte_stuffer.c"
 #include "protocol/frame_validator.h"
 
+byte_stuffer_state_t state;
+
 Describe(ByteStuffer);
-BeforeEach(ByteStuffer) {}
+BeforeEach(ByteStuffer) {
+    init_byte_stuffer_state(&state);
+}
 AfterEach(ByteStuffer) {}
 
 void recv_frame(uint8_t* data, uint16_t size) {
@@ -38,15 +42,64 @@ void recv_frame(uint8_t* data, uint16_t size) {
 
 Ensure(ByteStuffer, receives_no_frame_for_a_single_zero_byte) {
     never_expect(recv_frame);
-    recv_byte(0);
+    recv_byte(&state, 0);
 }
 
 Ensure(ByteStuffer, receives_no_frame_for_a_single_FF_byte) {
     never_expect(recv_frame);
-    recv_byte(0xFF);
+    recv_byte(&state, 0xFF);
 }
 
 Ensure(ByteStuffer, receives_no_frame_for_a_single_random_byte) {
     never_expect(recv_frame);
-    recv_byte(0x4A);
+    recv_byte(&state, 0x4A);
+}
+
+Ensure(ByteStuffer, receives_single_byte_valid_frame) {
+    uint8_t expected[] = {0x37};
+    expect(recv_frame,
+        when(size, is_equal_to(1)),
+        when(data, is_equal_to_contents_of(expected, 1))
+        );
+    recv_byte(&state, 2);
+    recv_byte(&state, 0x37);
+    recv_byte(&state, 0);
+}
+
+Ensure(ByteStuffer, receives_three_bytes_valid_frame) {
+    uint8_t expected[] = {0x37, 0x99, 0xFF};
+    expect(recv_frame,
+        when(size, is_equal_to(3)),
+        when(data, is_equal_to_contents_of(expected, 3))
+        );
+    recv_byte(&state, 5);
+    recv_byte(&state, 0x37);
+    recv_byte(&state, 0x99);
+    recv_byte(&state, 0xFF);
+    recv_byte(&state, 0);
+}
+
+Ensure(ByteStuffer, receives_single_zero_valid_frame) {
+    uint8_t expected[] = {0};
+    expect(recv_frame,
+        when(size, is_equal_to(1)),
+        when(data, is_equal_to_contents_of(expected, 1))
+        );
+    recv_byte(&state, 1);
+    recv_byte(&state, 1);
+    recv_byte(&state, 0);
+}
+
+Ensure(ByteStuffer, receives_valid_frame_with_zeroes) {
+    uint8_t expected[] = {5, 0, 3, 0};
+    expect(recv_frame,
+        when(size, is_equal_to(4)),
+        when(data, is_equal_to_contents_of(expected, 4))
+        );
+    recv_byte(&state, 2);
+    recv_byte(&state, 5);
+    recv_byte(&state, 2);
+    recv_byte(&state, 3);
+    recv_byte(&state, 1);
+    recv_byte(&state, 0);
 }