/* Frame parser tests against the recovered 0x1bb1b11b framing. */ #include "mag160c/mag160c.h" #include #include #include static void put32(uint8_t *p, uint32_t v) { p[0] = (uint8_t)v; p[1] = (uint8_t)(v >> 8); p[2] = (uint8_t)(v >> 16); p[3] = (uint8_t)(v >> 24); } static void test_parse_valid(void) { uint8_t frame[0x40]; memset(frame, 0xaa, sizeof(frame)); put32(frame + 0x00, 0x1bb1b11b); put32(frame + 0x04, 42); put32(frame + 0x08, 4); put32(frame + 0x0c, 1); put32(frame + 0x10, 1000); frame[0x1c] = 0x34; frame[0x1d] = 0x12; put32(frame + 0x1c + 4, 0x1bb1b11c); mag160c_frame_header_t h; const uint16_t *pixels = NULL; assert(mag160c_frame_parse(frame, sizeof(frame), &h, &pixels) == MAG160C_OK); assert(h.marker == 0x1bb1b11b); assert(h.frame_counter == 42); assert(h.data_length == 4); assert(h.frame_type == 1); assert(h.period_shutter == 1000); assert(h.trailing_marker == 0x1bb1b11c); assert(pixels[0] == 0x1234); } static void test_parse_rejects(void) { uint8_t frame[0x40]; memset(frame, 0, sizeof(frame)); mag160c_frame_header_t h; const uint16_t *pixels = NULL; memset(frame, 0, sizeof(frame)); assert(mag160c_frame_parse(frame, sizeof(frame), &h, &pixels) == MAG160C_ERR_BAD_FRAME); put32(frame + 0x00, 0x1bb1b11b); put32(frame + 0x08, 4); put32(frame + 0x0c, 2); /* bad type */ assert(mag160c_frame_parse(frame, sizeof(frame), &h, &pixels) == MAG160C_ERR_BAD_FRAME); put32(frame + 0x0c, 0); put32(frame + 0x1c + 4, 0xdeadbeef); /* bad trailer */ assert(mag160c_frame_parse(frame, sizeof(frame), &h, &pixels) == MAG160C_ERR_BAD_FRAME); } static void test_stream_split(void) { uint8_t frame[0x40]; memset(frame, 0xaa, sizeof(frame)); put32(frame + 0x00, 0x1bb1b11b); put32(frame + 0x04, 7); put32(frame + 0x08, 4); put32(frame + 0x0c, 1); frame[0x1c] = 0x78; frame[0x1d] = 0x56; put32(frame + 0x1c + 4, 0x1bb1b11c); mag160c_frame_stream_t s; mag160c_frame_stream_init(&s, 0x40); assert(s.buf != NULL); uint8_t out[0x100]; size_t len = 99; const size_t total = 0x38 + 4; /* 0x3c */ /* feed one byte at a time; the frame completes exactly at total bytes */ for (size_t i = 0; i + 1 < total; ++i) { len = 99; assert(mag160c_frame_stream_push(&s, frame + i, 1, out, sizeof(out), &len) == MAG160C_OK); assert(len == 0); } len = 99; assert(mag160c_frame_stream_push(&s, frame + total - 1, 1, out, sizeof(out), &len) == MAG160C_OK); assert(len == total); mag160c_frame_header_t h; const uint16_t *pixels = NULL; assert(mag160c_frame_parse(out, len, &h, &pixels) == MAG160C_OK); assert(h.frame_counter == 7); assert(pixels[0] == 0x5678); /* trailing 4 bytes of the 0x40-byte test frame must not form a frame */ len = 99; assert(mag160c_frame_stream_push(&s, frame + total, 4, out, sizeof(out), &len) == MAG160C_OK); assert(len == 0); mag160c_frame_stream_destroy(&s); } static void test_stream_resync(void) { uint8_t frame[0x40]; memset(frame, 0xaa, sizeof(frame)); put32(frame + 0x00, 0x1bb1b11b); put32(frame + 0x08, 4); put32(frame + 0x0c, 0); frame[0x1c] = 0x11; frame[0x1d] = 0x22; put32(frame + 0x1c + 4, 0x1bb1b11c); mag160c_frame_stream_t s; mag160c_frame_stream_init(&s, 0x40); /* garbage prefix (4-byte aligned) then the frame */ const uint8_t garbage[] = {0x00, 0xff, 0x12, 0x34}; uint8_t out[0x100]; size_t len = 0; assert(mag160c_frame_stream_push(&s, garbage, sizeof(garbage), out, sizeof(out), &len) == MAG160C_OK); assert(len == 0); assert(mag160c_frame_stream_push(&s, frame, sizeof(frame), out, sizeof(out), &len) == MAG160C_OK); assert(len == 0x38 + 4); mag160c_frame_stream_destroy(&s); } int main(void) { test_parse_valid(); test_parse_rejects(); test_stream_split(); test_stream_resync(); printf("test_frame: all passed\n"); return 0; }