#include "unity.h" #include "celrs/crsf.h" #include void setUp(void) {} void tearDown(void) {} /* CRC tests — CRC8/DVB-S2 (poly 0xD5) */ 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) { /* Verify CRC is deterministic */ uint8_t data[6] = {0x10, 0x80, 0x03, 0x02, 0x80, 0x01}; uint8_t crc = cel_crsf_crc(data, 6); TEST_ASSERT_TRUE(crc != 0); uint8_t crc2 = cel_crsf_crc(data, 6); TEST_ASSERT_EQUAL_UINT8(crc, crc2); } /* TODO: rewrite parse/build tests for new ELRS frame format. * New format: [addr][length][type][payload...][crc] * Old tests below use legacy functions for backward compat. */ /* Frame parse tests (legacy format) */ void test_parse_legacy_invalid_header(void) { cel_crsf_frame_legacy frame; uint8_t buf[8] = {0x00, 0x10, 0x80, 0x03, 0x02, 0x80, 0x01, 0x00}; TEST_ASSERT_EQUAL_INT(-1, cel_crsf_frame_parse_legacy(&frame, buf, 8)); } void test_parse_legacy_too_short(void) { cel_crsf_frame_legacy frame; uint8_t buf[2] = {0xC8, 0x10}; TEST_ASSERT_EQUAL_INT(-1, cel_crsf_frame_parse_legacy(&frame, buf, 2)); } void test_parse_legacy_null_frame(void) { uint8_t buf[8] = {0xC8, 0x10, 0x80, 0x03, 0x02, 0x80, 0x01, 0x00}; TEST_ASSERT_EQUAL_INT(-1, cel_crsf_frame_parse_legacy(NULL, buf, 8)); } void test_parse_legacy_null_buf(void) { cel_crsf_frame_legacy frame; TEST_ASSERT_EQUAL_INT(-1, cel_crsf_frame_parse_legacy(&frame, NULL, 8)); } /* Frame build tests (legacy format) */ void test_build_legacy_heartbeat(void) { uint8_t dst[256]; uint8_t payload[2] = {0x80, 0x01}; size_t len = cel_crsf_frame_build_legacy(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_legacy_roundtrip(void) { uint8_t dst[256]; uint8_t payload[4] = {0xAA, 0xBB, 0xCC, 0xDD}; size_t len = cel_crsf_frame_build_legacy(dst, 0x10, 0x80, 0x01, payload, 4); /* Parse the built frame back */ cel_crsf_frame_legacy frame; TEST_ASSERT_EQUAL_INT(0, cel_crsf_frame_parse_legacy(&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_legacy_null_dst(void) { uint8_t payload[2] = {0x01, 0x02}; TEST_ASSERT_EQUAL_UINT(0, cel_crsf_frame_build_legacy(NULL, 0x00, 0x80, 0x03, payload, 2)); } void test_build_legacy_null_payload(void) { uint8_t dst[256]; size_t len = cel_crsf_frame_build_legacy(dst, 0x10, 0x80, 0x03, NULL, 0); TEST_ASSERT_GREATER_THAN(0, len); /* Should still have valid CRC for empty payload */ cel_crsf_frame_legacy frame; TEST_ASSERT_EQUAL_INT(0, cel_crsf_frame_parse_legacy(&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_legacy_invalid_header); RUN_TEST(test_parse_legacy_too_short); RUN_TEST(test_parse_legacy_null_frame); RUN_TEST(test_parse_legacy_null_buf); RUN_TEST(test_build_legacy_heartbeat); RUN_TEST(test_build_legacy_roundtrip); RUN_TEST(test_build_legacy_null_dst); RUN_TEST(test_build_legacy_null_payload); return UNITY_END(); }