1d3762d15SMatthias Ringwald #include <stdint.h> 2d3762d15SMatthias Ringwald #include <stdio.h> 3d3762d15SMatthias Ringwald #include <stdlib.h> 4d3762d15SMatthias Ringwald #include <string.h> 5d3762d15SMatthias Ringwald 6d3762d15SMatthias Ringwald #include "CppUTest/TestHarness.h" 7d3762d15SMatthias Ringwald #include "CppUTest/CommandLineTestRunner.h" 8d3762d15SMatthias Ringwald #include "CppUTestExt/MockSupport.h" 9d3762d15SMatthias Ringwald 10d3762d15SMatthias Ringwald #include "hci_cmd.h" 11d3762d15SMatthias Ringwald 12d3762d15SMatthias Ringwald #include "btstack_memory.h" 13d3762d15SMatthias Ringwald #include "hci.h" 14d3762d15SMatthias Ringwald #include "ble/gatt_client.h" 15d3762d15SMatthias Ringwald #include "btstack_event.h" 16d3762d15SMatthias Ringwald #include "hci_dump.h" 17d3762d15SMatthias Ringwald #include "hci_dump_posix_fs.h" 18d3762d15SMatthias Ringwald #include "btstack_debug.h" 19fcebe167SMilanka Ringwald #include "btstack_util.h" 20fcebe167SMilanka Ringwald #include "btstack_run_loop_posix.h" 21d3762d15SMatthias Ringwald 22d3762d15SMatthias Ringwald typedef struct { 23d3762d15SMatthias Ringwald uint8_t type; 24d3762d15SMatthias Ringwald uint16_t size; 25d3762d15SMatthias Ringwald uint8_t buffer[258]; 26d3762d15SMatthias Ringwald } hci_packet_t; 27d3762d15SMatthias Ringwald 28d3762d15SMatthias Ringwald #define MAX_HCI_PACKETS 10 29d3762d15SMatthias Ringwald static uint16_t transport_count_packets; 30d3762d15SMatthias Ringwald static hci_packet_t transport_packets[MAX_HCI_PACKETS]; 3128739e5fSMatthias Ringwald static int can_send_now = 1; 32d3762d15SMatthias Ringwald static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); 33d3762d15SMatthias Ringwald 34d3762d15SMatthias Ringwald static const uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 35d3762d15SMatthias Ringwald 36d3762d15SMatthias Ringwald static int hci_transport_test_set_baudrate(uint32_t baudrate){ 37d3762d15SMatthias Ringwald return 0; 38d3762d15SMatthias Ringwald } 39d3762d15SMatthias Ringwald 40d3762d15SMatthias Ringwald static int hci_transport_test_can_send_now(uint8_t packet_type){ 4128739e5fSMatthias Ringwald return can_send_now; 42d3762d15SMatthias Ringwald } 43d3762d15SMatthias Ringwald 44d3762d15SMatthias Ringwald static int hci_transport_test_send_packet(uint8_t packet_type, uint8_t * packet, int size){ 45d3762d15SMatthias Ringwald btstack_assert(transport_count_packets < MAX_HCI_PACKETS); 46d3762d15SMatthias Ringwald memcpy(transport_packets[transport_count_packets].buffer, packet, size); 47d3762d15SMatthias Ringwald transport_packets[transport_count_packets].type = packet_type; 48d3762d15SMatthias Ringwald transport_packets[transport_count_packets].size = size; 49d3762d15SMatthias Ringwald transport_count_packets++; 50d3762d15SMatthias Ringwald // notify upper stack that it can send again 51d3762d15SMatthias Ringwald packet_handler(HCI_EVENT_PACKET, (uint8_t *) &packet_sent_event[0], sizeof(packet_sent_event)); 52d3762d15SMatthias Ringwald return 0; 53d3762d15SMatthias Ringwald } 54d3762d15SMatthias Ringwald 55d3762d15SMatthias Ringwald static void hci_transport_test_init(const void * transport_config){ 56d3762d15SMatthias Ringwald } 57d3762d15SMatthias Ringwald 58d3762d15SMatthias Ringwald static int hci_transport_test_open(void){ 59d3762d15SMatthias Ringwald return 0; 60d3762d15SMatthias Ringwald } 61d3762d15SMatthias Ringwald 62d3762d15SMatthias Ringwald static int hci_transport_test_close(void){ 63d3762d15SMatthias Ringwald return 0; 64d3762d15SMatthias Ringwald } 65d3762d15SMatthias Ringwald 66d3762d15SMatthias Ringwald static void hci_transport_test_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 67d3762d15SMatthias Ringwald packet_handler = handler; 68d3762d15SMatthias Ringwald } 69d3762d15SMatthias Ringwald 70d3762d15SMatthias Ringwald static const hci_transport_t hci_transport_test = { 71d3762d15SMatthias Ringwald /* const char * name; */ "TEST", 72d3762d15SMatthias Ringwald /* void (*init) (const void *transport_config); */ &hci_transport_test_init, 73d3762d15SMatthias Ringwald /* int (*open)(void); */ &hci_transport_test_open, 74d3762d15SMatthias Ringwald /* int (*close)(void); */ &hci_transport_test_close, 75d3762d15SMatthias Ringwald /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_test_register_packet_handler, 76d3762d15SMatthias Ringwald /* int (*can_send_packet_now)(uint8_t packet_type); */ &hci_transport_test_can_send_now, 77d3762d15SMatthias Ringwald /* int (*send_packet)(...); */ &hci_transport_test_send_packet, 78d3762d15SMatthias Ringwald /* int (*set_baudrate)(uint32_t baudrate); */ &hci_transport_test_set_baudrate, 79d3762d15SMatthias Ringwald /* void (*reset_link)(void); */ NULL, 80d3762d15SMatthias Ringwald /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL, 81d3762d15SMatthias Ringwald }; 82d3762d15SMatthias Ringwald 83d3762d15SMatthias Ringwald static uint16_t next_hci_packet; 84d3762d15SMatthias Ringwald 85d3762d15SMatthias Ringwald void CHECK_EQUAL_ARRAY(const uint8_t * expected, uint8_t * actual, int size){ 86d3762d15SMatthias Ringwald for (int i=0; i<size; i++){ 87d3762d15SMatthias Ringwald BYTES_EQUAL(expected[i], actual[i]); 88d3762d15SMatthias Ringwald } 89d3762d15SMatthias Ringwald } 90d3762d15SMatthias Ringwald 91d3762d15SMatthias Ringwald void CHECK_HCI_COMMAND(const hci_cmd_t * expected_hci_command){ 92d3762d15SMatthias Ringwald uint16_t actual_opcode = little_endian_read_16(transport_packets[next_hci_packet].buffer, 0); 93d3762d15SMatthias Ringwald next_hci_packet++; 94d3762d15SMatthias Ringwald CHECK_EQUAL(expected_hci_command->opcode, actual_opcode); 95d3762d15SMatthias Ringwald } 96d3762d15SMatthias Ringwald 97d3762d15SMatthias Ringwald TEST_GROUP(HCI){ 98*566df4e8SMatthias Ringwald hci_stack_t * hci_stack; 99*566df4e8SMatthias Ringwald 100d3762d15SMatthias Ringwald void setup(void){ 101d3762d15SMatthias Ringwald transport_count_packets = 0; 10228739e5fSMatthias Ringwald can_send_now = 1; 103d3762d15SMatthias Ringwald next_hci_packet = 0; 104d3762d15SMatthias Ringwald hci_init(&hci_transport_test, NULL); 105*566df4e8SMatthias Ringwald hci_stack = hci_get_stack(); 106d3762d15SMatthias Ringwald hci_simulate_working_fuzz(); 107d3762d15SMatthias Ringwald hci_setup_test_connections_fuzz(); 108d3762d15SMatthias Ringwald // register for HCI events 109d3762d15SMatthias Ringwald mock().expectOneCall("hci_can_send_packet_now_using_packet_buffer").andReturnValue(1); 110d3762d15SMatthias Ringwald } 111d3762d15SMatthias Ringwald void teardown(void){ 112d3762d15SMatthias Ringwald mock().clear(); 113d3762d15SMatthias Ringwald } 114d3762d15SMatthias Ringwald }; 115d3762d15SMatthias Ringwald 116d3762d15SMatthias Ringwald TEST(HCI, GetSetConnectionRange){ 117d3762d15SMatthias Ringwald le_connection_parameter_range_t range; 118d3762d15SMatthias Ringwald gap_get_connection_parameter_range(&range); 119d3762d15SMatthias Ringwald gap_set_connection_parameter_range(&range); 120d3762d15SMatthias Ringwald } 121d3762d15SMatthias Ringwald 122d3762d15SMatthias Ringwald TEST(HCI, ConnectionRangeValid){ 123d3762d15SMatthias Ringwald le_connection_parameter_range_t range = { 124fcebe167SMilanka Ringwald .le_conn_interval_min = 1, 125fcebe167SMilanka Ringwald .le_conn_interval_max = 10, 126fcebe167SMilanka Ringwald .le_conn_latency_min = 1, 127fcebe167SMilanka Ringwald .le_conn_latency_max = 10, 128fcebe167SMilanka Ringwald .le_supervision_timeout_min = 1, 129fcebe167SMilanka Ringwald .le_supervision_timeout_max = 10 130d3762d15SMatthias Ringwald }; 131d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 0, 0, 0, 0)); 132fcebe167SMilanka Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 11, 0, 0)); 133fcebe167SMilanka Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 11, 0)); 134d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 0, 0, 0)); 135d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 0, 0)); 136d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 10, 0)); 137d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 5, 0)); 138d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 5, 11)); 139d3762d15SMatthias Ringwald CHECK_EQUAL( 1, gap_connection_parameter_range_included(&range, 2, 9, 5, 5)); 140d3762d15SMatthias Ringwald } 141d3762d15SMatthias Ringwald 142fcebe167SMilanka Ringwald TEST(HCI, other_functions){ 143fcebe167SMilanka Ringwald gap_set_scan_phys(1); 144fcebe167SMilanka Ringwald gap_set_connection_phys(1); 145fcebe167SMilanka Ringwald hci_enable_custom_pre_init(); 146fcebe167SMilanka Ringwald gap_whitelist_clear(); 147fcebe167SMilanka Ringwald } 148fcebe167SMilanka Ringwald 149fcebe167SMilanka Ringwald TEST(HCI, gap_whitelist_add_remove){ 150fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_ACL; 151fcebe167SMilanka Ringwald bd_addr_t addr = { 0 }; 152fcebe167SMilanka Ringwald 153fcebe167SMilanka Ringwald uint8_t status = gap_whitelist_add(addr_type, addr); 154fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 155fcebe167SMilanka Ringwald 156fcebe167SMilanka Ringwald status = gap_whitelist_add(addr_type, addr); 157fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 158fcebe167SMilanka Ringwald 159fcebe167SMilanka Ringwald status = gap_whitelist_remove(addr_type, addr); 160fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 161fcebe167SMilanka Ringwald 162fcebe167SMilanka Ringwald status = gap_whitelist_remove(addr_type, addr); 163e406aa8dSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 164fcebe167SMilanka Ringwald 165fcebe167SMilanka Ringwald status = gap_whitelist_remove(BD_ADDR_TYPE_SCO, addr); 166fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 167fcebe167SMilanka Ringwald } 168fcebe167SMilanka Ringwald 169fcebe167SMilanka Ringwald TEST(HCI, gap_connect_with_whitelist){ 170fcebe167SMilanka Ringwald uint8_t status = gap_connect_with_whitelist(); 171fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 172fcebe167SMilanka Ringwald 17328739e5fSMatthias Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC; 17428739e5fSMatthias Ringwald bd_addr_t addr = { 0 }; 17528739e5fSMatthias Ringwald gap_auto_connection_start(addr_type, addr); 17628739e5fSMatthias Ringwald 177fcebe167SMilanka Ringwald status = gap_connect_with_whitelist(); 178fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 179fcebe167SMilanka Ringwald } 180fcebe167SMilanka Ringwald 181fcebe167SMilanka Ringwald TEST(HCI, gap_auto_connection_start_stop){ 182fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC; 183fcebe167SMilanka Ringwald bd_addr_t addr = { 0 }; 184fcebe167SMilanka Ringwald 185fcebe167SMilanka Ringwald uint8_t status = gap_auto_connection_start(addr_type, addr); 186fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 187fcebe167SMilanka Ringwald 188fcebe167SMilanka Ringwald status = gap_auto_connection_stop(addr_type, addr); 189fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 190fcebe167SMilanka Ringwald } 191fcebe167SMilanka Ringwald 192fcebe167SMilanka Ringwald TEST(HCI, gap_auto_connection_stop_all){ 193fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC; 194fcebe167SMilanka Ringwald bd_addr_t addr = { 0 }; 195fcebe167SMilanka Ringwald 196fcebe167SMilanka Ringwald uint8_t status = gap_auto_connection_start(addr_type, addr); 197fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 198fcebe167SMilanka Ringwald 199fcebe167SMilanka Ringwald status = gap_auto_connection_stop_all(); 200fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 201fcebe167SMilanka Ringwald } 202fcebe167SMilanka Ringwald 203fcebe167SMilanka Ringwald TEST(HCI, gap_read_rssi){ 204fcebe167SMilanka Ringwald int status = gap_read_rssi(HCI_CON_HANDLE_INVALID); 205fcebe167SMilanka Ringwald CHECK_EQUAL(0, status); 206fcebe167SMilanka Ringwald 207fcebe167SMilanka Ringwald status = gap_read_rssi(0x01); 208fcebe167SMilanka Ringwald CHECK_EQUAL(1, status); 209fcebe167SMilanka Ringwald } 210fcebe167SMilanka Ringwald 211fcebe167SMilanka Ringwald TEST(HCI, gap_le_connection_interval){ 212fcebe167SMilanka Ringwald uint16_t con_interval = gap_le_connection_interval(HCI_CON_HANDLE_INVALID); 213fcebe167SMilanka Ringwald CHECK_EQUAL(0, con_interval); 214fcebe167SMilanka Ringwald 215fcebe167SMilanka Ringwald con_interval = gap_le_connection_interval(0x01); 216fcebe167SMilanka Ringwald CHECK_EQUAL(0, con_interval); 217fcebe167SMilanka Ringwald } 218fcebe167SMilanka Ringwald 219fcebe167SMilanka Ringwald 220fcebe167SMilanka Ringwald TEST(HCI, gap_get_connection_type){ 221fcebe167SMilanka Ringwald gap_connection_type_t type = gap_get_connection_type(HCI_CON_HANDLE_INVALID); 222fcebe167SMilanka Ringwald CHECK_EQUAL(GAP_CONNECTION_INVALID, type); 223fcebe167SMilanka Ringwald 224fcebe167SMilanka Ringwald type = gap_get_connection_type(0x01); 225fcebe167SMilanka Ringwald CHECK_EQUAL(GAP_CONNECTION_ACL, type); 226fcebe167SMilanka Ringwald } 227fcebe167SMilanka Ringwald 228fcebe167SMilanka Ringwald TEST(HCI, gap_le_set_phy){ 229fcebe167SMilanka Ringwald uint8_t status = gap_le_set_phy(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0); 230fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 231fcebe167SMilanka Ringwald 232fcebe167SMilanka Ringwald status = gap_le_set_phy(0x01, 0, 0, 0, 0); 233fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 234fcebe167SMilanka Ringwald } 235fcebe167SMilanka Ringwald 236fcebe167SMilanka Ringwald TEST(HCI, hci_connection_for_bd_addr_and_type){ 237fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_ACL; 238fcebe167SMilanka Ringwald bd_addr_t addr = { 0 }; 239fcebe167SMilanka Ringwald 240fcebe167SMilanka Ringwald hci_connection_t * con = hci_connection_for_bd_addr_and_type(addr , addr_type); 241fcebe167SMilanka Ringwald CHECK_EQUAL(NULL, con); 242fcebe167SMilanka Ringwald } 243fcebe167SMilanka Ringwald 244fcebe167SMilanka Ringwald TEST(HCI, hci_number_free_acl_slots_for_handle){ 245fcebe167SMilanka Ringwald int free_acl_slots_num = hci_number_free_acl_slots_for_handle(HCI_CON_HANDLE_INVALID); 246fcebe167SMilanka Ringwald CHECK_EQUAL(0, free_acl_slots_num); 247fcebe167SMilanka Ringwald } 248fcebe167SMilanka Ringwald 249*566df4e8SMatthias Ringwald TEST(HCI, hci_send_acl_packet_buffer_no_connection){ 250*566df4e8SMatthias Ringwald hci_reserve_packet_buffer(); 251*566df4e8SMatthias Ringwald uint8_t status = hci_send_acl_packet_buffer(16); 252*566df4e8SMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 253*566df4e8SMatthias Ringwald } 254*566df4e8SMatthias Ringwald 255fcebe167SMilanka Ringwald TEST(HCI, hci_send_acl_packet_buffer){ 256fcebe167SMilanka Ringwald hci_reserve_packet_buffer(); 257*566df4e8SMatthias Ringwald uint8_t * packet = hci_get_outgoing_packet_buffer(); 258*566df4e8SMatthias Ringwald uint8_t flags = 0x02; 259*566df4e8SMatthias Ringwald // LE Packet 260*566df4e8SMatthias Ringwald uint16_t acl_len = 50; 261*566df4e8SMatthias Ringwald hci_stack->le_data_packets_length = acl_len - 10;; 262*566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, 0x05 | (flags << 12)); 263*566df4e8SMatthias Ringwald uint8_t status = hci_send_acl_packet_buffer(acl_len); 264*566df4e8SMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 265*566df4e8SMatthias Ringwald hci_stack->le_data_packets_length = 0; 266fcebe167SMilanka Ringwald } 267fcebe167SMilanka Ringwald 268fcebe167SMilanka Ringwald TEST(HCI, hci_send_cmd_packet){ 269fcebe167SMilanka Ringwald bd_addr_t addr = { 0 }; 270fcebe167SMilanka Ringwald 271fcebe167SMilanka Ringwald uint8_t status = hci_send_cmd(&hci_write_loopback_mode, 1); 272fcebe167SMilanka Ringwald CHECK_EQUAL(0, status); 273fcebe167SMilanka Ringwald 274fcebe167SMilanka Ringwald uint8_t i; 275fcebe167SMilanka Ringwald for (i = 0; i < 3; i++){ 276fcebe167SMilanka Ringwald status = hci_send_cmd(&hci_le_create_connection, 277fcebe167SMilanka Ringwald 1000, // scan interval: 625 ms 278fcebe167SMilanka Ringwald 1000, // scan interval: 625 ms 279fcebe167SMilanka Ringwald i, // don't use whitelist 280fcebe167SMilanka Ringwald 0, // peer address type: public 281fcebe167SMilanka Ringwald addr, // remote bd addr 282fcebe167SMilanka Ringwald 0, // random or public 283fcebe167SMilanka Ringwald 80, // conn interval min 284fcebe167SMilanka Ringwald 80, // conn interval max (3200 * 0.625) 285fcebe167SMilanka Ringwald 0, // conn latency 286fcebe167SMilanka Ringwald 2000, // supervision timeout 287fcebe167SMilanka Ringwald 0, // min ce length 288fcebe167SMilanka Ringwald 1000 // max ce length 289fcebe167SMilanka Ringwald ); 290fcebe167SMilanka Ringwald CHECK_EQUAL(0, status); 291fcebe167SMilanka Ringwald } 292fcebe167SMilanka Ringwald } 293fcebe167SMilanka Ringwald 294fcebe167SMilanka Ringwald TEST(HCI, hci_send_cmd_va_arg){ 295fcebe167SMilanka Ringwald hci_reserve_packet_buffer(); 296fcebe167SMilanka Ringwald uint8_t status = hci_send_cmd(&hci_write_loopback_mode, 1); 297fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 298fcebe167SMilanka Ringwald } 299fcebe167SMilanka Ringwald 300fcebe167SMilanka Ringwald TEST(HCI, hci_power_control){ 301fcebe167SMilanka Ringwald int status = hci_power_control(HCI_POWER_ON); 302fcebe167SMilanka Ringwald CHECK_EQUAL(0, status); 303fcebe167SMilanka Ringwald } 304fcebe167SMilanka Ringwald 305d3762d15SMatthias Ringwald TEST(HCI, NumPeripherals){ 306d3762d15SMatthias Ringwald gap_set_max_number_peripheral_connections(1); 307d3762d15SMatthias Ringwald } 308d3762d15SMatthias Ringwald 309d3762d15SMatthias Ringwald TEST(HCI, MaxAclLen){ 310d3762d15SMatthias Ringwald hci_max_acl_data_packet_length(); 311d3762d15SMatthias Ringwald } 312d3762d15SMatthias Ringwald 313d3762d15SMatthias Ringwald TEST(HCI, Flushable){ 314d3762d15SMatthias Ringwald hci_non_flushable_packet_boundary_flag_supported(); 315d3762d15SMatthias Ringwald } 316d3762d15SMatthias Ringwald 317d3762d15SMatthias Ringwald TEST(HCI, RemovePacketHandler){ 318d3762d15SMatthias Ringwald hci_remove_event_handler(NULL); 319d3762d15SMatthias Ringwald } 320d3762d15SMatthias Ringwald 321d3762d15SMatthias Ringwald static void dummy_fn(const void * config){}; 322d3762d15SMatthias Ringwald TEST(HCI, SetChipset){ 323d3762d15SMatthias Ringwald hci_set_chipset(NULL); 324d3762d15SMatthias Ringwald btstack_chipset_t chipset_driver = { 0 }; 325d3762d15SMatthias Ringwald hci_set_chipset(NULL); 326d3762d15SMatthias Ringwald chipset_driver.init = dummy_fn; 327d3762d15SMatthias Ringwald } 328d3762d15SMatthias Ringwald 329d3762d15SMatthias Ringwald TEST(HCI, SetControl){ 330d3762d15SMatthias Ringwald btstack_control_t hardware_control = { .init = &dummy_fn}; 331d3762d15SMatthias Ringwald hci_set_control(&hardware_control); 332d3762d15SMatthias Ringwald } 333d3762d15SMatthias Ringwald 334d3762d15SMatthias Ringwald //TEST(HCI, Close){ 335d3762d15SMatthias Ringwald // hci_close(); 336d3762d15SMatthias Ringwald //} 337d3762d15SMatthias Ringwald 338d3762d15SMatthias Ringwald TEST(HCI, SetPublicAddress){ 339d3762d15SMatthias Ringwald bd_addr_t addr = { 0 }; 340d3762d15SMatthias Ringwald hci_set_bd_addr(addr); 341d3762d15SMatthias Ringwald } 342d3762d15SMatthias Ringwald 343d3762d15SMatthias Ringwald TEST(HCI, DisconnectSecurityBlock){ 344d3762d15SMatthias Ringwald hci_disconnect_security_block(HCI_CON_HANDLE_INVALID); 345d3762d15SMatthias Ringwald hci_disconnect_security_block(3); 346d3762d15SMatthias Ringwald } 347d3762d15SMatthias Ringwald 348d3762d15SMatthias Ringwald TEST(HCI, SetDuplicateFilter){ 349d3762d15SMatthias Ringwald gap_set_scan_duplicate_filter(true); 350d3762d15SMatthias Ringwald } 351d3762d15SMatthias Ringwald 352d3762d15SMatthias Ringwald TEST(HCI, ConnectCancel){ 35328739e5fSMatthias Ringwald uint8_t status; 35428739e5fSMatthias Ringwald status = gap_connect_with_whitelist(); 35528739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 35628739e5fSMatthias Ringwald gap_connect_cancel(); 35728739e5fSMatthias Ringwald 35828739e5fSMatthias Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC; 35928739e5fSMatthias Ringwald bd_addr_t addr = { 0 }; 36028739e5fSMatthias Ringwald gap_connect(addr, addr_type); 361d3762d15SMatthias Ringwald gap_connect_cancel(); 362d3762d15SMatthias Ringwald } 363d3762d15SMatthias Ringwald 364d3762d15SMatthias Ringwald TEST(HCI, SetGapConnParams){ 365d3762d15SMatthias Ringwald gap_set_connection_parameters(0, 0, 0, 0, 0, 0, 0, 0); 366d3762d15SMatthias Ringwald } 367d3762d15SMatthias Ringwald 368d3762d15SMatthias Ringwald TEST(HCI, UpdateConnParams){ 369d3762d15SMatthias Ringwald gap_update_connection_parameters(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0); 370d3762d15SMatthias Ringwald gap_update_connection_parameters(5, 0, 0, 0, 0); 371d3762d15SMatthias Ringwald } 372d3762d15SMatthias Ringwald 373d3762d15SMatthias Ringwald TEST(HCI, RequestConnParamUpdate){ 374d3762d15SMatthias Ringwald gap_request_connection_parameter_update(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0); 375d3762d15SMatthias Ringwald gap_request_connection_parameter_update(5, 0, 0, 0, 0); 376d3762d15SMatthias Ringwald } 377d3762d15SMatthias Ringwald 378d3762d15SMatthias Ringwald TEST(HCI, SetScanResponse){ 379d3762d15SMatthias Ringwald gap_scan_response_set_data(0, NULL); 380d3762d15SMatthias Ringwald } 381d3762d15SMatthias Ringwald 382d3762d15SMatthias Ringwald TEST(HCI, SetAddrType){ 383d3762d15SMatthias Ringwald hci_le_set_own_address_type(0); 384d3762d15SMatthias Ringwald hci_le_set_own_address_type(1); 385d3762d15SMatthias Ringwald } 386d3762d15SMatthias Ringwald 387d3762d15SMatthias Ringwald TEST(HCI, AdvEnable){ 388d3762d15SMatthias Ringwald gap_advertisements_enable(0); 389d3762d15SMatthias Ringwald gap_advertisements_enable(1); 390d3762d15SMatthias Ringwald } 391d3762d15SMatthias Ringwald 392d3762d15SMatthias Ringwald TEST(HCI, SetRandomAddr){ 393d3762d15SMatthias Ringwald bd_addr_t addr = { 0 }; 394d3762d15SMatthias Ringwald hci_le_random_address_set(addr); 395d3762d15SMatthias Ringwald } 396d3762d15SMatthias Ringwald 397d3762d15SMatthias Ringwald TEST(HCI, Disconnect){ 398d3762d15SMatthias Ringwald gap_disconnect(HCI_CON_HANDLE_INVALID); 399d3762d15SMatthias Ringwald gap_disconnect(5); 400d3762d15SMatthias Ringwald } 401d3762d15SMatthias Ringwald 402d3762d15SMatthias Ringwald TEST(HCI, GetRole){ 403d3762d15SMatthias Ringwald gap_get_role(HCI_CON_HANDLE_INVALID); 404d3762d15SMatthias Ringwald gap_get_role(5); 405d3762d15SMatthias Ringwald } 40628739e5fSMatthias Ringwald TEST(HCI, hci_is_le_identity_address_type_other){ 40728739e5fSMatthias Ringwald hci_is_le_identity_address_type(BD_ADDR_TYPE_LE_PUBLIC_IDENTITY); 40828739e5fSMatthias Ringwald hci_is_le_identity_address_type(BD_ADDR_TYPE_LE_RANDOM); 40928739e5fSMatthias Ringwald } 41028739e5fSMatthias Ringwald 41128739e5fSMatthias Ringwald TEST(HCI, hci_can_send_command_packet_now){ 41228739e5fSMatthias Ringwald can_send_now = 0; 41328739e5fSMatthias Ringwald hci_can_send_command_packet_now(); 41428739e5fSMatthias Ringwald can_send_now = 1; 41528739e5fSMatthias Ringwald hci_can_send_command_packet_now(); 41628739e5fSMatthias Ringwald } 41728739e5fSMatthias Ringwald 41828739e5fSMatthias Ringwald TEST(HCI, hci_can_send_prepared_acl_packet_now){ 41928739e5fSMatthias Ringwald can_send_now = 0; 42028739e5fSMatthias Ringwald hci_can_send_prepared_acl_packet_now(0); 42128739e5fSMatthias Ringwald can_send_now = 1; 42228739e5fSMatthias Ringwald hci_can_send_prepared_acl_packet_now(0); 42328739e5fSMatthias Ringwald } 42428739e5fSMatthias Ringwald 42528739e5fSMatthias Ringwald TEST(HCI, hci_can_send_acl_le_packet_now) { 42628739e5fSMatthias Ringwald can_send_now = 0; 42728739e5fSMatthias Ringwald hci_can_send_acl_le_packet_now(); 42828739e5fSMatthias Ringwald can_send_now = 1; 42928739e5fSMatthias Ringwald hci_can_send_acl_le_packet_now(); 43028739e5fSMatthias Ringwald } 431*566df4e8SMatthias Ringwald TEST(HCI, hci_number_free_acl_slots_for_connection_type) { 432*566df4e8SMatthias Ringwald CHECK_EQUAL(0, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_UNKNOWN)); 433*566df4e8SMatthias Ringwald CHECK_EQUAL(255, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_ACL)); 434*566df4e8SMatthias Ringwald CHECK_EQUAL(255, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_LE_PUBLIC)); 435*566df4e8SMatthias Ringwald // tweak stack 436*566df4e8SMatthias Ringwald hci_stack_t * hci_stack = hci_get_stack(); 437*566df4e8SMatthias Ringwald hci_stack->le_acl_packets_total_num = 1; 438*566df4e8SMatthias Ringwald CHECK_EQUAL(1, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_LE_PUBLIC)); 43928739e5fSMatthias Ringwald } 44028739e5fSMatthias Ringwald 441*566df4e8SMatthias Ringwald // TEST(HCI, hci_close) { 442*566df4e8SMatthias Ringwald // hci_close(); 443*566df4e8SMatthias Ringwald // } 444*566df4e8SMatthias Ringwald 44528739e5fSMatthias Ringwald TEST(HCI, gap_connect) { 44628739e5fSMatthias Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC; 44728739e5fSMatthias Ringwald bd_addr_t addr = { 0 }; 44828739e5fSMatthias Ringwald 44928739e5fSMatthias Ringwald uint8_t status; 45028739e5fSMatthias Ringwald status = gap_connect(addr, addr_type); 45128739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 45228739e5fSMatthias Ringwald status = gap_connect(addr, addr_type); 45328739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 45428739e5fSMatthias Ringwald } 45528739e5fSMatthias Ringwald 45628739e5fSMatthias Ringwald TEST(HCI, hci_emit_state) { 45728739e5fSMatthias Ringwald hci_emit_state(); 45828739e5fSMatthias Ringwald } 45928739e5fSMatthias Ringwald 46028739e5fSMatthias Ringwald TEST(HCI, gap_request_connection_subrating) { 46128739e5fSMatthias Ringwald int status = gap_request_connection_subrating(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0, 0); 46228739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 46328739e5fSMatthias Ringwald status = gap_request_connection_subrating(0x01, 0, 0, 0, 0, 0); 46428739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 46528739e5fSMatthias Ringwald } 46628739e5fSMatthias Ringwald 46728739e5fSMatthias Ringwald 46828739e5fSMatthias Ringwald TEST(HCI, hci_set_hardware_error_callback) { 46928739e5fSMatthias Ringwald hci_set_hardware_error_callback(NULL); 47028739e5fSMatthias Ringwald } 47128739e5fSMatthias Ringwald 47228739e5fSMatthias Ringwald TEST(HCI, hci_disconnect_all) { 47328739e5fSMatthias Ringwald hci_disconnect_all(); 47428739e5fSMatthias Ringwald } 47528739e5fSMatthias Ringwald 47628739e5fSMatthias Ringwald TEST(HCI, hci_get_manufacturer) { 47728739e5fSMatthias Ringwald hci_get_manufacturer(); 47828739e5fSMatthias Ringwald } 47928739e5fSMatthias Ringwald TEST(HCI, gap_authorization_state) { 48028739e5fSMatthias Ringwald gap_authorization_state(HCI_CON_HANDLE_INVALID); 48128739e5fSMatthias Ringwald } 48228739e5fSMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION 48328739e5fSMatthias Ringwald TEST(HCI, hci_load_le_device_db_entry_into_resolving_list) { 48428739e5fSMatthias Ringwald hci_load_le_device_db_entry_into_resolving_list(0); 48528739e5fSMatthias Ringwald } 48628739e5fSMatthias Ringwald 48728739e5fSMatthias Ringwald TEST(HCI, hci_remove_le_device_db_entry_from_resolving_list) { 48828739e5fSMatthias Ringwald hci_remove_le_device_db_entry_from_resolving_list(0); 48928739e5fSMatthias Ringwald } 49028739e5fSMatthias Ringwald 49128739e5fSMatthias Ringwald TEST(HCI, gap_load_resolving_list_from_le_device_db) { 49228739e5fSMatthias Ringwald gap_load_resolving_list_from_le_device_db(); 49328739e5fSMatthias Ringwald } 49428739e5fSMatthias Ringwald #endif 49528739e5fSMatthias Ringwald 49628739e5fSMatthias Ringwald TEST(HCI, gap_privacy_client) { 49728739e5fSMatthias Ringwald gap_privacy_client_t client; 49828739e5fSMatthias Ringwald gap_privacy_client_register(&client); 49928739e5fSMatthias Ringwald gap_privacy_client_ready(&client); 50028739e5fSMatthias Ringwald gap_privacy_client_unregister(&client); 50128739e5fSMatthias Ringwald } 502d3762d15SMatthias Ringwald 503*566df4e8SMatthias Ringwald TEST(HCI, acl_handling) { 504*566df4e8SMatthias Ringwald uint16_t con_handle = 1; 505*566df4e8SMatthias Ringwald uint8_t flags = 0; 506*566df4e8SMatthias Ringwald 507*566df4e8SMatthias Ringwald uint8_t packet[16]; 508*566df4e8SMatthias Ringwald // no connection for invalid handle 509*566df4e8SMatthias Ringwald memset(packet, 0xff, sizeof(packet)); 510*566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 511*566df4e8SMatthias Ringwald // invalid length 512*566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 513*566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 514*566df4e8SMatthias Ringwald // fix length 515*566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 12); 516*566df4e8SMatthias Ringwald little_endian_store_16(packet, 6, 8); 517*566df4e8SMatthias Ringwald 518*566df4e8SMatthias Ringwald // unexpected acl continuation 519*566df4e8SMatthias Ringwald flags = 0x01; 520*566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 521*566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 522*566df4e8SMatthias Ringwald // invalid packet boundary flags 523*566df4e8SMatthias Ringwald flags = 0x03; 524*566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 525*566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 526*566df4e8SMatthias Ringwald // oversized first fragment 527*566df4e8SMatthias Ringwald flags = 0x02; 528*566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 529*566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 1996); 530*566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, 2000); 531*566df4e8SMatthias Ringwald 532*566df4e8SMatthias Ringwald // 1a store first flushable fragment 533*566df4e8SMatthias Ringwald flags = 0x02; 534*566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 535*566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 12); 536*566df4e8SMatthias Ringwald little_endian_store_16(packet, 4, 20); 537*566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 538*566df4e8SMatthias Ringwald 539*566df4e8SMatthias Ringwald // 1b another first non-flushable 540*566df4e8SMatthias Ringwald flags = 0x06; 541*566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 542*566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 543*566df4e8SMatthias Ringwald 544*566df4e8SMatthias Ringwald // 1c another first 545*566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 546*566df4e8SMatthias Ringwald 547*566df4e8SMatthias Ringwald // oversized continuation fragment 548*566df4e8SMatthias Ringwald flags = 0x01; 549*566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 550*566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 1996); 551*566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, 2000); 552*566df4e8SMatthias Ringwald } 553*566df4e8SMatthias Ringwald TEST(HCI, gap_le_get_own_address) { 554*566df4e8SMatthias Ringwald uint8_t addr_type; 555*566df4e8SMatthias Ringwald bd_addr_t addr; 556*566df4e8SMatthias Ringwald hci_stack->le_own_addr_type = BD_ADDR_TYPE_LE_PUBLIC; 557*566df4e8SMatthias Ringwald gap_le_get_own_address(&addr_type, addr); 558*566df4e8SMatthias Ringwald hci_stack->le_own_addr_type = BD_ADDR_TYPE_LE_RANDOM; 559*566df4e8SMatthias Ringwald gap_le_get_own_address(&addr_type, addr); 560*566df4e8SMatthias Ringwald } 561*566df4e8SMatthias Ringwald 562*566df4e8SMatthias Ringwald static void simulate_hci_command_complete(uint16_t opcode, uint8_t status) { 563*566df4e8SMatthias Ringwald uint8_t packet[30]; 564*566df4e8SMatthias Ringwald packet[0] = HCI_EVENT_COMMAND_COMPLETE; 565*566df4e8SMatthias Ringwald packet[1] = sizeof(packet)-2; 566*566df4e8SMatthias Ringwald packet[2] = 1; 567*566df4e8SMatthias Ringwald little_endian_store_16(packet, 3, opcode); 568*566df4e8SMatthias Ringwald packet[5] = status; 569*566df4e8SMatthias Ringwald packet_handler(HCI_EVENT_PACKET, packet, sizeof(packet)); 570*566df4e8SMatthias Ringwald } 571*566df4e8SMatthias Ringwald 572*566df4e8SMatthias Ringwald TEST(HCI, handle_command_complete_event) { 573*566df4e8SMatthias Ringwald struct { 574*566df4e8SMatthias Ringwald uint16_t opcode; 575*566df4e8SMatthias Ringwald uint8_t status; 576*566df4e8SMatthias Ringwald } variations[] = { 577*566df4e8SMatthias Ringwald {HCI_OPCODE_HCI_READ_LOCAL_NAME, ERROR_CODE_SUCCESS}, 578*566df4e8SMatthias Ringwald {HCI_OPCODE_HCI_READ_LOCAL_NAME, ERROR_CODE_UNKNOWN_HCI_COMMAND }, 579*566df4e8SMatthias Ringwald {HCI_OPCODE_HCI_READ_BUFFER_SIZE, ERROR_CODE_SUCCESS}, 580*566df4e8SMatthias Ringwald {HCI_OPCODE_HCI_READ_RSSI, ERROR_CODE_SUCCESS}, 581*566df4e8SMatthias Ringwald {HCI_OPCODE_HCI_READ_RSSI, ERROR_CODE_UNKNOWN_HCI_COMMAND}, 582*566df4e8SMatthias Ringwald }; 583*566df4e8SMatthias Ringwald for (uint8_t i = 0; i < sizeof(variations) / sizeof(variations[0]); i++) { 584*566df4e8SMatthias Ringwald // extras 585*566df4e8SMatthias Ringwald uint16_t opcode = variations[i].opcode; 586*566df4e8SMatthias Ringwald uint8_t status = variations[i].status; 587*566df4e8SMatthias Ringwald switch (opcode) { 588*566df4e8SMatthias Ringwald default: 589*566df4e8SMatthias Ringwald break; 590*566df4e8SMatthias Ringwald } 591*566df4e8SMatthias Ringwald simulate_hci_command_complete(opcode, status); 592*566df4e8SMatthias Ringwald switch (opcode) { 593*566df4e8SMatthias Ringwald default: 594*566df4e8SMatthias Ringwald break; 595*566df4e8SMatthias Ringwald } 596*566df4e8SMatthias Ringwald } 597*566df4e8SMatthias Ringwald } 598*566df4e8SMatthias Ringwald 599d3762d15SMatthias Ringwald int main (int argc, const char * argv[]){ 600fcebe167SMilanka Ringwald btstack_run_loop_init(btstack_run_loop_posix_get_instance()); 601d3762d15SMatthias Ringwald return CommandLineTestRunner::RunAllTests(argc, argv); 602d3762d15SMatthias Ringwald } 603