BOOST_FIXTURE_TEST_CASE( a_new_pdu_will_be_transmitted_if_the_last_was_acknowladged, running_mode ) { transmit_pdu( { 1 } ); transmit_pdu( { 2 } ); transmit_pdu( { 3 } ); transmit_pdu( { 4 } ); BOOST_CHECK_EQUAL( next_transmit().buffer[ 2 ], 1u ); BOOST_CHECK_EQUAL( next_transmit().buffer[ 2 ], 1u ); // incomming PDU acknowledges auto incomming = allocate_receive_buffer(); incomming.buffer[ 0 ] = 1 | 4; incomming.buffer[ 1 ] = 0; received( incomming ); // now the next pdu to be transmitted BOOST_CHECK_EQUAL( next_transmit().buffer[ 2 ], 2u ); // next incomming PDU acknowledges, this time with NESN = 0 incomming = allocate_receive_buffer(); incomming.buffer[ 0 ] = 1; incomming.buffer[ 1 ] = 25; received( incomming ); // now the next pdu to be transmitted BOOST_CHECK_EQUAL( next_transmit().buffer[ 2 ], 3u ); }
BOOST_FIXTURE_TEST_CASE( with_every_new_received_pdu_a_new_sequence_is_expected, running_mode ) { BOOST_CHECK_EQUAL( next_transmit().buffer[ 0 ] & 0x4, 0 ); receive_pdu( { 1 }, false, false ); BOOST_CHECK_EQUAL( next_transmit().buffer[ 0 ] & 0x4, 0x4 ); receive_pdu( { 2 }, true, false ); BOOST_CHECK_EQUAL( next_transmit().buffer[ 0 ] & 0x4, 0 ); }
BOOST_FIXTURE_TEST_CASE( more_data_flag_is_added_if_pdu_is_added, running_mode ) { // empty PDU without MD flag auto first = next_transmit(); BOOST_CHECK_EQUAL( first.buffer[ 0 ] & 0x10, 0 ); transmit_pdu( { 0x01, 0x02, 0x03, 0x04 } ); auto next = next_transmit(); // must be the same PDU, as it was not acknowladged BOOST_CHECK_EQUAL_COLLECTIONS( &first.buffer[ 2 ], &first.buffer[ first.size ], &next.buffer[ 2 ], &next.buffer[ next.size ] ); // sequence numbers and LLID must be equal BOOST_CHECK_EQUAL( first.buffer[ 0 ] & 0xf, first.buffer[ 0 ] & 0xf ); }
BOOST_FIXTURE_TEST_CASE( sequence_number_and_next_sequence_number_must_be_0_for_the_first_pdu, one_element_in_transmit_buffer ) { auto write = next_transmit(); BOOST_CHECK_EQUAL( write.buffer[ 0 ] & 0x4, 0 ); BOOST_CHECK_EQUAL( write.buffer[ 0 ] & 0x8, 0 ); }
BOOST_FIXTURE_TEST_CASE( more_data_flag_is_set_if_there_is_more_than_one_element_in_the_transmit_buffer, one_element_in_transmit_buffer ) { transmit_pdu( { 0x01 } ); auto transmit = next_transmit(); BOOST_CHECK_EQUAL( transmit.buffer[ 0 ] & 0x10, 0x10 ); }
write_buffer ll_data_pdu_buffer< TransmitSize, ReceiveSize, Radio >::received( read_buffer pdu ) { assert( pdu.buffer ); assert( pdu.buffer >= receive_buffer() ); assert( pdu.size >= pdu.buffer[ 1 ] + ll_header_size ); assert( end_receive_buffer() - pdu.buffer >= pdu.buffer[ 1 ] + ll_header_size ); assert( check_receive_buffer_consistency( "+received" ) ); // invalid LLID or resent? if ( ( pdu.buffer[ 0 ] & 0x3 ) != 0 ) { acknowledge( pdu.buffer[ 0 ] & nesn_flag ); // resent PDU? if ( static_cast< bool >( pdu.buffer[ 0 ] & sn_flag ) == next_expected_sequence_number_ ) { next_expected_sequence_number_ = !next_expected_sequence_number_; if ( pdu.buffer[ 1 ] != 0 ) { received_end_ = pdu.buffer + pdu.buffer[ 1 ] + ll_header_size; // we received data, so we can not end up with the receive buffer beeing empty assert( received_end_ != received_ ); } } } assert( check_receive_buffer_consistency( "-received" ) ); return next_transmit(); }
BOOST_FIXTURE_TEST_CASE( the_transmitbuffer_will_yield_an_empty_pdu_if_the_buffer_is_empty, running_mode ) { auto write = next_transmit(); BOOST_CHECK_EQUAL( write.size, 2u ); BOOST_CHECK_EQUAL( write.buffer[ 0 ] & 0x03, 1 ); BOOST_CHECK_EQUAL( write.buffer[ 1 ], 0u ); }
BOOST_FIXTURE_TEST_CASE( getting_an_empty_pdu_must_not_result_in_changing_allocated_transmit_buffer, running_mode ) { auto trans = allocate_transmit_buffer(); std::fill( trans.buffer, trans.buffer + trans.size, 0x22 ); // this call should not change the allocated buffer next_transmit(); BOOST_CHECK( std::find_if( trans.buffer, trans.buffer + trans.size, []( std::uint8_t b ) { return b != 0x22; } ) == trans.buffer + trans.size ); }
BOOST_FIXTURE_TEST_CASE( as_long_as_an_pdu_is_not_acknowlaged_it_will_be_retransmited, one_element_in_transmit_buffer ) { for ( int i = 0; i != 3; ++i ) { auto trans = next_transmit(); BOOST_REQUIRE_EQUAL( trans.size, 3u ); BOOST_CHECK_EQUAL( trans.buffer[ 1 ], 1u ); BOOST_CHECK_EQUAL( trans.buffer[ 2 ], 0x34u ); } }
BOOST_FIXTURE_TEST_CASE( more_data_flag_is_not_set_if_only_one_element_is_in_the_transmit_buffer, one_element_in_transmit_buffer ) { auto write = next_transmit(); BOOST_CHECK_EQUAL( write.buffer[ 0 ] & 0x10, 0 ); }
BOOST_FIXTURE_TEST_CASE( if_transmit_buffer_is_empty_mode_data_flag_is_not_set, running_mode ) { auto write = next_transmit(); BOOST_CHECK_EQUAL( write.buffer[ 0 ] & 0x10, 0 ); }