// hal_cpu #include "hal_cpu.h" void hal_cpu_disable_irqs(void){} void hal_cpu_enable_irqs(void){} void hal_cpu_enable_irqs_and_sleep(void){} // mock_sm.c #include "ble/sm.h" void sm_add_event_handler(btstack_packet_callback_registration_t * callback_handler){} void sm_request_pairing(hci_con_handle_t con_handle){} // mock_hci_transport.h #include "hci_transport.h" void mock_hci_transport_receive_packet(uint8_t packet_type, uint8_t * packet, uint16_t size); const hci_transport_t * mock_hci_transport_mock_get_instance(void); // mock_hci_transport.c #include static uint8_t mock_hci_transport_outgoing_packet_buffer[HCI_ACL_PAYLOAD_SIZE]; static uint16_t mock_hci_transport_outgoing_packet_size; static uint8_t mock_hci_transport_outgoing_packet_type; static void (*mock_hci_transport_packet_handler)(uint8_t packet_type, uint8_t * packet, uint16_t size); static void mock_hci_transport_register_packet_handler(void (*packet_handler)(uint8_t packet_type, uint8_t * packet, uint16_t size)){ mock_hci_transport_packet_handler = packet_handler; } static int mock_hci_transport_send_packet(uint8_t packet_type, uint8_t *packet, int size){ mock_hci_transport_outgoing_packet_type = packet_type; mock_hci_transport_outgoing_packet_size = size; memcpy(mock_hci_transport_outgoing_packet_buffer, packet, size); return 0; } const hci_transport_t * mock_hci_transport_mock_get_instance(void){ static hci_transport_t mock_hci_transport = { /* .transport.name = */ "mock", /* .transport.init = */ NULL, /* .transport.open = */ NULL, /* .transport.close = */ NULL, /* .transport.register_packet_handler = */ &mock_hci_transport_register_packet_handler, /* .transport.can_send_packet_now = */ NULL, /* .transport.send_packet = */ &mock_hci_transport_send_packet, /* .transport.set_baudrate = */ NULL, }; return &mock_hci_transport; } void mock_hci_transport_receive_packet(uint8_t packet_type, const uint8_t * packet, uint16_t size){ (*mock_hci_transport_packet_handler)(packet_type, (uint8_t *) packet, size); } // copy from hci.c static void mock_hci_emit_disconnection_complete(hci_con_handle_t con_handle, uint8_t reason){ uint8_t event[6]; event[0] = HCI_EVENT_DISCONNECTION_COMPLETE; event[1] = sizeof(event) - 2u; event[2] = 0; // status = OK little_endian_store_16(event, 3, con_handle); event[5] = reason; (*mock_hci_transport_packet_handler)(HCI_EVENT_PACKET, event, sizeof(event)); } // #include #include #include #include #include "CppUTest/TestHarness.h" #include "CppUTest/CommandLineTestRunner.h" #include "CppUTestExt/MockSupport.h" #include "hci_dump.h" #include "btstack_debug.h" #include "l2cap.h" #include "btstack_memory.h" #include "btstack_run_loop_embedded.h" #include "hci_dump_posix_stdout.h" #include "btstack_event.h" #define TEST_PACKET_SIZE 100 #define HCI_CON_HANDLE_TEST_LE 0x0005 #define HCI_CON_HANDLE_TEST_CLASSIC 0x0003 #define TEST_PSM 0x1001 static bool l2cap_channel_accept_incoming; static uint16_t initial_credits = L2CAP_LE_AUTOMATIC_CREDITS; static uint8_t data_channel_buffer_1[TEST_PACKET_SIZE]; static uint8_t data_channel_buffer_2[TEST_PACKET_SIZE]; static uint16_t l2cap_cids[10]; static uint16_t num_l2cap_channel_opened; static uint16_t num_l2cap_channel_closed; static uint8_t * receive_buffers_2[] = { data_channel_buffer_1, data_channel_buffer_2 }; static uint8_t * reconfigure_buffers_2[] = {data_channel_buffer_1, data_channel_buffer_2 }; static uint8_t received_packet[TEST_PACKET_SIZE]; static uint16_t reconfigure_result; static btstack_packet_callback_registration_t l2cap_event_callback_registration; // two channels with cids 0x041 and 0x042 const uint8_t l2cap_enhanced_data_channel_le_conn_request_1[] = { 0x05, 0x20, 0x14, 0x00, 0x10, 0x00, 0x05, 0x00, 0x17, 0x01, 0x0c, 0x00, 0x01, 0x10, 0x64, 0x00, 0x30, 0x00, 0xff, 0xff, 0x41, 0x00, 0x42, 0x00 }; const uint8_t l2cap_enhanced_data_channel_classic_conn_request_1[] = { 0x03, 0x20, 0x14, 0x00, 0x10, 0x00, 0x01, 0x00, 0x17, 0x01, 0x0c, 0x00, 0x01, 0x10, 0x64, 0x00, 0x30, 0x00, 0xff, 0xff, 0x41, 0x00, 0x42, 0x00 }; const uint8_t l2cap_enhanced_data_channel_le_conn_response_2_failed[] = { 0x05, 0x20, 0x14, 0x00, 0x10, 0x00, 0x05, 0x00, 0x18, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 }; const uint8_t l2cap_enhanced_data_channel_le_conn_response_2_success[] = { 0x05, 0x20, 0x14, 0x00, 0x10, 0x00, 0x05, 0x00, 0x18, 0x01, 0x0c, 0x00, 0x64, 0x00, 0x30, 0x00, 0xff, 0xff, 0x00, 0x00, 0x41, 0x00, 0x42, 0x00 }; const uint8_t l2cap_enhanced_data_channel_classic_conn_response_2_success[] = { 0x03, 0x20, 0x14, 0x00, 0x10, 0x00, 0x01, 0x00, 0x18, 0x01, 0x0c, 0x00, 0x64, 0x00, 0x30, 0x00, 0xff, 0xff, 0x00, 0x00, 0x41, 0x00, 0x42, 0x00 }; const uint8_t l2cap_enhanced_data_channel_le_credits[] = { 0x05, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x05, 0x00, 0x16, 0x02, 0x04, 0x00, 0x41, 0x00, 0x05, 0x00, }; const uint8_t l2cap_enhanced_data_channel_classic_credits[] = { 0x03, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x01, 0x00, 0x16, 0x02, 0x04, 0x00, 0x41, 0x00, 0x05, 0x00, }; const uint8_t l2cap_enhanced_data_channel_le_single_packet[] = { 0x05, 0x20, 0x0b, 0x00, 0x07, 0x00, 0x41, 0x00, 0x05, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f }; const uint8_t l2cap_enhanced_data_channel_classic_single_packet[] = { 0x03, 0x20, 0x0b, 0x00, 0x07, 0x00, 0x41, 0x00, 0x05, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f }; const uint8_t l2cap_enhanced_data_channel_le_disconnect_request_1[] = { 0x05, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x05, 0x00, 0x06, 0x02, 0x04, 0x00, 0x41, 0x00, 0x41, 0x00 }; const uint8_t l2cap_enhanced_data_channel_le_disconnect_response_1[] = { 0x05, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x05, 0x00, 0x07, 0x02, 0x04, 0x00, 0x41, 0x00, 0x41, 0x00 }; const uint8_t l2cap_enhanced_data_channel_le_disconnect_request_2[] = { 0x05, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x05, 0x00, 0x06, 0x03, 0x04, 0x00, 0x42, 0x00, 0x42, 0x00 }; const uint8_t l2cap_enhanced_data_channel_le_disconnect_response_2[] = { 0x05, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x05, 0x00, 0x07, 0x03, 0x04, 0x00, 0x42, 0x00, 0x42, 0x00 }; const uint8_t l2cap_enhanced_data_channel_classic_disconnect_request_1[] = { 0x03, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x01, 0x00, 0x06, 0x02, 0x04, 0x00, 0x41, 0x00, 0x41, 0x00 }; const uint8_t l2cap_enhanced_data_channel_classic_disconnect_response_1[] = { 0x03, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x01, 0x00, 0x07, 0x02, 0x04, 0x00, 0x41, 0x00, 0x41, 0x00 }; const uint8_t l2cap_enhanced_data_channel_classic_disconnect_request_2[] = { 0x03, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x01, 0x00, 0x06, 0x03, 0x04, 0x00, 0x42, 0x00, 0x42, 0x00 }; const uint8_t l2cap_enhanced_data_channel_classic_disconnect_response_2[] = { 0x03, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x01, 0x00, 0x07, 0x03, 0x04, 0x00, 0x42, 0x00, 0x42, 0x00 }; const uint8_t l2cap_enhanced_data_channel_le_renegotiate_request[] = { 0x05, 0x20, 0x10, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x19, 0x02, 0x08, 0x00, 0x64, 0x00, 0x30, 0x00, 0x41, 0x00, 0x42, 0x00 }; const uint8_t l2cap_enhanced_data_channel_classic_renegotiate_request[] = { 0x03, 0x20, 0x10, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x19, 0x02, 0x08, 0x00, 0x64, 0x00, 0x30, 0x00, 0x41, 0x00, 0x42, 0x00 }; const uint8_t l2cap_enhanced_data_channel_le_renegotiate_response[] = { 0x05, 0x20, 0x0a, 0x00, 0x06, 0x00, 0x05, 0x00, 0x1a, 0x02, 0x02, 0x00, 0x00, 0x00 }; const uint8_t l2cap_enhanced_data_channel_classic_renegotiate_response[] = { 0x03, 0x20, 0x0a, 0x00, 0x06, 0x00, 0x01, 0x00, 0x1a, 0x02, 0x02, 0x00, 0x00, 0x00 }; static void fix_boundary_flags(uint8_t * packet, uint16_t size){ uint8_t acl_flags = packet[1] >> 4; if (acl_flags == 0){ acl_flags = 2; // first fragment } packet[1] = (packet[1] & 0x0f) | (acl_flags << 4); } static void print_acl(const char * name, const uint8_t * packet, uint16_t size){ printf("const uint8_t %s[] = {", name); uint16_t i; for (i=0;i