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 34*5308d607SMatthias Ringwald #if 0 35*5308d607SMatthias Ringwald static btstack_timer_source_t packet_sent_timer; 36*5308d607SMatthias Ringwald 37d3762d15SMatthias Ringwald static const uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 38d3762d15SMatthias Ringwald 39*5308d607SMatthias Ringwald // sm_trigger_run allows to schedule callback from main run loop // reduces stack depth 40*5308d607SMatthias Ringwald static void hci_transport_emit_packet_sent(btstack_timer_source_t * ts){ 41*5308d607SMatthias Ringwald UNUSED(ts); 42*5308d607SMatthias Ringwald // notify upper stack that it can send again 43*5308d607SMatthias Ringwald can_send_now = 1; 44*5308d607SMatthias Ringwald packet_handler(HCI_EVENT_PACKET, (uint8_t *) &packet_sent_event[0], sizeof(packet_sent_event)); 45*5308d607SMatthias Ringwald } 46*5308d607SMatthias Ringwald 47*5308d607SMatthias Ringwald static void hci_transport_trigger_packet_sent(void) { 48*5308d607SMatthias Ringwald btstack_run_loop_remove_timer(&packet_sent_timer); 49*5308d607SMatthias Ringwald btstack_run_loop_set_timer_handler(&packet_sent_timer, &hci_transport_emit_packet_sent); 50*5308d607SMatthias Ringwald btstack_run_loop_set_timer(&packet_sent_timer, 0); 51*5308d607SMatthias Ringwald btstack_run_loop_add_timer(&packet_sent_timer); 52d3762d15SMatthias Ringwald } 53d3762d15SMatthias Ringwald 54d3762d15SMatthias Ringwald static int hci_transport_test_can_send_now(uint8_t packet_type){ 5528739e5fSMatthias Ringwald return can_send_now; 56d3762d15SMatthias Ringwald } 57*5308d607SMatthias Ringwald #endif 58*5308d607SMatthias Ringwald 59*5308d607SMatthias Ringwald static int hci_transport_test_set_baudrate(uint32_t baudrate){ 60*5308d607SMatthias Ringwald return 0; 61*5308d607SMatthias Ringwald } 62d3762d15SMatthias Ringwald 63d3762d15SMatthias Ringwald static int hci_transport_test_send_packet(uint8_t packet_type, uint8_t * packet, int size){ 64d3762d15SMatthias Ringwald btstack_assert(transport_count_packets < MAX_HCI_PACKETS); 65d3762d15SMatthias Ringwald memcpy(transport_packets[transport_count_packets].buffer, packet, size); 66d3762d15SMatthias Ringwald transport_packets[transport_count_packets].type = packet_type; 67d3762d15SMatthias Ringwald transport_packets[transport_count_packets].size = size; 68d3762d15SMatthias Ringwald transport_count_packets++; 69d3762d15SMatthias Ringwald return 0; 70d3762d15SMatthias Ringwald } 71d3762d15SMatthias Ringwald 72d3762d15SMatthias Ringwald static void hci_transport_test_init(const void * transport_config){ 73d3762d15SMatthias Ringwald } 74d3762d15SMatthias Ringwald 75d3762d15SMatthias Ringwald static int hci_transport_test_open(void){ 76d3762d15SMatthias Ringwald return 0; 77d3762d15SMatthias Ringwald } 78d3762d15SMatthias Ringwald 79d3762d15SMatthias Ringwald static int hci_transport_test_close(void){ 80d3762d15SMatthias Ringwald return 0; 81d3762d15SMatthias Ringwald } 82d3762d15SMatthias Ringwald 83d3762d15SMatthias Ringwald static void hci_transport_test_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 84d3762d15SMatthias Ringwald packet_handler = handler; 85d3762d15SMatthias Ringwald } 86d3762d15SMatthias Ringwald 87d3762d15SMatthias Ringwald static const hci_transport_t hci_transport_test = { 88d3762d15SMatthias Ringwald /* const char * name; */ "TEST", 89d3762d15SMatthias Ringwald /* void (*init) (const void *transport_config); */ &hci_transport_test_init, 90d3762d15SMatthias Ringwald /* int (*open)(void); */ &hci_transport_test_open, 91d3762d15SMatthias Ringwald /* int (*close)(void); */ &hci_transport_test_close, 92d3762d15SMatthias Ringwald /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_test_register_packet_handler, 93*5308d607SMatthias Ringwald /* int (*can_send_packet_now)(uint8_t packet_type); */ NULL, 94d3762d15SMatthias Ringwald /* int (*send_packet)(...); */ &hci_transport_test_send_packet, 95d3762d15SMatthias Ringwald /* int (*set_baudrate)(uint32_t baudrate); */ &hci_transport_test_set_baudrate, 96d3762d15SMatthias Ringwald /* void (*reset_link)(void); */ NULL, 97d3762d15SMatthias Ringwald /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL, 98d3762d15SMatthias Ringwald }; 99d3762d15SMatthias Ringwald 100d3762d15SMatthias Ringwald static uint16_t next_hci_packet; 101d3762d15SMatthias Ringwald 102*5308d607SMatthias Ringwald void CHECK_EQUAL_ARRAY(const uint8_t * expected, const uint8_t * actual, int size){ 103d3762d15SMatthias Ringwald for (int i=0; i<size; i++){ 104d3762d15SMatthias Ringwald BYTES_EQUAL(expected[i], actual[i]); 105d3762d15SMatthias Ringwald } 106d3762d15SMatthias Ringwald } 107d3762d15SMatthias Ringwald 108d3762d15SMatthias Ringwald void CHECK_HCI_COMMAND(const hci_cmd_t * expected_hci_command){ 109d3762d15SMatthias Ringwald uint16_t actual_opcode = little_endian_read_16(transport_packets[next_hci_packet].buffer, 0); 110d3762d15SMatthias Ringwald next_hci_packet++; 111d3762d15SMatthias Ringwald CHECK_EQUAL(expected_hci_command->opcode, actual_opcode); 112d3762d15SMatthias Ringwald } 113d3762d15SMatthias Ringwald 114d3762d15SMatthias Ringwald TEST_GROUP(HCI){ 115566df4e8SMatthias Ringwald hci_stack_t * hci_stack; 116566df4e8SMatthias Ringwald 117d3762d15SMatthias Ringwald void setup(void){ 118d3762d15SMatthias Ringwald transport_count_packets = 0; 11928739e5fSMatthias Ringwald can_send_now = 1; 120d3762d15SMatthias Ringwald next_hci_packet = 0; 121d3762d15SMatthias Ringwald hci_init(&hci_transport_test, NULL); 122566df4e8SMatthias Ringwald hci_stack = hci_get_stack(); 123d3762d15SMatthias Ringwald hci_simulate_working_fuzz(); 124d3762d15SMatthias Ringwald hci_setup_test_connections_fuzz(); 125d3762d15SMatthias Ringwald // register for HCI events 126d3762d15SMatthias Ringwald mock().expectOneCall("hci_can_send_packet_now_using_packet_buffer").andReturnValue(1); 127d3762d15SMatthias Ringwald } 128d3762d15SMatthias Ringwald void teardown(void){ 129d3762d15SMatthias Ringwald mock().clear(); 130d3762d15SMatthias Ringwald } 131d3762d15SMatthias Ringwald }; 132d3762d15SMatthias Ringwald 133d3762d15SMatthias Ringwald TEST(HCI, GetSetConnectionRange){ 134d3762d15SMatthias Ringwald le_connection_parameter_range_t range; 135d3762d15SMatthias Ringwald gap_get_connection_parameter_range(&range); 136d3762d15SMatthias Ringwald gap_set_connection_parameter_range(&range); 137d3762d15SMatthias Ringwald } 138d3762d15SMatthias Ringwald 139d3762d15SMatthias Ringwald TEST(HCI, ConnectionRangeValid){ 140d3762d15SMatthias Ringwald le_connection_parameter_range_t range = { 141fcebe167SMilanka Ringwald .le_conn_interval_min = 1, 142fcebe167SMilanka Ringwald .le_conn_interval_max = 10, 143fcebe167SMilanka Ringwald .le_conn_latency_min = 1, 144fcebe167SMilanka Ringwald .le_conn_latency_max = 10, 145fcebe167SMilanka Ringwald .le_supervision_timeout_min = 1, 146fcebe167SMilanka Ringwald .le_supervision_timeout_max = 10 147d3762d15SMatthias Ringwald }; 148d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 0, 0, 0, 0)); 149fcebe167SMilanka Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 11, 0, 0)); 150fcebe167SMilanka Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 11, 0)); 151d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 0, 0, 0)); 152d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 0, 0)); 153d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 10, 0)); 154d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 5, 0)); 155d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 5, 11)); 156d3762d15SMatthias Ringwald CHECK_EQUAL( 1, gap_connection_parameter_range_included(&range, 2, 9, 5, 5)); 157d3762d15SMatthias Ringwald } 158d3762d15SMatthias Ringwald 159fcebe167SMilanka Ringwald TEST(HCI, other_functions){ 160fcebe167SMilanka Ringwald gap_set_scan_phys(1); 161fcebe167SMilanka Ringwald gap_set_connection_phys(1); 162fcebe167SMilanka Ringwald hci_enable_custom_pre_init(); 163fcebe167SMilanka Ringwald gap_whitelist_clear(); 164fcebe167SMilanka Ringwald } 165fcebe167SMilanka Ringwald 166fcebe167SMilanka Ringwald TEST(HCI, gap_whitelist_add_remove){ 167fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_ACL; 168fcebe167SMilanka Ringwald bd_addr_t addr = { 0 }; 169fcebe167SMilanka Ringwald 170fcebe167SMilanka Ringwald uint8_t status = gap_whitelist_add(addr_type, addr); 171fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 172fcebe167SMilanka Ringwald 173fcebe167SMilanka Ringwald status = gap_whitelist_add(addr_type, addr); 174fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 175fcebe167SMilanka Ringwald 176fcebe167SMilanka Ringwald status = gap_whitelist_remove(addr_type, addr); 177fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 178fcebe167SMilanka Ringwald 179fcebe167SMilanka Ringwald status = gap_whitelist_remove(addr_type, addr); 180e406aa8dSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 181fcebe167SMilanka Ringwald 182fcebe167SMilanka Ringwald status = gap_whitelist_remove(BD_ADDR_TYPE_SCO, addr); 183fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 184fcebe167SMilanka Ringwald } 185fcebe167SMilanka Ringwald 186fcebe167SMilanka Ringwald TEST(HCI, gap_connect_with_whitelist){ 187fcebe167SMilanka Ringwald uint8_t status = gap_connect_with_whitelist(); 188fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 189fcebe167SMilanka Ringwald 19028739e5fSMatthias Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC; 19128739e5fSMatthias Ringwald bd_addr_t addr = { 0 }; 19228739e5fSMatthias Ringwald gap_auto_connection_start(addr_type, addr); 19328739e5fSMatthias Ringwald 194fcebe167SMilanka Ringwald status = gap_connect_with_whitelist(); 195fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 196fcebe167SMilanka Ringwald } 197fcebe167SMilanka Ringwald 198fcebe167SMilanka Ringwald TEST(HCI, gap_auto_connection_start_stop){ 199fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC; 200fcebe167SMilanka Ringwald bd_addr_t addr = { 0 }; 201fcebe167SMilanka Ringwald 202fcebe167SMilanka Ringwald uint8_t status = gap_auto_connection_start(addr_type, addr); 203fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 204fcebe167SMilanka Ringwald 205fcebe167SMilanka Ringwald status = gap_auto_connection_stop(addr_type, addr); 206fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 207fcebe167SMilanka Ringwald } 208fcebe167SMilanka Ringwald 209fcebe167SMilanka Ringwald TEST(HCI, gap_auto_connection_stop_all){ 210fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC; 211fcebe167SMilanka Ringwald bd_addr_t addr = { 0 }; 212fcebe167SMilanka Ringwald 213fcebe167SMilanka Ringwald uint8_t status = gap_auto_connection_start(addr_type, addr); 214fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 215fcebe167SMilanka Ringwald 216fcebe167SMilanka Ringwald status = gap_auto_connection_stop_all(); 217fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 218fcebe167SMilanka Ringwald } 219fcebe167SMilanka Ringwald 220fcebe167SMilanka Ringwald TEST(HCI, gap_read_rssi){ 221fcebe167SMilanka Ringwald int status = gap_read_rssi(HCI_CON_HANDLE_INVALID); 222fcebe167SMilanka Ringwald CHECK_EQUAL(0, status); 223fcebe167SMilanka Ringwald 224fcebe167SMilanka Ringwald status = gap_read_rssi(0x01); 225fcebe167SMilanka Ringwald CHECK_EQUAL(1, status); 226fcebe167SMilanka Ringwald } 227fcebe167SMilanka Ringwald 228fcebe167SMilanka Ringwald TEST(HCI, gap_le_connection_interval){ 229fcebe167SMilanka Ringwald uint16_t con_interval = gap_le_connection_interval(HCI_CON_HANDLE_INVALID); 230fcebe167SMilanka Ringwald CHECK_EQUAL(0, con_interval); 231fcebe167SMilanka Ringwald 232fcebe167SMilanka Ringwald con_interval = gap_le_connection_interval(0x01); 233fcebe167SMilanka Ringwald CHECK_EQUAL(0, con_interval); 234fcebe167SMilanka Ringwald } 235fcebe167SMilanka Ringwald 236fcebe167SMilanka Ringwald 237fcebe167SMilanka Ringwald TEST(HCI, gap_get_connection_type){ 238fcebe167SMilanka Ringwald gap_connection_type_t type = gap_get_connection_type(HCI_CON_HANDLE_INVALID); 239fcebe167SMilanka Ringwald CHECK_EQUAL(GAP_CONNECTION_INVALID, type); 240fcebe167SMilanka Ringwald 241fcebe167SMilanka Ringwald type = gap_get_connection_type(0x01); 242fcebe167SMilanka Ringwald CHECK_EQUAL(GAP_CONNECTION_ACL, type); 243fcebe167SMilanka Ringwald } 244fcebe167SMilanka Ringwald 245fcebe167SMilanka Ringwald TEST(HCI, gap_le_set_phy){ 246fcebe167SMilanka Ringwald uint8_t status = gap_le_set_phy(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0); 247fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 248fcebe167SMilanka Ringwald 249fcebe167SMilanka Ringwald status = gap_le_set_phy(0x01, 0, 0, 0, 0); 250fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 251fcebe167SMilanka Ringwald } 252fcebe167SMilanka Ringwald 253fcebe167SMilanka Ringwald TEST(HCI, hci_connection_for_bd_addr_and_type){ 254fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_ACL; 255fcebe167SMilanka Ringwald bd_addr_t addr = { 0 }; 256fcebe167SMilanka Ringwald 257fcebe167SMilanka Ringwald hci_connection_t * con = hci_connection_for_bd_addr_and_type(addr , addr_type); 258fcebe167SMilanka Ringwald CHECK_EQUAL(NULL, con); 259fcebe167SMilanka Ringwald } 260fcebe167SMilanka Ringwald 261fcebe167SMilanka Ringwald TEST(HCI, hci_number_free_acl_slots_for_handle){ 262fcebe167SMilanka Ringwald int free_acl_slots_num = hci_number_free_acl_slots_for_handle(HCI_CON_HANDLE_INVALID); 263fcebe167SMilanka Ringwald CHECK_EQUAL(0, free_acl_slots_num); 264fcebe167SMilanka Ringwald } 265fcebe167SMilanka Ringwald 266566df4e8SMatthias Ringwald TEST(HCI, hci_send_acl_packet_buffer_no_connection){ 267566df4e8SMatthias Ringwald hci_reserve_packet_buffer(); 268566df4e8SMatthias Ringwald uint8_t status = hci_send_acl_packet_buffer(16); 269566df4e8SMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 270566df4e8SMatthias Ringwald } 271566df4e8SMatthias Ringwald 272fcebe167SMilanka Ringwald TEST(HCI, hci_send_acl_packet_buffer){ 273fcebe167SMilanka Ringwald hci_reserve_packet_buffer(); 274566df4e8SMatthias Ringwald uint8_t * packet = hci_get_outgoing_packet_buffer(); 275566df4e8SMatthias Ringwald uint8_t flags = 0x02; 276566df4e8SMatthias Ringwald // LE Packet 277566df4e8SMatthias Ringwald uint16_t acl_len = 50; 278566df4e8SMatthias Ringwald hci_stack->le_data_packets_length = acl_len - 10;; 279566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, 0x05 | (flags << 12)); 280566df4e8SMatthias Ringwald uint8_t status = hci_send_acl_packet_buffer(acl_len); 281566df4e8SMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 282566df4e8SMatthias Ringwald hci_stack->le_data_packets_length = 0; 283fcebe167SMilanka Ringwald } 284fcebe167SMilanka Ringwald 285fcebe167SMilanka Ringwald TEST(HCI, hci_send_cmd_packet){ 286fcebe167SMilanka Ringwald bd_addr_t addr = { 0 }; 287fcebe167SMilanka Ringwald 288fcebe167SMilanka Ringwald uint8_t status = hci_send_cmd(&hci_write_loopback_mode, 1); 289fcebe167SMilanka Ringwald CHECK_EQUAL(0, status); 290fcebe167SMilanka Ringwald 291fcebe167SMilanka Ringwald uint8_t i; 292fcebe167SMilanka Ringwald for (i = 0; i < 3; i++){ 293fcebe167SMilanka Ringwald status = hci_send_cmd(&hci_le_create_connection, 294fcebe167SMilanka Ringwald 1000, // scan interval: 625 ms 295fcebe167SMilanka Ringwald 1000, // scan interval: 625 ms 296fcebe167SMilanka Ringwald i, // don't use whitelist 297fcebe167SMilanka Ringwald 0, // peer address type: public 298fcebe167SMilanka Ringwald addr, // remote bd addr 299fcebe167SMilanka Ringwald 0, // random or public 300fcebe167SMilanka Ringwald 80, // conn interval min 301fcebe167SMilanka Ringwald 80, // conn interval max (3200 * 0.625) 302fcebe167SMilanka Ringwald 0, // conn latency 303fcebe167SMilanka Ringwald 2000, // supervision timeout 304fcebe167SMilanka Ringwald 0, // min ce length 305fcebe167SMilanka Ringwald 1000 // max ce length 306fcebe167SMilanka Ringwald ); 307fcebe167SMilanka Ringwald CHECK_EQUAL(0, status); 308fcebe167SMilanka Ringwald } 309fcebe167SMilanka Ringwald } 310fcebe167SMilanka Ringwald 311fcebe167SMilanka Ringwald TEST(HCI, hci_send_cmd_va_arg){ 312fcebe167SMilanka Ringwald hci_reserve_packet_buffer(); 313fcebe167SMilanka Ringwald uint8_t status = hci_send_cmd(&hci_write_loopback_mode, 1); 314fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 315fcebe167SMilanka Ringwald } 316fcebe167SMilanka Ringwald 317fcebe167SMilanka Ringwald TEST(HCI, hci_power_control){ 318fcebe167SMilanka Ringwald int status = hci_power_control(HCI_POWER_ON); 319fcebe167SMilanka Ringwald CHECK_EQUAL(0, status); 320fcebe167SMilanka Ringwald } 321fcebe167SMilanka Ringwald 322d3762d15SMatthias Ringwald TEST(HCI, NumPeripherals){ 323d3762d15SMatthias Ringwald gap_set_max_number_peripheral_connections(1); 324d3762d15SMatthias Ringwald } 325d3762d15SMatthias Ringwald 326d3762d15SMatthias Ringwald TEST(HCI, MaxAclLen){ 327d3762d15SMatthias Ringwald hci_max_acl_data_packet_length(); 328d3762d15SMatthias Ringwald } 329d3762d15SMatthias Ringwald 330d3762d15SMatthias Ringwald TEST(HCI, Flushable){ 331d3762d15SMatthias Ringwald hci_non_flushable_packet_boundary_flag_supported(); 332d3762d15SMatthias Ringwald } 333d3762d15SMatthias Ringwald 334d3762d15SMatthias Ringwald TEST(HCI, RemovePacketHandler){ 335d3762d15SMatthias Ringwald hci_remove_event_handler(NULL); 336d3762d15SMatthias Ringwald } 337d3762d15SMatthias Ringwald 338d3762d15SMatthias Ringwald static void dummy_fn(const void * config){}; 339d3762d15SMatthias Ringwald TEST(HCI, SetChipset){ 340d3762d15SMatthias Ringwald hci_set_chipset(NULL); 341d3762d15SMatthias Ringwald btstack_chipset_t chipset_driver = { 0 }; 342d3762d15SMatthias Ringwald hci_set_chipset(NULL); 343d3762d15SMatthias Ringwald chipset_driver.init = dummy_fn; 344d3762d15SMatthias Ringwald } 345d3762d15SMatthias Ringwald 346d3762d15SMatthias Ringwald TEST(HCI, SetControl){ 347d3762d15SMatthias Ringwald btstack_control_t hardware_control = { .init = &dummy_fn}; 348d3762d15SMatthias Ringwald hci_set_control(&hardware_control); 349d3762d15SMatthias Ringwald } 350d3762d15SMatthias Ringwald 351d3762d15SMatthias Ringwald //TEST(HCI, Close){ 352d3762d15SMatthias Ringwald // hci_close(); 353d3762d15SMatthias Ringwald //} 354d3762d15SMatthias Ringwald 355d3762d15SMatthias Ringwald TEST(HCI, SetPublicAddress){ 356d3762d15SMatthias Ringwald bd_addr_t addr = { 0 }; 357d3762d15SMatthias Ringwald hci_set_bd_addr(addr); 358d3762d15SMatthias Ringwald } 359d3762d15SMatthias Ringwald 360d3762d15SMatthias Ringwald TEST(HCI, DisconnectSecurityBlock){ 361d3762d15SMatthias Ringwald hci_disconnect_security_block(HCI_CON_HANDLE_INVALID); 362d3762d15SMatthias Ringwald hci_disconnect_security_block(3); 363d3762d15SMatthias Ringwald } 364d3762d15SMatthias Ringwald 365d3762d15SMatthias Ringwald TEST(HCI, SetDuplicateFilter){ 366d3762d15SMatthias Ringwald gap_set_scan_duplicate_filter(true); 367d3762d15SMatthias Ringwald } 368d3762d15SMatthias Ringwald 369d3762d15SMatthias Ringwald TEST(HCI, ConnectCancel){ 37028739e5fSMatthias Ringwald uint8_t status; 37128739e5fSMatthias Ringwald status = gap_connect_with_whitelist(); 37228739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 37328739e5fSMatthias Ringwald gap_connect_cancel(); 37428739e5fSMatthias Ringwald 37528739e5fSMatthias Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC; 37628739e5fSMatthias Ringwald bd_addr_t addr = { 0 }; 37728739e5fSMatthias Ringwald gap_connect(addr, addr_type); 378d3762d15SMatthias Ringwald gap_connect_cancel(); 379d3762d15SMatthias Ringwald } 380d3762d15SMatthias Ringwald 381d3762d15SMatthias Ringwald TEST(HCI, SetGapConnParams){ 382d3762d15SMatthias Ringwald gap_set_connection_parameters(0, 0, 0, 0, 0, 0, 0, 0); 383d3762d15SMatthias Ringwald } 384d3762d15SMatthias Ringwald 385d3762d15SMatthias Ringwald TEST(HCI, UpdateConnParams){ 386d3762d15SMatthias Ringwald gap_update_connection_parameters(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0); 387d3762d15SMatthias Ringwald gap_update_connection_parameters(5, 0, 0, 0, 0); 388d3762d15SMatthias Ringwald } 389d3762d15SMatthias Ringwald 390d3762d15SMatthias Ringwald TEST(HCI, RequestConnParamUpdate){ 391d3762d15SMatthias Ringwald gap_request_connection_parameter_update(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0); 392d3762d15SMatthias Ringwald gap_request_connection_parameter_update(5, 0, 0, 0, 0); 393d3762d15SMatthias Ringwald } 394d3762d15SMatthias Ringwald 395d3762d15SMatthias Ringwald TEST(HCI, SetScanResponse){ 396d3762d15SMatthias Ringwald gap_scan_response_set_data(0, NULL); 397d3762d15SMatthias Ringwald } 398d3762d15SMatthias Ringwald 399d3762d15SMatthias Ringwald TEST(HCI, SetAddrType){ 400d3762d15SMatthias Ringwald hci_le_set_own_address_type(0); 401d3762d15SMatthias Ringwald hci_le_set_own_address_type(1); 402d3762d15SMatthias Ringwald } 403d3762d15SMatthias Ringwald 404d3762d15SMatthias Ringwald TEST(HCI, AdvEnable){ 405d3762d15SMatthias Ringwald gap_advertisements_enable(0); 406d3762d15SMatthias Ringwald gap_advertisements_enable(1); 407d3762d15SMatthias Ringwald } 408d3762d15SMatthias Ringwald 409d3762d15SMatthias Ringwald TEST(HCI, SetRandomAddr){ 410d3762d15SMatthias Ringwald bd_addr_t addr = { 0 }; 411d3762d15SMatthias Ringwald hci_le_random_address_set(addr); 412d3762d15SMatthias Ringwald } 413d3762d15SMatthias Ringwald 414d3762d15SMatthias Ringwald TEST(HCI, Disconnect){ 415d3762d15SMatthias Ringwald gap_disconnect(HCI_CON_HANDLE_INVALID); 416d3762d15SMatthias Ringwald gap_disconnect(5); 417d3762d15SMatthias Ringwald } 418d3762d15SMatthias Ringwald 419d3762d15SMatthias Ringwald TEST(HCI, GetRole){ 420d3762d15SMatthias Ringwald gap_get_role(HCI_CON_HANDLE_INVALID); 421d3762d15SMatthias Ringwald gap_get_role(5); 422d3762d15SMatthias Ringwald } 42328739e5fSMatthias Ringwald TEST(HCI, hci_is_le_identity_address_type_other){ 42428739e5fSMatthias Ringwald hci_is_le_identity_address_type(BD_ADDR_TYPE_LE_PUBLIC_IDENTITY); 42528739e5fSMatthias Ringwald hci_is_le_identity_address_type(BD_ADDR_TYPE_LE_RANDOM); 42628739e5fSMatthias Ringwald } 42728739e5fSMatthias Ringwald 42828739e5fSMatthias Ringwald TEST(HCI, hci_can_send_command_packet_now){ 42928739e5fSMatthias Ringwald can_send_now = 0; 43028739e5fSMatthias Ringwald hci_can_send_command_packet_now(); 43128739e5fSMatthias Ringwald can_send_now = 1; 43228739e5fSMatthias Ringwald hci_can_send_command_packet_now(); 43328739e5fSMatthias Ringwald } 43428739e5fSMatthias Ringwald 43528739e5fSMatthias Ringwald TEST(HCI, hci_can_send_prepared_acl_packet_now){ 43628739e5fSMatthias Ringwald can_send_now = 0; 43728739e5fSMatthias Ringwald hci_can_send_prepared_acl_packet_now(0); 43828739e5fSMatthias Ringwald can_send_now = 1; 43928739e5fSMatthias Ringwald hci_can_send_prepared_acl_packet_now(0); 44028739e5fSMatthias Ringwald } 44128739e5fSMatthias Ringwald 44228739e5fSMatthias Ringwald TEST(HCI, hci_can_send_acl_le_packet_now) { 44328739e5fSMatthias Ringwald can_send_now = 0; 44428739e5fSMatthias Ringwald hci_can_send_acl_le_packet_now(); 44528739e5fSMatthias Ringwald can_send_now = 1; 44628739e5fSMatthias Ringwald hci_can_send_acl_le_packet_now(); 44728739e5fSMatthias Ringwald } 448566df4e8SMatthias Ringwald TEST(HCI, hci_number_free_acl_slots_for_connection_type) { 449566df4e8SMatthias Ringwald CHECK_EQUAL(0, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_UNKNOWN)); 450566df4e8SMatthias Ringwald CHECK_EQUAL(255, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_ACL)); 451566df4e8SMatthias Ringwald CHECK_EQUAL(255, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_LE_PUBLIC)); 452566df4e8SMatthias Ringwald // tweak stack 453566df4e8SMatthias Ringwald hci_stack_t * hci_stack = hci_get_stack(); 454566df4e8SMatthias Ringwald hci_stack->le_acl_packets_total_num = 1; 455566df4e8SMatthias Ringwald CHECK_EQUAL(1, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_LE_PUBLIC)); 45628739e5fSMatthias Ringwald } 45728739e5fSMatthias Ringwald 458566df4e8SMatthias Ringwald // TEST(HCI, hci_close) { 459566df4e8SMatthias Ringwald // hci_close(); 460566df4e8SMatthias Ringwald // } 461566df4e8SMatthias Ringwald 46228739e5fSMatthias Ringwald TEST(HCI, gap_connect) { 46328739e5fSMatthias Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC; 46428739e5fSMatthias Ringwald bd_addr_t addr = { 0 }; 46528739e5fSMatthias Ringwald 46628739e5fSMatthias Ringwald uint8_t status; 46728739e5fSMatthias Ringwald status = gap_connect(addr, addr_type); 46828739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 46928739e5fSMatthias Ringwald status = gap_connect(addr, addr_type); 47028739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 47128739e5fSMatthias Ringwald } 47228739e5fSMatthias Ringwald 47328739e5fSMatthias Ringwald TEST(HCI, hci_emit_state) { 47428739e5fSMatthias Ringwald hci_emit_state(); 47528739e5fSMatthias Ringwald } 47628739e5fSMatthias Ringwald 47728739e5fSMatthias Ringwald TEST(HCI, gap_request_connection_subrating) { 47828739e5fSMatthias Ringwald int status = gap_request_connection_subrating(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0, 0); 47928739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 48028739e5fSMatthias Ringwald status = gap_request_connection_subrating(0x01, 0, 0, 0, 0, 0); 48128739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 48228739e5fSMatthias Ringwald } 48328739e5fSMatthias Ringwald 48428739e5fSMatthias Ringwald 48528739e5fSMatthias Ringwald TEST(HCI, hci_set_hardware_error_callback) { 48628739e5fSMatthias Ringwald hci_set_hardware_error_callback(NULL); 48728739e5fSMatthias Ringwald } 48828739e5fSMatthias Ringwald 48928739e5fSMatthias Ringwald TEST(HCI, hci_disconnect_all) { 49028739e5fSMatthias Ringwald hci_disconnect_all(); 49128739e5fSMatthias Ringwald } 49228739e5fSMatthias Ringwald 49328739e5fSMatthias Ringwald TEST(HCI, hci_get_manufacturer) { 49428739e5fSMatthias Ringwald hci_get_manufacturer(); 49528739e5fSMatthias Ringwald } 49628739e5fSMatthias Ringwald TEST(HCI, gap_authorization_state) { 49728739e5fSMatthias Ringwald gap_authorization_state(HCI_CON_HANDLE_INVALID); 49828739e5fSMatthias Ringwald } 49928739e5fSMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION 50028739e5fSMatthias Ringwald TEST(HCI, hci_load_le_device_db_entry_into_resolving_list) { 50128739e5fSMatthias Ringwald hci_load_le_device_db_entry_into_resolving_list(0); 50228739e5fSMatthias Ringwald } 50328739e5fSMatthias Ringwald 50428739e5fSMatthias Ringwald TEST(HCI, hci_remove_le_device_db_entry_from_resolving_list) { 50528739e5fSMatthias Ringwald hci_remove_le_device_db_entry_from_resolving_list(0); 50628739e5fSMatthias Ringwald } 50728739e5fSMatthias Ringwald 50828739e5fSMatthias Ringwald TEST(HCI, gap_load_resolving_list_from_le_device_db) { 50928739e5fSMatthias Ringwald gap_load_resolving_list_from_le_device_db(); 51028739e5fSMatthias Ringwald } 51128739e5fSMatthias Ringwald #endif 51228739e5fSMatthias Ringwald 51328739e5fSMatthias Ringwald TEST(HCI, gap_privacy_client) { 51428739e5fSMatthias Ringwald gap_privacy_client_t client; 51528739e5fSMatthias Ringwald gap_privacy_client_register(&client); 51628739e5fSMatthias Ringwald gap_privacy_client_ready(&client); 51728739e5fSMatthias Ringwald gap_privacy_client_unregister(&client); 51828739e5fSMatthias Ringwald } 519d3762d15SMatthias Ringwald 520566df4e8SMatthias Ringwald TEST(HCI, acl_handling) { 521566df4e8SMatthias Ringwald uint16_t con_handle = 1; 522566df4e8SMatthias Ringwald uint8_t flags = 0; 523566df4e8SMatthias Ringwald 524566df4e8SMatthias Ringwald uint8_t packet[16]; 525566df4e8SMatthias Ringwald // no connection for invalid handle 526566df4e8SMatthias Ringwald memset(packet, 0xff, sizeof(packet)); 527566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 528566df4e8SMatthias Ringwald // invalid length 529566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 530566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 531566df4e8SMatthias Ringwald // fix length 532566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 12); 533566df4e8SMatthias Ringwald little_endian_store_16(packet, 6, 8); 534566df4e8SMatthias Ringwald 535566df4e8SMatthias Ringwald // unexpected acl continuation 536566df4e8SMatthias Ringwald flags = 0x01; 537566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 538566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 539566df4e8SMatthias Ringwald // invalid packet boundary flags 540566df4e8SMatthias Ringwald flags = 0x03; 541566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 542566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 543566df4e8SMatthias Ringwald // oversized first fragment 544566df4e8SMatthias Ringwald flags = 0x02; 545566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 546566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 1996); 547566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, 2000); 548566df4e8SMatthias Ringwald 549566df4e8SMatthias Ringwald // 1a store first flushable fragment 550566df4e8SMatthias Ringwald flags = 0x02; 551566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 552566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 12); 553566df4e8SMatthias Ringwald little_endian_store_16(packet, 4, 20); 554566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 555566df4e8SMatthias Ringwald 556566df4e8SMatthias Ringwald // 1b another first non-flushable 557566df4e8SMatthias Ringwald flags = 0x06; 558566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 559566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 560566df4e8SMatthias Ringwald 561566df4e8SMatthias Ringwald // 1c another first 562566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet)); 563566df4e8SMatthias Ringwald 564566df4e8SMatthias Ringwald // oversized continuation fragment 565566df4e8SMatthias Ringwald flags = 0x01; 566566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12)); 567566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 1996); 568566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, 2000); 569566df4e8SMatthias Ringwald } 570566df4e8SMatthias Ringwald TEST(HCI, gap_le_get_own_address) { 571566df4e8SMatthias Ringwald uint8_t addr_type; 572566df4e8SMatthias Ringwald bd_addr_t addr; 573566df4e8SMatthias Ringwald hci_stack->le_own_addr_type = BD_ADDR_TYPE_LE_PUBLIC; 574566df4e8SMatthias Ringwald gap_le_get_own_address(&addr_type, addr); 575566df4e8SMatthias Ringwald hci_stack->le_own_addr_type = BD_ADDR_TYPE_LE_RANDOM; 576566df4e8SMatthias Ringwald gap_le_get_own_address(&addr_type, addr); 577566df4e8SMatthias Ringwald } 578566df4e8SMatthias Ringwald 579566df4e8SMatthias Ringwald static void simulate_hci_command_complete(uint16_t opcode, uint8_t status) { 580*5308d607SMatthias Ringwald uint8_t packet[2 + 255]; 581566df4e8SMatthias Ringwald packet[0] = HCI_EVENT_COMMAND_COMPLETE; 582566df4e8SMatthias Ringwald packet[1] = sizeof(packet) - 2; 583566df4e8SMatthias Ringwald packet[2] = 1; 584566df4e8SMatthias Ringwald little_endian_store_16(packet, 3, opcode); 585566df4e8SMatthias Ringwald packet[5] = status; 586566df4e8SMatthias Ringwald packet_handler(HCI_EVENT_PACKET, packet, sizeof(packet)); 587566df4e8SMatthias Ringwald } 588566df4e8SMatthias Ringwald 589566df4e8SMatthias Ringwald TEST(HCI, handle_command_complete_event) { 590566df4e8SMatthias Ringwald struct { 591566df4e8SMatthias Ringwald uint16_t opcode; 592566df4e8SMatthias Ringwald uint8_t status; 593566df4e8SMatthias Ringwald } variations[] = { 594566df4e8SMatthias Ringwald {HCI_OPCODE_HCI_READ_LOCAL_NAME, ERROR_CODE_SUCCESS}, 595566df4e8SMatthias Ringwald {HCI_OPCODE_HCI_READ_LOCAL_NAME, ERROR_CODE_UNKNOWN_HCI_COMMAND }, 596566df4e8SMatthias Ringwald {HCI_OPCODE_HCI_READ_BUFFER_SIZE, ERROR_CODE_SUCCESS}, 597566df4e8SMatthias Ringwald {HCI_OPCODE_HCI_READ_RSSI, ERROR_CODE_SUCCESS}, 598566df4e8SMatthias Ringwald {HCI_OPCODE_HCI_READ_RSSI, ERROR_CODE_UNKNOWN_HCI_COMMAND}, 599566df4e8SMatthias Ringwald }; 600566df4e8SMatthias Ringwald for (uint8_t i = 0; i < sizeof(variations) / sizeof(variations[0]); i++) { 601566df4e8SMatthias Ringwald // extras 602566df4e8SMatthias Ringwald uint16_t opcode = variations[i].opcode; 603566df4e8SMatthias Ringwald uint8_t status = variations[i].status; 604566df4e8SMatthias Ringwald switch (opcode) { 605566df4e8SMatthias Ringwald default: 606566df4e8SMatthias Ringwald break; 607566df4e8SMatthias Ringwald } 608566df4e8SMatthias Ringwald simulate_hci_command_complete(opcode, status); 609566df4e8SMatthias Ringwald switch (opcode) { 610566df4e8SMatthias Ringwald default: 611566df4e8SMatthias Ringwald break; 612566df4e8SMatthias Ringwald } 613566df4e8SMatthias Ringwald } 614566df4e8SMatthias Ringwald } 615566df4e8SMatthias Ringwald 616d3762d15SMatthias Ringwald int main (int argc, const char * argv[]){ 617fcebe167SMilanka Ringwald btstack_run_loop_init(btstack_run_loop_posix_get_instance()); 618d3762d15SMatthias Ringwald return CommandLineTestRunner::RunAllTests(argc, argv); 619d3762d15SMatthias Ringwald } 620