diff --git a/test/gatt_client/Makefile b/test/gatt_client/Makefile index e2e6784f4..069f90783 100644 --- a/test/gatt_client/Makefile +++ b/test/gatt_client/Makefile @@ -21,7 +21,6 @@ COMMON = \ sdp_util.c \ remote_device_db_memory.c \ hci_cmds.c \ - hci.c \ hci_dump.c \ att_dispatch.c \ att.c \ diff --git a/test/gatt_client/le_central.c b/test/gatt_client/le_central.c index 6e2cc5902..51fdf39f1 100644 --- a/test/gatt_client/le_central.c +++ b/test/gatt_client/le_central.c @@ -20,27 +20,16 @@ #include "btstack_memory.h" #include "hci.h" #include "gatt_client.h" - -static bd_addr_t test_device_addr = {0x34, 0xb1, 0xf7, 0xd1, 0x77, 0x9b}; -//static le_central_t test_le_central_context; static uint8_t advertisement_received; static uint8_t connected; +static uint8_t advertisement_packet[150]; void mock_simulate_hci_state_working(); void mock_simulate_command_complete(const hci_cmd_t *cmd); void mock_simulate_scan_response(); void mock_simulate_connected(); -typedef struct ad_event { - uint8_t type; - uint8_t event_type; - uint8_t address_type; - bd_addr_t address; - uint8_t rssi; - uint8_t length; - uint8_t * data; -} ad_event_t; void CHECK_EQUAL_ARRAY(const uint8_t * expected, uint8_t * actual, int size){ for (int i=0; ievent_type); - CHECK_EQUAL(0, e->address_type); - CHECK_EQUAL(188, e->rssi); - CHECK_EQUAL(3, e->length); - CHECK_EQUAL_ARRAY((uint8_t *)test_device_addr, (uint8_t *)e->address, 6); -} - - -static void handle_le_client_event(le_event_t * event){ - switch(event->type){ - case GAP_LE_ADVERTISING_REPORT:{ - advertisement_received = 1; - verify_advertisement((ad_event_t *) event); - break; - // TODO handle hci le connection complete event instead of this - // case GATT_CONNECTION_COMPLETE: { - // connected = 1; - // break; +static void handle_hci_event(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + printf(" handle_hci_event \n"); + if (packet_type != HCI_EVENT_PACKET) return; + + bd_addr_t address; + uint8_t event = packet[0]; + switch (event) { + case BTSTACK_EVENT_STATE: + if (packet[2] != HCI_STATE_WORKING) break; + printf("BTstack activated, set scan params!\n"); + le_central_set_scan_parameters(0,0x0030, 0x0030); + printf("Start scanning\n"); + le_central_start_scan(); + break; + + case GAP_LE_ADVERTISING_REPORT:{ + advertisement_received = 1; + memcpy(advertisement_packet, packet, size); + + bt_flip_addr(address, &packet[4]); + le_central_connect(address, (bd_addr_type_t)packet[3]); + break; } - - default: - printf("le_event_t"); - break; - } + case HCI_EVENT_LE_META: + // wait for connection complete + if (packet[2] != HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break; + printf("connected\n"); + connected = 1; + break; + case HCI_EVENT_DISCONNECTION_COMPLETE: + printf("disconnected\n"); + exit(0); + break; + default: + break; + } } + TEST_GROUP(LECentral){ - void connect(void){ - le_central_connect(test_device_addr, BD_ADDR_TYPE_LE_PUBLIC); - mock_simulate_connected(); - CHECK(connected); - } - void setup(void){ advertisement_received = 0; connected = 0; + l2cap_init(); + l2cap_register_packet_handler(&handle_hci_event); - - // mock().expectOneCall("productionCode").andReturnValue(10); - - // ble_client_init(); - // le_central_register_handler(handle_le_client_event); - // le_central_register_connection_handler(handle_le_client_event); - - // mock().expectOneCall("hci_can_send_packet_now_using_packet_buffer").andReturnValue(1); - // mock_simulate_hci_state_working(); - // connect(); + mock().expectOneCall("hci_can_send_packet_now_using_packet_buffer").andReturnValue(1); + mock_simulate_hci_state_working(); } void teardown(void){ @@ -107,26 +96,26 @@ TEST_GROUP(LECentral){ -// TEST(LECentral, TestScanning){ -// le_central_start_scan(); -// mock_simulate_command_complete(&hci_le_set_scan_enable); -// mock_simulate_scan_response(); -// CHECK(advertisement_received); -// } - -int productionCode(void){ - printf("productionCode 20\n"); - mock().actualCall("productionCode"); - return 20; +TEST(LECentral, TestScanningAndConnect){ + uint8_t expected_bt_addr[] = {0x34, 0xB1, 0xF7, 0xD1, 0x77, 0x9B}; + + mock_simulate_command_complete(&hci_le_set_scan_enable); + mock_simulate_scan_response(); + + CHECK(advertisement_received); + CHECK_EQUAL(0xE2, advertisement_packet[2]); // event type + CHECK_EQUAL(0x01, advertisement_packet[3]); // address type + CHECK_EQUAL_ARRAY(expected_bt_addr, &advertisement_packet[4], 6); + CHECK_EQUAL(0xCC, advertisement_packet[10]); // rssi + CHECK_EQUAL(0x09, advertisement_packet[11]); // data size + + for (int i=0; i<0x09; i++){ // data + CHECK_EQUAL(i, advertisement_packet[12+i]); + } + mock_simulate_connected(); + CHECK(connected); } -TEST(LECentral, SimpleScenario){ - mock().expectOneCall("productionCode").andReturnValue(10); - printf("productionCode %d\n", productionCode()); - mock().checkExpectations(); -} - - int main (int argc, const char * argv[]){ return CommandLineTestRunner::RunAllTests(argc, argv); } diff --git a/test/gatt_client/mock.c b/test/gatt_client/mock.c index 3f3865575..34ebeb4b6 100644 --- a/test/gatt_client/mock.c +++ b/test/gatt_client/mock.c @@ -12,9 +12,9 @@ #include "sm.h" static btstack_packet_handler_t att_packet_handler; -static void (*gatt_central_packet_handler) (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) = NULL; - +static void (*hci_packet_handler) (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) = NULL; +static linked_list_t connections; static const uint16_t max_mtu = 23; static uint8_t l2cap_stack_buffer[max_mtu]; uint16_t gatt_client_handle = 0x40; @@ -25,23 +25,34 @@ uint16_t get_gatt_client_handle(void){ void mock_simulate_command_complete(const hci_cmd_t *cmd){ uint8_t packet[] = {HCI_EVENT_COMMAND_COMPLETE, 4, 1, cmd->opcode & 0xff, cmd->opcode >> 8, 0}; - gatt_central_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet)); + hci_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet)); } void mock_simulate_hci_state_working(void){ uint8_t packet[3] = {BTSTACK_EVENT_STATE, 0, HCI_STATE_WORKING}; - gatt_central_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, 3); + hci_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, 3); } void mock_simulate_connected(void){ uint8_t packet[] = {0x3E, 0x13, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x9B, 0x77, 0xD1, 0xF7, 0xB1, 0x34, 0x50, 0x00, 0x00, 0x00, 0xD0, 0x07, 0x05}; - gatt_central_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet)); + hci_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet)); } - void mock_simulate_scan_response(void){ - uint8_t packet[] = {0x3E, 0x0F, 0x02, 0x01, 0x00, 0x00, 0x9B, 0x77, 0xD1, 0xF7, 0xB1, 0x34, 0x03, 0x02, 0x01, 0x05, 0xBC}; - gatt_central_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet)); + uint8_t packet[] = {0xE2, 0x00, 0xE2, 0x01, 0x34, 0xB1, 0xF7, 0xD1, 0x77, 0x9B, 0xCC, 0x09, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; + hci_packet_handler(NULL, HCI_EVENT_PACKET, NULL, (uint8_t *)&packet, sizeof(packet)); +} + +le_command_status_t le_central_start_scan(void){ + return BLE_PERIPHERAL_OK; +} +le_command_status_t le_central_stop_scan(void){ + return BLE_PERIPHERAL_OK; +} +le_command_status_t le_central_connect(bd_addr_t addr, bd_addr_type_t addr_type){ + return BLE_PERIPHERAL_OK; +} +void le_central_set_scan_parameters(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window){ } static void att_init_connection(att_connection_t * att_connection){ @@ -71,14 +82,17 @@ uint16_t l2cap_max_le_mtu(void){ return max_mtu; } +void l2cap_init(){} + void l2cap_register_fixed_channel(btstack_packet_handler_t packet_handler, uint16_t channel_id) { att_packet_handler = packet_handler; } void l2cap_register_packet_handler(void (*handler)(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)){ - gatt_central_packet_handler = handler; + hci_packet_handler = handler; } + int l2cap_reserve_packet_buffer(void){ return 1; } @@ -123,6 +137,19 @@ int run_loop_remove_timer(timer_source_t *timer){ return 1; } +// todo: +hci_connection_t * hci_connection_for_bd_addr_and_type(bd_addr_t addr, bd_addr_type_t addr_type){ + printf("hci_connection_for_bd_addr_and_type not implemented in mock backend\n"); + return NULL; +} +hci_connection_t * hci_connection_for_handle(hci_con_handle_t con_handle){ + printf("hci_connection_for_handle not implemented in mock backend\n"); + return NULL; +} +void hci_connections_get_iterator(linked_list_iterator_t *it){ + // printf("hci_connections_get_iterator not implemented in mock backend\n"); + linked_list_iterator_init(it, &connections); +} // int hci_send_cmd(const hci_cmd_t *cmd, ...){ // // printf("hci_send_cmd opcode 0x%02x\n", cmd->opcode);