@@ -1919,189 +1919,6 @@ static void test_all_7_kinds(void)
19191919 }
19201920}
19211921
1922- // =====================================================================================================================
1923- // Group 10: Regression
1924-
1925- /// Regression: v0 CRC is a uint16_t, not a bool. Ensure CRC comparison works for values > 1.
1926- /// This test verifies that the v0 CRC reference is correctly read as a 16-bit LE value from the stored payload,
1927- /// not truncated to a boolean or single byte.
1928- static void test_regression_v0_crc_not_bool (void )
1929- {
1930- const uint64_t dts = 0x1122334455667788ULL ;
1931- const uint16_t crc_seed = canard_0v1_crc_seed_from_data_type_signature (dts );
1932- session_fixture_t fx ;
1933- fixture_init (& fx , canard_kind_0v1_message , 500 , 64 , 2 * MEGA , crc_seed );
1934-
1935- // Create a payload that produces a CRC with both bytes nonzero.
1936- const byte_t user_data [8 ] = { 0x99 , 0x88 , 0x77 , 0x66 , 0x55 , 0x44 , 0x33 , 0x22 };
1937- const uint16_t crc = crc_add (crc_seed , 8 , user_data );
1938- // Ensure both bytes of CRC are nonzero and > 1 to catch bool truncation.
1939- // The CRC value depends on the seed and data; we just verify the transfer succeeds.
1940- const byte_t crc_lo = (byte_t )(crc & 0xFF ); // NOLINT(hicpp-signed-bitwise)
1941- const byte_t crc_hi = (byte_t )(crc >> 8 ); // NOLINT(hicpp-signed-bitwise)
1942-
1943- byte_t f0 [7 ];
1944- f0 [0 ] = crc_lo ;
1945- f0 [1 ] = crc_hi ;
1946- f0 [2 ] = 0x99 ;
1947- f0 [3 ] = 0x88 ;
1948- f0 [4 ] = 0x77 ;
1949- f0 [5 ] = 0x66 ;
1950- f0 [6 ] = 0x55 ;
1951- const byte_t f1 [3 ] = { 0x44 , 0x33 , 0x22 };
1952-
1953- frame_t fr0 = make_start_frame (
1954- canard_prio_nominal , canard_kind_0v1_message , 500 , CANARD_NODE_ID_ANONYMOUS , 10 , 0 , f0 , sizeof (f0 ));
1955- TEST_ASSERT_TRUE (feed (& fx , 1 * MEGA , & fr0 , 0 ));
1956-
1957- frame_t fr1 = make_cont_frame (
1958- canard_prio_nominal , canard_kind_0v1_message , 500 , CANARD_NODE_ID_ANONYMOUS , 10 , 0 , true, true, f1 , sizeof (f1 ));
1959- TEST_ASSERT_TRUE (feed (& fx , 1 * MEGA , & fr1 , 0 ));
1960-
1961- TEST_ASSERT_EQUAL_size_t (1 , fx .capture .call_count );
1962- TEST_ASSERT_EQUAL_size_t (8 , fx .capture .payload .view .size );
1963- TEST_ASSERT_EQUAL_INT (0 , memcmp (fx .capture .payload .view .data , user_data , 8 ));
1964-
1965- // Verify the CRC had both bytes nonzero (regression check: not accidentally compared as bool).
1966- TEST_ASSERT_TRUE (crc > 0xFF ); // At least the high byte is nonzero.
1967-
1968- fixture_destroy_all_sessions (& fx );
1969- fixture_check_alloc_balance (& fx );
1970- }
1971-
1972- /// Regression: v1 toggle assertion. The start frame toggle MUST be 1 for v1, 0 for v0.
1973- /// Ensure that the code correctly checks the toggle and does not confuse them.
1974- static void test_regression_v1_toggle_assertion (void )
1975- {
1976- // Test v1 single-frame: toggle must be 1.
1977- {
1978- session_fixture_t fx ;
1979- fixture_init_v1 (& fx , canard_kind_1v1_message , 100 , 64 );
1980-
1981- const byte_t payload [] = { 0x42 };
1982- frame_t fr = make_single_frame (
1983- canard_prio_nominal , canard_kind_1v1_message , 100 , CANARD_NODE_ID_ANONYMOUS , 42 , 0 , payload , sizeof (payload ));
1984- // Verify toggle is 1 as set by make_single_frame for v1.
1985- TEST_ASSERT_TRUE (fr .toggle );
1986- TEST_ASSERT_TRUE (feed (& fx , 1 * MEGA , & fr , 0 ));
1987- TEST_ASSERT_EQUAL_size_t (1 , fx .capture .call_count );
1988-
1989- fixture_destroy_all_sessions (& fx );
1990- fixture_check_alloc_balance (& fx );
1991- }
1992-
1993- // Test v0 single-frame: toggle must be 0.
1994- {
1995- session_fixture_t fx ;
1996- fixture_init (& fx , canard_kind_0v1_message , 100 , 64 , 2 * MEGA , 0 );
1997-
1998- const byte_t payload [] = { 0x42 };
1999- frame_t fr = make_single_frame (
2000- canard_prio_nominal , canard_kind_0v1_message , 100 , CANARD_NODE_ID_ANONYMOUS , 42 , 0 , payload , sizeof (payload ));
2001- // Verify toggle is 0 as set by make_single_frame for v0.
2002- TEST_ASSERT_FALSE (fr .toggle );
2003- TEST_ASSERT_TRUE (feed (& fx , 1 * MEGA , & fr , 0 ));
2004- TEST_ASSERT_EQUAL_size_t (1 , fx .capture .call_count );
2005-
2006- fixture_destroy_all_sessions (& fx );
2007- fixture_check_alloc_balance (& fx );
2008- }
2009-
2010- // Test v1 multi-frame start: toggle=1, continuation toggles 0,1,0,...
2011- {
2012- session_fixture_t fx ;
2013- fixture_init_v1 (& fx , canard_kind_1v0_message , 2222 , 64 );
2014-
2015- const byte_t data [] = { 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 };
2016- frame_t fr = make_start_frame (
2017- canard_prio_nominal , canard_kind_1v0_message , 2222 , CANARD_NODE_ID_ANONYMOUS , 42 , 0 , data , sizeof (data ));
2018- TEST_ASSERT_TRUE (fr .toggle ); // v1 start toggle = 1.
2019- TEST_ASSERT_TRUE (feed (& fx , 1 * MEGA , & fr , 0 ));
2020-
2021- // Continuation: expected toggle = 0 (flipped from 1).
2022- const uint16_t crc = crc_add (CRC_INITIAL , 7 , data );
2023- byte_t f_end [2 ];
2024- f_end [0 ] = (byte_t )(crc >> 8U );
2025- f_end [1 ] = (byte_t )(crc & 0xFF ); // NOLINT(hicpp-signed-bitwise)
2026- frame_t fr_end = make_cont_frame (canard_prio_nominal ,
2027- canard_kind_1v0_message ,
2028- 2222 ,
2029- CANARD_NODE_ID_ANONYMOUS ,
2030- 42 ,
2031- 0 ,
2032- true,
2033- false,
2034- f_end ,
2035- sizeof (f_end ));
2036- TEST_ASSERT_TRUE (feed (& fx , 1 * MEGA , & fr_end , 0 ));
2037- TEST_ASSERT_EQUAL_size_t (1 , fx .capture .call_count );
2038- TEST_ASSERT_EQUAL_size_t (7 , fx .capture .payload .view .size );
2039-
2040- fixture_destroy_all_sessions (& fx );
2041- fixture_check_alloc_balance (& fx );
2042- }
2043-
2044- // Test v0 multi-frame start: toggle=0, continuation toggle=1,0,1,...
2045- {
2046- session_fixture_t fx ;
2047- const uint16_t crc_seed = canard_0v1_crc_seed_from_data_type_signature (0xABCDEF0123456789ULL );
2048- fixture_init (& fx , canard_kind_0v1_message , 999 , 64 , 2 * MEGA , crc_seed );
2049-
2050- const byte_t user_data [5 ] = { 0x11 , 0x22 , 0x33 , 0x44 , 0x55 };
2051- const uint16_t crc = crc_add (crc_seed , 5 , user_data );
2052- const byte_t crc_lo = (byte_t )(crc & 0xFF ); // NOLINT(hicpp-signed-bitwise)
2053- const byte_t crc_hi = (byte_t )(crc >> 8 ); // NOLINT(hicpp-signed-bitwise)
2054-
2055- byte_t f0 [7 ];
2056- f0 [0 ] = crc_lo ;
2057- f0 [1 ] = crc_hi ;
2058- f0 [2 ] = 0x11 ;
2059- f0 [3 ] = 0x22 ;
2060- f0 [4 ] = 0x33 ;
2061- f0 [5 ] = 0x44 ;
2062- f0 [6 ] = 0x55 ;
2063-
2064- frame_t fr = make_start_frame (
2065- canard_prio_nominal , canard_kind_0v1_message , 999 , CANARD_NODE_ID_ANONYMOUS , 10 , 0 , f0 , sizeof (f0 ));
2066- TEST_ASSERT_FALSE (fr .toggle ); // v0 start toggle = 0.
2067- TEST_ASSERT_TRUE (feed (& fx , 1 * MEGA , & fr , 0 ));
2068-
2069- // Single-frame-like end (but actually it's a 2-frame transfer). No, this is a start+cont.
2070- // We need a second frame with the end bit. But we already have all the data in frame 0.
2071- // Actually CRC+payload = 2+5=7 bytes, exactly one Classic CAN frame.
2072- // But make_start_frame has end=false, so we need a second frame.
2073- // The second frame should just be the end frame with no additional data... but
2074- // the assertion requires non-end frames to have payload.size >= 7.
2075- // Actually the end frame CAN have < 7 bytes. Let's just send an empty end frame with CRC residue check.
2076- // Wait - the total CRC was computed over 5 bytes of user_data (the CRC bytes in v0 are excluded from CRC input
2077- // on the start frame). Let me reconsider.
2078- //
2079- // For v0 multi-frame, the first frame has CRC-LE in the first 2 bytes. The CRC input for the start frame
2080- // is payload[2:] (skip the CRC bytes). So the slot's CRC state after frame 0 = crc_add(crc_seed, 5, user_data).
2081- // The end frame would have no additional user data, so no CRC update except for the empty payload.
2082- // The final CRC check: slot->crc == CRC_ref where CRC_ref = slot->payload[0] | (slot->payload[1]<<8).
2083- // slot->payload[0..1] = {crc_lo, crc_hi} = crc in LE.
2084- // slot->crc after all frames = crc_add(crc_seed, 5, user_data) = crc.
2085- // So CRC_ref = crc, and slot->crc = crc → match!
2086- // But we need an end frame. The end frame payload must exist (can be empty for single-frame, but this
2087- // is a multi-frame so the assertion says !start && end is ok with any payload size).
2088- // Actually: the assertion is `frame->end || (frame->payload.size >= 7)`.
2089- // So end frames can have any size. But we need at least some data pointer.
2090- const byte_t empty = 0 ;
2091- frame_t fr_end = make_cont_frame (
2092- canard_prio_nominal , canard_kind_0v1_message , 999 , CANARD_NODE_ID_ANONYMOUS , 10 , 0 , true, true, & empty , 0 );
2093- // Wait, payload.data must not be NULL per the assertion in rx_session_update.
2094- // Let's use size=0 but point to a valid address.
2095- TEST_ASSERT_TRUE (feed (& fx , 1 * MEGA , & fr_end , 0 ));
2096- TEST_ASSERT_EQUAL_size_t (1 , fx .capture .call_count );
2097- TEST_ASSERT_EQUAL_size_t (5 , fx .capture .payload .view .size );
2098- TEST_ASSERT_EQUAL_INT (0 , memcmp (fx .capture .payload .view .data , user_data , 5 ));
2099-
2100- fixture_destroy_all_sessions (& fx );
2101- fixture_check_alloc_balance (& fx );
2102- }
2103- }
2104-
21051922// =====================================================================================================================
21061923
21071924int main (void )
@@ -2174,9 +1991,5 @@ int main(void)
21741991 RUN_TEST (test_session_animation_ordering );
21751992 RUN_TEST (test_all_7_kinds );
21761993
2177- // Group 10: Regression
2178- RUN_TEST (test_regression_v0_crc_not_bool );
2179- RUN_TEST (test_regression_v1_toggle_assertion );
2180-
21811994 return UNITY_END ();
21821995}
0 commit comments