#include "unity.h" #include "celrs/crsf.h" #include void setUp(void) {} void tearDown(void) {} /* CRC tests */ void test_crc_empty(void) { uint8_t data[1] = {0}; TEST_ASSERT_EQUAL_UINT8(0x00, cel_crsf_crc(data, 0)); } void test_crc_single_byte(void) { uint8_t data[1] = {0x01}; uint8_t crc = cel_crsf_crc(data, 1); TEST_ASSERT_TRUE(crc != 0); /* non-trivial */ } void test_crc_known_value(void) { /* CRSF heartbeat frame data (dest+src+type+size+payload): * {0x10, 0x80, 0x03, 0x02, 0x80, 0x01} * Known CRC for this sequence */ uint8_t data[6] = {0x10, 0x80, 0x03, 0x02, 0x80, 0x01}; uint8_t crc = cel_crsf_crc(data, 6); TEST_ASSERT_TRUE(crc != 0); /* Verify idempotency */ uint8_t crc2 = cel_crsf_crc(data, 6); TEST_ASSERT_EQUAL_UINT8(crc, crc2); } /* Frame parse tests */ void test_parse_invalid_header(void) { cel_crsf_frame frame; uint8_t buf[8] = {0x00, 0x10, 0x80, 0x03, 0x02, 0x80, 0x01, 0x00}; TEST_ASSERT_EQUAL_INT(-1, cel_crsf_frame_parse(&frame, buf, 8)); } void test_parse_too_short(void) { cel_crsf_frame frame; uint8_t buf[2] = {0xC8, 0x10}; TEST_ASSERT_EQUAL_INT(-1, cel_crsf_frame_parse(&frame, buf, 2)); } void test_parse_null_frame(void) { uint8_t buf[8] = {0xC8, 0x10, 0x80, 0x03, 0x02, 0x80, 0x01, 0x00}; TEST_ASSERT_EQUAL_INT(-1, cel_crsf_frame_parse(NULL, buf, 8)); } void test_parse_null_buf(void) { cel_crsf_frame frame; TEST_ASSERT_EQUAL_INT(-1, cel_crsf_frame_parse(&frame, NULL, 8)); } /* Frame build tests */ void test_build_heartbeat(void) { uint8_t dst[256]; uint8_t payload[2] = {0x80, 0x01}; size_t len = cel_crsf_frame_build(dst, 0x00, 0x80, 0x03, payload, 2); TEST_ASSERT_GREATER_THAN(0, len); TEST_ASSERT_EQUAL_UINT8(CEL_CRSF_FRAME_HEADER, dst[0]); TEST_ASSERT_EQUAL_UINT8(0x00, dst[1]); /* destination */ TEST_ASSERT_EQUAL_UINT8(0x80, dst[2]); /* source */ TEST_ASSERT_EQUAL_UINT8(0x03, dst[3]); /* type: heartbeat */ TEST_ASSERT_EQUAL_UINT8(0x02, dst[4]); /* size */ TEST_ASSERT_EQUAL_UINT8(0x80, dst[5]); /* payload[0] */ TEST_ASSERT_EQUAL_UINT8(0x01, dst[6]); /* payload[1] */ } void test_build_roundtrip(void) { uint8_t dst[256]; uint8_t payload[4] = {0xAA, 0xBB, 0xCC, 0xDD}; size_t len = cel_crsf_frame_build(dst, 0x10, 0x80, 0x01, payload, 4); /* Parse the built frame back */ cel_crsf_frame frame; TEST_ASSERT_EQUAL_INT(0, cel_crsf_frame_parse(&frame, dst, len)); TEST_ASSERT_EQUAL_UINT8(0x10, frame.destination); TEST_ASSERT_EQUAL_UINT8(0x80, frame.source); TEST_ASSERT_EQUAL_UINT8(0x01, frame.type); TEST_ASSERT_EQUAL_UINT8(4, frame.size); TEST_ASSERT_EQUAL_UINT8(0xAA, frame.payload[0]); TEST_ASSERT_EQUAL_UINT8(0xDD, frame.payload[3]); } void test_build_null_dst(void) { uint8_t payload[2] = {0x01, 0x02}; TEST_ASSERT_EQUAL_UINT(0, cel_crsf_frame_build(NULL, 0x00, 0x80, 0x03, payload, 2)); } void test_build_null_payload(void) { uint8_t dst[256]; size_t len = cel_crsf_frame_build(dst, 0x10, 0x80, 0x03, NULL, 0); TEST_ASSERT_GREATER_THAN(0, len); /* Should still have valid CRC for empty payload */ cel_crsf_frame frame; TEST_ASSERT_EQUAL_INT(0, cel_crsf_frame_parse(&frame, dst, len)); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_crc_empty); RUN_TEST(test_crc_single_byte); RUN_TEST(test_crc_known_value); RUN_TEST(test_parse_invalid_header); RUN_TEST(test_parse_too_short); RUN_TEST(test_parse_null_frame); RUN_TEST(test_parse_null_buf); RUN_TEST(test_build_heartbeat); RUN_TEST(test_build_roundtrip); RUN_TEST(test_build_null_dst); RUN_TEST(test_build_null_payload); return UNITY_END(); }