diff --git a/example/sco_demo_util.c b/example/sco_demo_util.c index 3d9a19502..31f45ecf2 100644 --- a/example/sco_demo_util.c +++ b/example/sco_demo_util.c @@ -187,6 +187,7 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer, (void) timeInfo; /* Prevent unused variable warnings. */ (void) statusFlags; (void) inputBuffer; + (void) userData; uint32_t bytes_read = 0; int bytes_per_buffer = framesPerBuffer; diff --git a/src/ble/sm.c b/src/ble/sm.c index f0b481693..0aac763f4 100644 --- a/src/ble/sm.c +++ b/src/ble/sm.c @@ -1153,13 +1153,13 @@ static void sm_init_setup(sm_connection_t * sm_conn){ if (IS_RESPONDER(sm_conn->sm_role)){ // slave local_packet = &setup->sm_s_pres; - gap_advertisements_get_address(&setup->sm_s_addr_type, setup->sm_s_address); + gap_le_get_own_address(&setup->sm_s_addr_type, setup->sm_s_address); setup->sm_m_addr_type = sm_conn->sm_peer_addr_type; memcpy(setup->sm_m_address, sm_conn->sm_peer_address, 6); } else { // master local_packet = &setup->sm_m_preq; - gap_advertisements_get_address(&setup->sm_m_addr_type, setup->sm_m_address); + gap_le_get_own_address(&setup->sm_m_addr_type, setup->sm_m_address); setup->sm_s_addr_type = sm_conn->sm_peer_addr_type; memcpy(setup->sm_s_address, sm_conn->sm_peer_address, 6); @@ -2544,7 +2544,7 @@ static void sm_run(void){ bd_addr_t local_address; uint8_t buffer[8]; buffer[0] = SM_CODE_IDENTITY_ADDRESS_INFORMATION; - gap_advertisements_get_address(&buffer[1], local_address); + gap_le_get_own_address(&buffer[1], local_address); reverse_bd_addr(local_address, &buffer[2]); l2cap_send_connectionless(connection->sm_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) buffer, sizeof(buffer)); sm_timeout_reset(connection); @@ -3982,20 +3982,20 @@ static int gap_random_address_type_requires_updates(void){ return 1; } -#ifdef ENABLE_LE_PERIPHERAL static uint8_t own_address_type(void){ - if (gap_random_adress_type == 0) return 0; - return 1; + switch (gap_random_adress_type){ + case GAP_RANDOM_ADDRESS_TYPE_OFF: + return BD_ADDR_TYPE_LE_PUBLIC; + default: + return BD_ADDR_TYPE_LE_RANDOM; + } } -#endif // GAP LE API void gap_random_address_set_mode(gap_random_address_type_t random_address_type){ gap_random_address_update_stop(); gap_random_adress_type = random_address_type; -#ifdef ENABLE_LE_PERIPHERAL - hci_le_advertisements_set_own_address_type(own_address_type()); -#endif + hci_le_set_own_address_type(own_address_type()); if (!gap_random_address_type_requires_updates()) return; gap_random_address_update_start(); gap_random_address_trigger(); @@ -4035,7 +4035,7 @@ void gap_random_address_set(bd_addr_t addr){ */ void gap_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, uint8_t direct_address_typ, bd_addr_t direct_address, uint8_t channel_map, uint8_t filter_policy){ - hci_le_advertisements_set_params(adv_int_min, adv_int_max, adv_type, own_address_type(), + hci_le_advertisements_set_params(adv_int_min, adv_int_max, adv_type, direct_address_typ, direct_address, channel_map, filter_policy); } #endif diff --git a/src/bluetooth.h b/src/bluetooth.h index b1db0e31b..463a45d10 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -68,11 +68,15 @@ typedef uint8_t bd_addr_t[BD_ADDR_LEN]; typedef enum { BD_ADDR_TYPE_LE_PUBLIC = 0, BD_ADDR_TYPE_LE_RANDOM = 1, + BD_ADDR_TYPE_LE_PRIVAT_FALLBACK_PUBLIC = 2, + BD_ADDR_TYPE_LE_PRIVAT_FALLBACK_RANDOM = 3, BD_ADDR_TYPE_SCO = 0xfe, BD_ADDR_TYPE_CLASSIC = 0xff, BD_ADDR_TYPE_UNKNOWN = 0xfe } bd_addr_type_t; + + /** * @brief link key */ diff --git a/src/gap.h b/src/gap.h index c33fd71cd..3c615bb47 100644 --- a/src/gap.h +++ b/src/gap.h @@ -376,9 +376,9 @@ void gap_store_link_key_for_bd_addr(bd_addr_t addr, link_key_t link_key, link_ke // LE /** - * @brief Get addr type and address used in advertisement packets. + * @brief Get own addr type and address used for LE */ -void gap_advertisements_get_address(uint8_t * addr_type, bd_addr_t addr); +void gap_le_get_own_address(uint8_t * addr_type, bd_addr_t addr); /* API_END*/ diff --git a/src/hci.c b/src/hci.c index c9000b049..8dd43ec5f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -855,17 +855,20 @@ static int hci_le_supported(void){ #endif } -// get addr type and address used in advertisement packets -void gap_advertisements_get_address(uint8_t * addr_type, bd_addr_t addr){ - *addr_type = hci_stack->adv_addr_type; - if (hci_stack->adv_addr_type){ - memcpy(addr, hci_stack->adv_address, 6); +#ifdef ENABLE_BLE + +/** + * @brief Get addr type and address used for LE in Advertisements, Scan Responses, + */ +void gap_le_get_own_address(uint8_t * addr_type, bd_addr_t addr){ + *addr_type = hci_stack->le_own_addr_type; + if (hci_stack->le_own_addr_type){ + memcpy(addr, hci_stack->le_random_address, 6); } else { memcpy(addr, hci_stack->local_bd_addr, 6); } } -#ifdef ENABLE_BLE #ifdef ENABLE_LE_CENTRAL void le_handle_advertisement_report(uint8_t *packet, int size){ @@ -1166,15 +1169,17 @@ static void hci_initializing_run(void){ hci_stack->substate = HCI_INIT_W4_WRITE_LE_HOST_SUPPORTED; hci_send_cmd(&hci_write_le_host_supported, 1, 0); break; +#ifdef ENABLE_LE_CENTRAL case HCI_INIT_READ_WHITE_LIST_SIZE: hci_stack->substate = HCI_INIT_W4_READ_WHITE_LIST_SIZE; hci_send_cmd(&hci_le_read_white_list_size); break; case HCI_INIT_LE_SET_SCAN_PARAMETERS: - // LE Scan Parameters: active scanning, 300 ms interval, 30 ms window, public address, accept all advs + // LE Scan Parameters: active scanning, 300 ms interval, 30 ms window, own address type, accept all advs hci_stack->substate = HCI_INIT_W4_LE_SET_SCAN_PARAMETERS; - hci_send_cmd(&hci_le_set_scan_parameters, 1, 0x1e0, 0x30, 0, 0); + hci_send_cmd(&hci_le_set_scan_parameters, 1, 0x1e0, 0x30, hci_stack->le_own_addr_type, 0); break; +#endif #endif default: return; @@ -1411,11 +1416,17 @@ static void hci_initializing_event_handler(uint8_t * packet, uint16_t size){ return; } break; +#ifdef ENABLE_BLE case HCI_INIT_W4_LE_READ_BUFFER_SIZE: // skip write le host if not supported (e.g. on LE only EM9301) if (hci_stack->local_supported_commands[0] & 0x02) break; - hci_stack->substate = HCI_INIT_LE_SET_SCAN_PARAMETERS; +#ifdef ENABLE_LE_CENTRAL + hci_stack->substate = HCI_INIT_READ_WHITE_LIST_SIZE; +#else + hci_init_done(); +#endif return; +#endif case HCI_INIT_W4_WRITE_LOCAL_NAME: // skip write eir data if no eir data set if (hci_stack->eir_data) break; @@ -1527,7 +1538,7 @@ static void event_handler(uint8_t *packet, int size){ } #ifdef ENABLE_LE_CENTRAL if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_le_read_white_list_size)){ - hci_stack->le_whitelist_capacity = little_endian_read_16(packet, 6); + hci_stack->le_whitelist_capacity = packet[6]; log_info("hci_le_read_white_list_size: size %u", hci_stack->le_whitelist_capacity); } #endif @@ -2081,6 +2092,7 @@ static void hci_state_reset(void){ // hci_stack->discoverable = 0; // hci_stack->connectable = 0; // hci_stack->bondable = 1; + // hci_stack->own_addr_type = 0; // buffer is free hci_stack->hci_packet_buffer_reserved = 0; @@ -2090,10 +2102,9 @@ static void hci_state_reset(void){ hci_stack->new_scan_enable_value = 0xff; // LE -#ifdef ENABLE_LE_PERIPHERAL - hci_stack->adv_addr_type = 0; - hci_stack->le_advertisements_random_address_set = 0; - memset(hci_stack->adv_address, 0, 6); +#ifdef ENABLE_BLE + memset(hci_stack->le_random_address, 0, 6); + hci_stack->le_random_address_set = 0; #endif #ifdef ENABLE_LE_CENTRAL hci_stack->le_scanning_state = LE_SCAN_IDLE; @@ -2564,7 +2575,9 @@ static void hci_run(void){ #endif #ifdef ENABLE_BLE - if (hci_stack->state == HCI_STATE_WORKING){ + // advertisements, active scanning, and creating connections requires randaom address to be set if using private address + if ((hci_stack->state == HCI_STATE_WORKING) + && (hci_stack->le_own_addr_type == BD_ADDR_TYPE_LE_PUBLIC || hci_stack->le_random_address_set)){ #ifdef ENABLE_LE_CENTRAL // handle le scan @@ -2585,7 +2598,7 @@ static void hci_run(void){ // defaults: active scanning, accept all advertisement packets int scan_type = hci_stack->le_scan_type; hci_stack->le_scan_type = 0xff; - hci_send_cmd(&hci_le_set_scan_parameters, scan_type, hci_stack->le_scan_interval, hci_stack->le_scan_window, hci_stack->adv_addr_type, 0); + hci_send_cmd(&hci_le_set_scan_parameters, scan_type, hci_stack->le_scan_interval, hci_stack->le_scan_window, hci_stack->le_own_addr_type, 0); return; } #endif @@ -2605,7 +2618,7 @@ static void hci_run(void){ hci_stack->le_advertisements_interval_min, hci_stack->le_advertisements_interval_max, hci_stack->le_advertisements_type, - hci_stack->le_advertisements_own_address_type, + hci_stack->le_own_addr_type, hci_stack->le_advertisements_direct_address_type, hci_stack->le_advertisements_direct_address, hci_stack->le_advertisements_channel_map, @@ -2614,8 +2627,7 @@ static void hci_run(void){ } if (hci_stack->le_advertisements_todo & LE_ADVERTISEMENT_TASKS_SET_ADV_DATA){ hci_stack->le_advertisements_todo &= ~LE_ADVERTISEMENT_TASKS_SET_ADV_DATA; - hci_send_cmd(&hci_le_set_advertising_data, hci_stack->le_advertisements_data_len, - hci_stack->le_advertisements_data); + hci_send_cmd(&hci_le_set_advertising_data, hci_stack->le_advertisements_data_len, hci_stack->le_advertisements_data); return; } if (hci_stack->le_advertisements_todo & LE_ADVERTISEMENT_TASKS_SET_SCAN_DATA){ @@ -2624,9 +2636,7 @@ static void hci_run(void){ hci_stack->le_scan_response_data); return; } - // Random address needs to be set before enabling advertisements - if ((hci_stack->le_advertisements_todo & LE_ADVERTISEMENT_TASKS_ENABLE) - && (hci_stack->le_advertisements_own_address_type == 0 || hci_stack->le_advertisements_random_address_set)){ + if (hci_stack->le_advertisements_todo & LE_ADVERTISEMENT_TASKS_ENABLE){ hci_stack->le_advertisements_todo &= ~LE_ADVERTISEMENT_TASKS_ENABLE; hci_send_cmd(&hci_le_set_advertise_enable, 1); return; @@ -2689,8 +2699,8 @@ static void hci_run(void){ 0x0030, // scan interval: 30 ms 1, // use whitelist 0, // peer address type - null_addr, // peer bd addr - hci_stack->adv_addr_type, // our addr type: + null_addr, // peer bd addr + hci_stack->le_own_addr_type, // our addr type: 0x0008, // conn interval min 0x0018, // conn interval max 0, // conn latency @@ -2727,7 +2737,7 @@ static void hci_run(void){ 0, // don't use whitelist connection->address_type, // peer address type connection->address, // peer bd addr - hci_stack->adv_addr_type, // our addr type: + hci_stack->le_own_addr_type, // our addr type: 0x0008, // conn interval min 0x0018, // conn interval max 0, // conn latency @@ -3069,11 +3079,8 @@ int hci_send_cmd_packet(uint8_t *packet, int size){ #ifdef ENABLE_BLE #ifdef ENABLE_LE_PERIPHERAL if (IS_COMMAND(packet, hci_le_set_random_address)){ - hci_stack->le_advertisements_random_address_set = 1; - reverse_bd_addr(&packet[3], hci_stack->adv_address); - } - if (IS_COMMAND(packet, hci_le_set_advertising_parameters)){ - hci_stack->adv_addr_type = packet[8]; + hci_stack->le_random_address_set = 1; + reverse_bd_addr(&packet[3], hci_stack->le_random_address); } if (IS_COMMAND(packet, hci_le_set_advertise_enable)){ hci_stack->le_advertisements_active = packet[3]; @@ -3659,7 +3666,6 @@ void gap_scan_response_set_data(uint8_t scan_response_data_length, uint8_t * sca * @param adv_int_min * @param adv_int_max * @param adv_type - * @param own_address_type * @param direct_address_type * @param direct_address * @param channel_map @@ -3668,13 +3674,12 @@ void gap_scan_response_set_data(uint8_t scan_response_data_length, uint8_t * sca * @note internal use. use gap_advertisements_set_params from gap_le.h instead. */ void hci_le_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, - uint8_t own_address_type, uint8_t direct_address_typ, bd_addr_t direct_address, + uint8_t direct_address_typ, bd_addr_t direct_address, uint8_t channel_map, uint8_t filter_policy) { hci_stack->le_advertisements_interval_min = adv_int_min; hci_stack->le_advertisements_interval_max = adv_int_max; hci_stack->le_advertisements_type = adv_type; - hci_stack->le_advertisements_own_address_type = own_address_type; hci_stack->le_advertisements_direct_address_type = direct_address_typ; hci_stack->le_advertisements_channel_map = channel_map; hci_stack->le_advertisements_filter_policy = filter_policy; @@ -3684,12 +3689,6 @@ void gap_scan_response_set_data(uint8_t scan_response_data_length, uint8_t * sca gap_advertisments_changed(); } -void hci_le_advertisements_set_own_address_type(uint8_t own_address_type){ - hci_stack->le_advertisements_own_address_type = own_address_type; - hci_stack->le_advertisements_todo |= LE_ADVERTISEMENT_TASKS_SET_PARAMS; - gap_advertisments_changed(); -} - /** * @brief Enable/Disable Advertisements * @param enabled @@ -3706,6 +3705,22 @@ void gap_advertisements_enable(int enabled){ } #endif + +void hci_le_set_own_address_type(uint8_t own_address_type){ + log_info("hci_le_set_own_address_type: old %u, new %u", hci_stack->le_own_addr_type, own_address_type); + if (own_address_type == hci_stack->le_own_addr_type) return; + hci_stack->le_own_addr_type = own_address_type; + +#ifdef ENABLE_LE_PERIPHERAL + // update advertisement parameters, too + hci_stack->le_advertisements_todo |= LE_ADVERTISEMENT_TASKS_SET_PARAMS; + gap_advertisments_changed(); +#endif +#ifdef ENABLE_LE_CENTRAL + // note: we don't update scan parameters or modify ongoing connection attempts +#endif +} + #endif uint8_t gap_disconnect(hci_con_handle_t handle){ diff --git a/src/hci.h b/src/hci.h index e5a6d1e4f..47f5d8eb8 100644 --- a/src/hci.h +++ b/src/hci.h @@ -550,15 +550,20 @@ typedef enum hci_init_state{ HCI_INIT_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING, HCI_INIT_W4_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING, +#ifdef ENABLE_BLE HCI_INIT_LE_READ_BUFFER_SIZE, HCI_INIT_W4_LE_READ_BUFFER_SIZE, HCI_INIT_WRITE_LE_HOST_SUPPORTED, HCI_INIT_W4_WRITE_LE_HOST_SUPPORTED, +#endif + +#ifdef ENABLE_LE_CENTRAL HCI_INIT_READ_WHITE_LIST_SIZE, HCI_INIT_W4_READ_WHITE_LIST_SIZE, HCI_INIT_LE_SET_SCAN_PARAMETERS, HCI_INIT_W4_LE_SET_SCAN_PARAMETERS, +#endif HCI_INIT_DONE, @@ -696,8 +701,11 @@ typedef struct { uint8_t decline_reason; bd_addr_t decline_addr; - uint8_t adv_addr_type; - bd_addr_t adv_address; +#ifdef ENABLE_BLE + uint8_t le_own_addr_type; + bd_addr_t le_random_address; + uint8_t le_random_address_set; +#endif #ifdef ENABLE_LE_CENTRAL le_scanning_state_t le_scanning_state; @@ -709,7 +717,7 @@ typedef struct { uint16_t le_scan_window; // LE Whitelist Management - uint16_t le_whitelist_capacity; + uint8_t le_whitelist_capacity; btstack_linked_list_t le_whitelist; #endif @@ -725,12 +733,10 @@ typedef struct { uint8_t le_advertisements_active; uint8_t le_advertisements_enabled; uint8_t le_advertisements_todo; - uint8_t le_advertisements_random_address_set; uint16_t le_advertisements_interval_min; uint16_t le_advertisements_interval_max; uint8_t le_advertisements_type; - uint8_t le_advertisements_own_address_type; uint8_t le_advertisements_direct_address_type; uint8_t le_advertisements_channel_map; uint8_t le_advertisements_filter_policy; @@ -1011,19 +1017,21 @@ int hci_number_free_acl_slots_for_handle(hci_con_handle_t con_handle); * @param adv_int_min * @param adv_int_max * @param adv_type - * @param own_address_type * @param direct_address_type * @param direct_address * @param channel_map * @param filter_policy * - * @note internal use. use gap_advertisements_set_params from gap_le.h instead. + * @note internal use. use gap_advertisements_set_params from gap.h instead. */ -void hci_le_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, - uint8_t own_address_type, uint8_t direct_address_typ, bd_addr_t direct_address, - uint8_t channel_map, uint8_t filter_policy); +void hci_le_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, + uint8_t direct_address_typ, bd_addr_t direct_address, uint8_t channel_map, uint8_t filter_policy); -void hci_le_advertisements_set_own_address_type(uint8_t own_address_type); +/** + * + * @note internal use. use gap_random_address_set_mode from gap.h instead. + */ +void hci_le_set_own_address_type(uint8_t own_address_type); /** * @brief Get Manufactured diff --git a/test/security_manager/mock.c b/test/security_manager/mock.c index 03084fd06..cb2193742 100644 --- a/test/security_manager/mock.c +++ b/test/security_manager/mock.c @@ -142,22 +142,21 @@ void hci_connections_get_iterator(btstack_linked_list_iterator_t *it){ } // get addr type and address used in advertisement packets -void gap_advertisements_get_address(uint8_t * addr_type, bd_addr_t addr){ +void gap_le_get_own_address(uint8_t * addr_type, bd_addr_t addr){ *addr_type = 0; uint8_t dummy[] = { 0x00, 0x1b, 0xdc, 0x07, 0x32, 0xef }; memcpy(addr, dummy, 6); } void hci_le_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, - uint8_t own_address_type, uint8_t direct_address_typ, bd_addr_t direct_address, - uint8_t channel_map, uint8_t filter_policy) { + uint8_t direct_address_typ, bd_addr_t direct_address, uint8_t channel_map, uint8_t filter_policy) { } uint16_t hci_get_manufacturer(void){ return 0xffff; }; -void hci_le_advertisements_set_own_address_type(uint8_t own_address){ +void hci_le_set_own_address_type(uint8_t own_address){ } extern "C" void l2cap_request_can_send_fix_channel_now_event(hci_con_handle_t con_handle, uint16_t cid){