host privacy config option to enable it

pull/13759/head
Paul Szczeanek 2020-09-24 17:25:53 +01:00 committed by Vincent Coubard
parent 76f89f6f89
commit 03cc0f9940
9 changed files with 192 additions and 133 deletions

View File

@ -455,8 +455,8 @@ struct scanning_filter_policy_t : SafeEnum<scanning_filter_policy_t, uint8_t> {
NO_FILTER = 0x00, NO_FILTER = 0x00,
/** /**
* Accept only advertising packets from devices in the whitelist except * Accept only advertising packets from devices in the whitelist.
* directed advertising packets not addressed to this device. * Directed advertising packets not addressed to this device will be ignored.
*/ */
FILTER_ADVERTISING = 0x01, FILTER_ADVERTISING = 0x01,

View File

@ -93,10 +93,20 @@
"value": 15, "value": 15,
"macro_name": "BLE_GAP_MAX_ADVERTISING_SETS" "macro_name": "BLE_GAP_MAX_ADVERTISING_SETS"
}, },
"ble-gap-host-based-private-address-resolution": {
"help": "Perform address resolution on the host, not the controller. Controller based privacy is preferred as it happens lower down the stack but this can be used in case controller based privacy is unavailable. If this is enabled the controller will not be used for privacy.",
"value": true,
"macro_name": "BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION"
},
"ble-gap-max-advertising-reports-pending-address-resolution": { "ble-gap-max-advertising-reports-pending-address-resolution": {
"help": "How many advertising reports can be pending while awaiting private address resolution. This is only used if host privacy is enabled and controller privacy is disabled. Must be non-zero", "help": "How many advertising reports can be pending while awaiting private address resolution. This is only used if host privacy is enabled and controller privacy is disabled. Must be non-zero",
"value": 16, "value": 16,
"macro_name": "BLE_GAP_MAX_ADVERTISING_REPORTS_PENDING_ADDRESS_RESOLUTION" "macro_name": "BLE_GAP_MAX_ADVERTISING_REPORTS_PENDING_ADDRESS_RESOLUTION"
},
"ble-gap-host-privacy-resolved-cache-size": {
"help": "Used for host privacy. How many last resolved addresses to store to speed up resolution. This is especially valuable for resolving advertising which creates repeated queries for the same address.",
"value": 16,
"macro_name": "BLE_GAP_HOST_PRIVACY_RESOLVED_CACHE_SIZE"
} }
} }
} }

View File

@ -1,7 +1,7 @@
/* mbed Microcontroller Library /* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited * Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
@ -506,4 +506,4 @@ ble::address_t Gap::getRandomStaticAddress()
return impl->getRandomStaticAddress(); return impl->getRandomStaticAddress();
} }
} // namespace ble } // namespace ble

View File

@ -1,7 +1,7 @@
/* mbed Microcontroller Library /* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited * Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
@ -193,6 +193,7 @@ bool PalPrivateAddressController::cordio_handler(const wsfMsgHdr_t *msg)
return true; return true;
} }
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
case DM_PRIV_RESOLVED_ADDR_IND: { case DM_PRIV_RESOLVED_ADDR_IND: {
instance()._resolving_rpa = false; instance()._resolving_rpa = false;
@ -203,6 +204,7 @@ bool PalPrivateAddressController::cordio_handler(const wsfMsgHdr_t *msg)
handler->on_private_address_resolved(msg->status == HCI_SUCCESS); handler->on_private_address_resolved(msg->status == HCI_SUCCESS);
return true; return true;
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
case DM_PRIV_ADD_DEV_TO_RES_LIST_IND: // Device added to resolving list case DM_PRIV_ADD_DEV_TO_RES_LIST_IND: // Device added to resolving list
case DM_PRIV_REM_DEV_FROM_RES_LIST_IND: // Device removed from resolving list case DM_PRIV_REM_DEV_FROM_RES_LIST_IND: // Device removed from resolving list

View File

@ -929,9 +929,11 @@ ble_error_t Gap::enablePrivacy(bool enable)
_address_registry.stop_private_address_generation(); _address_registry.stop_private_address_generation();
} }
#if !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
if (_address_registry.is_controller_privacy_supported()) { if (_address_registry.is_controller_privacy_supported()) {
update_ll_address_resolution_setting(); update_ll_address_resolution_setting();
} }
#endif // !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -946,9 +948,11 @@ ble_error_t Gap::setPeripheralPrivacyConfiguration(
{ {
_peripheral_privacy_configuration = *configuration; _peripheral_privacy_configuration = *configuration;
#if !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
if (_address_registry.is_controller_privacy_supported()) { if (_address_registry.is_controller_privacy_supported()) {
update_ll_address_resolution_setting(); update_ll_address_resolution_setting();
} }
#endif // !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -978,9 +982,11 @@ ble_error_t Gap::setCentralPrivacyConfiguration(
{ {
_central_privacy_configuration = *configuration; _central_privacy_configuration = *configuration;
#if !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
if (_address_registry.is_controller_privacy_supported()) { if (_address_registry.is_controller_privacy_supported()) {
update_ll_address_resolution_setting(); update_ll_address_resolution_setting();
} }
#endif // !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -1474,7 +1480,7 @@ bool Gap::initialize_whitelist() const
return true; return true;
} }
#if BLE_FEATURE_PRIVACY && !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
ble_error_t Gap::update_ll_address_resolution_setting() ble_error_t Gap::update_ll_address_resolution_setting()
{ {
// enable if privacy is enabled and resolution is requested in either central or peripheral mode // enable if privacy is enabled and resolution is requested in either central or peripheral mode
@ -1496,6 +1502,7 @@ ble_error_t Gap::update_ll_address_resolution_setting()
return _address_registry.enable_controller_address_resolution(enable); return _address_registry.enable_controller_address_resolution(enable);
} }
#endif // BLE_FEATURE_PRIVACY && !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
#if BLE_ROLE_BROADCASTER #if BLE_ROLE_BROADCASTER
uint8_t Gap::getMaxAdvertisingSetNumber() uint8_t Gap::getMaxAdvertisingSetNumber()
@ -2314,12 +2321,11 @@ void Gap::signal_connection_complete(
ConnectionCompleteEvent& event ConnectionCompleteEvent& event
) )
{ {
#if BLE_FEATURE_PRIVACY #if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
bool address_resolved = false; bool address_resolved = false;
/* if address resolution is not needed or already handled then the address is already resolved */ /* if address resolution is not needed or already handled then the address is already resolved */
if (!_privacy_enabled || if (!_privacy_enabled ||
_address_registry.is_controller_privacy_supported() ||
event.getPeerAddressType() == peer_address_type_t::PUBLIC || event.getPeerAddressType() == peer_address_type_t::PUBLIC ||
!is_random_private_resolvable_address(event.getPeerAddress())) { !is_random_private_resolvable_address(event.getPeerAddress())) {
address_resolved = true; address_resolved = true;
@ -2330,7 +2336,7 @@ void Gap::signal_connection_complete(
address_resolved = true; address_resolved = true;
} }
} }
#endif #endif // BLE_ROLE_CENTRAL
#if BLE_ROLE_PERIPHERAL #if BLE_ROLE_PERIPHERAL
if (event.getOwnRole() == connection_role_t::PERIPHERAL) { if (event.getOwnRole() == connection_role_t::PERIPHERAL) {
@ -2347,7 +2353,7 @@ void Gap::signal_connection_complete(
/* first try to resolve synchronously in cache */ /* first try to resolve synchronously in cache */
if (!address_resolved) { if (!address_resolved) {
address_resolved = _address_registry.resolve_address_in_cache( address_resolved = _address_registry.resolve_address_in_host_cache(
event.getPeerAddress(), event.getPeerAddress(),
&peer_address_type, &peer_address_type,
&peer_address &peer_address
@ -2372,7 +2378,7 @@ void Gap::signal_connection_complete(
_event_handler->onConnectionComplete(event); _event_handler->onConnectionComplete(event);
} else { } else {
bool resolution_pending = false; bool resolution_pending = false;
ble_error_t ret = _address_registry.queue_resolve_address(event.getPeerAddress()); ble_error_t ret = _address_registry.queue_resolve_address_on_host(event.getPeerAddress());
if (ret == BLE_ERROR_NONE) { if (ret == BLE_ERROR_NONE) {
ConnectionCompleteEvent* event_copy = new(std::nothrow) ConnectionCompleteEvent(event); ConnectionCompleteEvent* event_copy = new(std::nothrow) ConnectionCompleteEvent(event);
@ -2397,11 +2403,10 @@ void Gap::signal_connection_complete(
#else #else
report_internal_connection_complete(event); report_internal_connection_complete(event);
_event_handler->onConnectionComplete(event); _event_handler->onConnectionComplete(event);
#endif // BLE_FEATURE_PRIVACY #endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
} }
#if BLE_FEATURE_PRIVACY #if BLE_FEATURE_PRIVACY
bool Gap::apply_peripheral_privacy_connection_policy( bool Gap::apply_peripheral_privacy_connection_policy(
const ConnectionCompleteEvent &event const ConnectionCompleteEvent &event
) )
@ -2451,8 +2456,9 @@ bool Gap::apply_peripheral_privacy_connection_policy(
return true; return true;
#endif #endif
} }
#endif // BLE_FEATURE_PRIVACY
#if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
void Gap::conclude_signal_connection_complete_after_address_resolution( void Gap::conclude_signal_connection_complete_after_address_resolution(
ConnectionCompleteEvent &event, ConnectionCompleteEvent &event,
target_peer_address_type_t identity_address_type, target_peer_address_type_t identity_address_type,
@ -2478,7 +2484,7 @@ void Gap::conclude_signal_connection_complete_after_address_resolution(
report_internal_connection_complete(event); report_internal_connection_complete(event);
_event_handler->onConnectionComplete(event); _event_handler->onConnectionComplete(event);
} }
#endif // BLE_FEATURE_PRIVACY #endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
#endif // BLE_FEATURE_CONNECTABLE #endif // BLE_FEATURE_CONNECTABLE
#if BLE_ROLE_OBSERVER #if BLE_ROLE_OBSERVER
@ -2486,13 +2492,12 @@ void Gap::signal_advertising_report(
AdvertisingReportEvent& event AdvertisingReportEvent& event
) )
{ {
#if BLE_FEATURE_PRIVACY #if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
bool address_resolved = false; bool address_resolved = false;
/* if address resolution is not needed or already handled then the address is already resolved */ /* if address resolution is not needed or already handled then the address is already resolved */
if (!_privacy_enabled || if (!_privacy_enabled ||
_central_privacy_configuration.resolution_strategy == central_privacy_configuration_t::DO_NOT_RESOLVE || _central_privacy_configuration.resolution_strategy == central_privacy_configuration_t::DO_NOT_RESOLVE ||
_address_registry.is_controller_privacy_supported() ||
event.getPeerAddressType() == peer_address_type_t::PUBLIC || event.getPeerAddressType() == peer_address_type_t::PUBLIC ||
!is_random_private_resolvable_address(event.getPeerAddress())) { !is_random_private_resolvable_address(event.getPeerAddress())) {
address_resolved = true; address_resolved = true;
@ -2503,7 +2508,7 @@ void Gap::signal_advertising_report(
const address_t *peer_address = nullptr; const address_t *peer_address = nullptr;
target_peer_address_type_t peer_address_type(target_peer_address_type_t::RANDOM); target_peer_address_type_t peer_address_type(target_peer_address_type_t::RANDOM);
address_resolved = _address_registry.resolve_address_in_cache( address_resolved = _address_registry.resolve_address_in_host_cache(
event.getPeerAddress(), event.getPeerAddress(),
&peer_address_type, &peer_address_type,
&peer_address &peer_address
@ -2536,7 +2541,7 @@ void Gap::signal_advertising_report(
/* if there is already an item with the same address pending don't kick off resolution*/ /* if there is already an item with the same address pending don't kick off resolution*/
if (!duplicate_pending_event) { if (!duplicate_pending_event) {
ret = _address_registry.queue_resolve_address(event.getPeerAddress()); ret = _address_registry.queue_resolve_address_on_host(event.getPeerAddress());
} }
if (ret == BLE_ERROR_NONE) { if (ret == BLE_ERROR_NONE) {
@ -2553,11 +2558,11 @@ void Gap::signal_advertising_report(
_event_handler->onAdvertisingReport( _event_handler->onAdvertisingReport(
event event
); );
#endif // BLE_FEATURE_PRIVACY #endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
} }
#endif //BLE_ROLE_OBSERVER #endif //BLE_ROLE_OBSERVER
#if BLE_FEATURE_PRIVACY #if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
#if BLE_ROLE_OBSERVER #if BLE_ROLE_OBSERVER
void Gap::conclude_signal_advertising_report_after_address_resolution( void Gap::conclude_signal_advertising_report_after_address_resolution(
AdvertisingReportEvent &event, AdvertisingReportEvent &event,
@ -2581,7 +2586,7 @@ void Gap::conclude_signal_advertising_report_after_address_resolution(
_event_handler->onAdvertisingReport(event); _event_handler->onAdvertisingReport(event);
} }
#endif // BLE_ROLE_OBSERVER #endif // BLE_ROLE_OBSERVER
#endif // BLE_FEATURE_PRIVACY #endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
void Gap::on_periodic_advertising_sync_established( void Gap::on_periodic_advertising_sync_established(
hci_error_code_t error, hci_error_code_t error,
@ -3179,7 +3184,8 @@ void Gap::on_private_address_generated(bool connectable)
} }
} }
#if BLE_FEATURE_PRIVACY
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
void Gap::on_address_resolution_completed( void Gap::on_address_resolution_completed(
const address_t &peer_resolvable_address, const address_t &peer_resolvable_address,
bool resolved, bool resolved,
@ -3187,7 +3193,6 @@ void Gap::on_address_resolution_completed(
const address_t &identity_address const address_t &identity_address
) )
{ {
#if BLE_FEATURE_PRIVACY
if (!_event_handler || !_privacy_enabled) { if (!_event_handler || !_privacy_enabled) {
return; return;
} }
@ -3237,9 +3242,9 @@ void Gap::on_address_resolution_completed(
delete event; delete event;
} }
#endif // BLE_ROLE_OBSERVER #endif // BLE_ROLE_OBSERVER
#endif // BLE_FEATURE_PRIVACY
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
#endif // BLE_FEATURE_PRIVACY
bool Gap::is_advertising() const bool Gap::is_advertising() const
{ {
@ -3297,7 +3302,7 @@ const address_t *Gap::get_random_address(controller_operation_t operation, size_
#if BLE_FEATURE_EXTENDED_ADVERTISING #if BLE_FEATURE_EXTENDED_ADVERTISING
if (is_extended_advertising_available()) { if (is_extended_advertising_available()) {
if (operation == controller_operation_t::advertising) { if (operation == controller_operation_t::advertising) {
if (_set_is_connectable.get(set_id) == false && peripheral_non_resolvable) { if (!_set_is_connectable.get(set_id) && peripheral_non_resolvable) {
return &non_resolvable_address; return &non_resolvable_address;
} else { } else {
return &resolvable_address; return &resolvable_address;

View File

@ -493,6 +493,7 @@ private:
IndexType _current_index = 0; IndexType _current_index = 0;
}; };
#if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
class PendingAdvertisingReportEvent { class PendingAdvertisingReportEvent {
public: public:
PendingAdvertisingReportEvent( PendingAdvertisingReportEvent(
@ -530,6 +531,7 @@ private:
AdvertisingReportEvent event; AdvertisingReportEvent event;
uint8_t *advertising_data_buffer = nullptr; uint8_t *advertising_data_buffer = nullptr;
}; };
#endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
private: private:
/* Disallow copy and assignment. */ /* Disallow copy and assignment. */
@ -585,7 +587,9 @@ private:
bool initialize_whitelist() const; bool initialize_whitelist() const;
#if BLE_FEATURE_PRIVACY && !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
ble_error_t update_ll_address_resolution_setting(); ble_error_t update_ll_address_resolution_setting();
#endif // BLE_FEATURE_PRIVACY && !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
ble_error_t setExtendedAdvertisingParameters( ble_error_t setExtendedAdvertisingParameters(
advertising_handle_t handle, advertising_handle_t handle,
@ -620,7 +624,9 @@ private:
bool apply_peripheral_privacy_connection_policy( bool apply_peripheral_privacy_connection_policy(
const ConnectionCompleteEvent &event const ConnectionCompleteEvent &event
); );
#endif // BLE_FEATURE_PRIVACY
#if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
/** Pass the connection complete event to the application after privacy resolution completed. /** Pass the connection complete event to the application after privacy resolution completed.
* *
* @param event Event to be passed to the user application. * @param event Event to be passed to the user application.
@ -632,7 +638,7 @@ private:
target_peer_address_type_t identity_address_type, target_peer_address_type_t identity_address_type,
const address_t *identity_address const address_t *identity_address
); );
#endif // BLE_FEATURE_PRIVACY #endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
#endif // BLE_FEATURE_CONNECTABLE #endif // BLE_FEATURE_CONNECTABLE
#if BLE_ROLE_OBSERVER #if BLE_ROLE_OBSERVER
@ -642,7 +648,7 @@ private:
*/ */
void signal_advertising_report(AdvertisingReportEvent& report); void signal_advertising_report(AdvertisingReportEvent& report);
#if BLE_FEATURE_PRIVACY #if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
/** Pass the advertising report to the application after privacy resolution completed. /** Pass the advertising report to the application after privacy resolution completed.
* *
* @param event Event to be passed to the user application. * @param event Event to be passed to the user application.
@ -654,7 +660,7 @@ private:
target_peer_address_type_t identity_address_type, target_peer_address_type_t identity_address_type,
const address_t *identity_address const address_t *identity_address
); );
#endif // BLE_FEATURE_PRIVACY #endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
#endif // BLE_ROLE_OBSERVER #endif // BLE_ROLE_OBSERVER
/* implements PalGap::EventHandler */ /* implements PalGap::EventHandler */
@ -767,13 +773,14 @@ private:
void on_non_resolvable_private_addresses_generated(const address_t &address) final; void on_non_resolvable_private_addresses_generated(const address_t &address) final;
void on_private_address_generated(bool connectable); void on_private_address_generated(bool connectable);
#if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
void on_address_resolution_completed( void on_address_resolution_completed(
const address_t &peer_resolvable_address, const address_t &peer_resolvable_address,
bool resolved, bool resolved,
target_peer_address_type_t identity_address_type, target_peer_address_type_t identity_address_type,
const address_t &identity_address const address_t &identity_address
) final; ) final;
#endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
private: private:
bool is_advertising() const; bool is_advertising() const;
@ -803,14 +810,14 @@ private:
*/ */
ble::Gap::EventHandler *_event_handler; ble::Gap::EventHandler *_event_handler;
#if BLE_FEATURE_PRIVACY #if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
#if BLE_ROLE_OBSERVER #if BLE_ROLE_OBSERVER
EventList<PendingAdvertisingReportEvent, uint8_t, BLE_GAP_MAX_ADVERTISING_REPORTS_PENDING_ADDRESS_RESOLUTION> _reports_pending_address_resolution; EventList<PendingAdvertisingReportEvent, uint8_t, BLE_GAP_MAX_ADVERTISING_REPORTS_PENDING_ADDRESS_RESOLUTION> _reports_pending_address_resolution;
#endif // BLE_ROLE_OBSERVER #endif // BLE_ROLE_OBSERVER
#if BLE_FEATURE_CONNECTABLE #if BLE_FEATURE_CONNECTABLE
EventList<ConnectionCompleteEvent, uint8_t, DM_CONN_MAX> _connections_pending_address_resolution; EventList<ConnectionCompleteEvent, uint8_t, DM_CONN_MAX> _connections_pending_address_resolution;
#endif // BLE_FEATURE_CONNECTABLE #endif // BLE_FEATURE_CONNECTABLE
#endif // BLE_FEATURE_PRIVACY #endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
PalEventQueue &_event_queue; PalEventQueue &_event_queue;
PalGap &_pal_gap; PalGap &_pal_gap;

View File

@ -31,11 +31,13 @@ PrivateAddressController::PrivateAddressController(
_pal.initialize(); _pal.initialize();
_pal.set_event_handler(this); _pal.set_event_handler(this);
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
auto** next = &_free_resolution_entries; auto** next = &_free_resolution_entries;
for (auto &entry : _resolution_list) { for (auto &entry : _resolution_list) {
*next = &entry; *next = &entry;
next = &entry.next; next = &entry.next;
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
} }
PrivateAddressController::~PrivateAddressController() PrivateAddressController::~PrivateAddressController()
@ -132,19 +134,25 @@ bool PrivateAddressController::is_controller_privacy_supported()
return _pal.is_ll_privacy_supported(); return _pal.is_ll_privacy_supported();
} }
#if !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
ble_error_t PrivateAddressController::enable_controller_address_resolution(bool enable) ble_error_t PrivateAddressController::enable_controller_address_resolution(bool enable)
{ {
MBED_ASSERT(is_controller_privacy_supported()); MBED_ASSERT(is_controller_privacy_supported());
return _pal.set_ll_address_resolution(enable); return _pal.set_ll_address_resolution(enable);
} }
#endif // !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
uint8_t PrivateAddressController::read_resolving_list_capacity() uint8_t PrivateAddressController::read_resolving_list_capacity()
{ {
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
return BLE_SECURITY_DATABASE_MAX_ENTRIES;
#else
if (is_controller_privacy_supported()) { if (is_controller_privacy_supported()) {
return _pal.read_resolving_list_capacity(); return _pal.read_resolving_list_capacity();
} else { } else {
return RESOLVING_LIST_SIZE; return 0;
} }
#endif //BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
} }
ble_error_t PrivateAddressController::add_device_to_resolving_list( ble_error_t PrivateAddressController::add_device_to_resolving_list(
@ -157,6 +165,47 @@ ble_error_t PrivateAddressController::add_device_to_resolving_list(
return BLE_ERROR_INVALID_STATE; return BLE_ERROR_INVALID_STATE;
} }
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
// ensure an entry is not added twice
for (auto &entry : _resolving_list) {
if (entry.populated &&
entry.peer_address_type == peer_address_type &&
entry.peer_address == peer_identity_address &&
entry.peer_irk == peer_irk
) {
return BLE_ERROR_NONE;
}
}
bool entry_added = false;
for (auto &entry : _resolving_list) {
if (entry.populated == false) {
entry.peer_address_type = peer_address_type;
entry.peer_address = peer_identity_address;
entry.peer_irk = peer_irk;
entry.populated = true;
entry_added = true;
break;
}
}
if (!entry_added) {
return BLE_ERROR_NO_MEM;
}
// Remove unresolved entries from the resolved list
remove_resolution_entry_from_cache(
[&](resolution_entry_t &entry) {
return entry.identity == nullptr;
}
);
// reset pending resolution request
restart_resolution_process_on_host();
return BLE_ERROR_NO_MEM;
#else
if (is_controller_privacy_supported()) { if (is_controller_privacy_supported()) {
return queue_add_device_to_resolving_list( return queue_add_device_to_resolving_list(
peer_address_type, peer_address_type,
@ -164,46 +213,9 @@ ble_error_t PrivateAddressController::add_device_to_resolving_list(
peer_irk peer_irk
); );
} else { } else {
// ensure an entry is not added twice return BLE_ERROR_NOT_IMPLEMENTED;
for (auto &entry : _resolving_list) {
if (entry.populated &&
entry.peer_address_type == peer_address_type &&
entry.peer_address == peer_identity_address &&
entry.peer_irk == peer_irk
) {
return BLE_ERROR_NONE;
}
}
bool entry_added = false;
for (auto &entry : _resolving_list) {
if (entry.populated == false) {
entry.peer_address_type = peer_address_type;
entry.peer_address = peer_identity_address;
entry.peer_irk = peer_irk;
entry.populated = true;
entry_added = true;
break;
}
}
if (!entry_added) {
return BLE_ERROR_NO_MEM;
}
// Remove unresolved entries from the resolved list
remove_resolution_entry_from_cache(
[&](resolution_entry_t &entry) {
return entry.identity == nullptr;
}
);
// reset pending resolution request
restart_resolution_process();
return BLE_ERROR_NO_MEM;
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
} }
ble_error_t PrivateAddressController::remove_device_from_resolving_list( ble_error_t PrivateAddressController::remove_device_from_resolving_list(
@ -211,48 +223,58 @@ ble_error_t PrivateAddressController::remove_device_from_resolving_list(
const address_t &peer_identity_address const address_t &peer_identity_address
) )
{ {
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
for (auto &entry : _resolving_list) {
if (entry.populated &&
entry.peer_address_type == peer_address_type &&
entry.peer_address == peer_identity_address
) {
remove_resolution_entry_from_cache([&](resolution_entry_t& cache_entry) {
return cache_entry.identity == &entry;
});
entry.populated = false;
restart_resolution_process_on_host();
}
}
return BLE_ERROR_NONE;
#else
if (is_controller_privacy_supported()) { if (is_controller_privacy_supported()) {
return queue_remove_device_from_resolving_list(peer_address_type, peer_identity_address); return queue_remove_device_from_resolving_list(peer_address_type, peer_identity_address);
} else { } else {
for (auto &entry : _resolving_list) { return BLE_ERROR_NOT_IMPLEMENTED;
if (entry.populated &&
entry.peer_address_type == peer_address_type &&
entry.peer_address == peer_identity_address
) {
remove_resolution_entry_from_cache([&](resolution_entry_t& cache_entry) {
return cache_entry.identity == &entry;
});
entry.populated = false;
restart_resolution_process();
}
}
return BLE_ERROR_NONE;
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
} }
ble_error_t PrivateAddressController::clear_resolving_list() ble_error_t PrivateAddressController::clear_resolving_list()
{ {
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
// Remove entry from the resolving list
for (auto &entry : _resolving_list) {
entry.populated = false;
}
// Remove all resolved entries from the cache
remove_resolution_entry_from_cache([&](resolution_entry_t& entry) {
return entry.identity != nullptr;
});
restart_resolution_process_on_host();
return BLE_ERROR_NONE;
#else
if (is_controller_privacy_supported()) { if (is_controller_privacy_supported()) {
return queue_clear_resolving_list(); return queue_clear_resolving_list();
} else { } else {
// Remove entry from the resolving list return BLE_ERROR_NOT_IMPLEMENTED;
for (auto &entry : _resolving_list) {
entry.populated = false;
}
// Remove all resolved entries from the cache
remove_resolution_entry_from_cache([&](resolution_entry_t& entry) {
return entry.identity != nullptr;
});
restart_resolution_process();
return BLE_ERROR_NONE;
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
} }
bool PrivateAddressController::resolve_address_in_cache( #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
bool PrivateAddressController::resolve_address_in_host_cache(
const address_t &peer_address, const address_t &peer_address,
target_peer_address_type_t *retrieved_address_type, target_peer_address_type_t *retrieved_address_type,
const address_t **retrieved_address const address_t **retrieved_address
@ -287,27 +309,24 @@ bool PrivateAddressController::resolve_address_in_cache(
return false; return false;
} }
ble_error_t PrivateAddressController::resolve_address( ble_error_t PrivateAddressController::resolve_address_on_host(
const address_t &peer_address, const address_t &peer_address,
bool *resolution_complete, bool *resolution_complete,
target_peer_address_type_t *retrieved_address_type, target_peer_address_type_t *retrieved_address_type,
const address_t **retrieved_address const address_t **retrieved_address
) )
{ {
if (is_controller_privacy_supported()) { *resolution_complete = resolve_address_in_host_cache(peer_address, retrieved_address_type, retrieved_address);
return BLE_ERROR_NOT_IMPLEMENTED;
}
*resolution_complete = resolve_address_in_cache(peer_address, retrieved_address_type, retrieved_address);
// In the case the address has not been resolved, we start the resolution // In the case the address has not been resolved, we start the resolution
// process. // process.
if (*resolution_complete) { if (*resolution_complete) {
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} else { } else {
return queue_resolve_address(peer_address); return queue_resolve_address_on_host(peer_address);
} }
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
void PrivateAddressController::on_resolving_list_action_complete() void PrivateAddressController::on_resolving_list_action_complete()
{ {
@ -338,6 +357,7 @@ private:
PrivacyControlBlock *_next; PrivacyControlBlock *_next;
}; };
#if !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
struct PrivateAddressController::PrivacyAddDevToResListControlBlock final : struct PrivateAddressController::PrivacyAddDevToResListControlBlock final :
PrivateAddressController::PrivacyControlBlock { PrivateAddressController::PrivacyControlBlock {
PrivacyAddDevToResListControlBlock( PrivacyAddDevToResListControlBlock(
@ -462,10 +482,12 @@ ble_error_t PrivateAddressController::queue_clear_resolving_list()
queue_privacy_control_block(cb); queue_privacy_control_block(cb);
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
#endif // !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
struct PrivateAddressController::PrivacyResolveAddress final : #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
struct PrivateAddressController::PrivacyResolveAddressOnHost final :
PrivateAddressController::PrivacyControlBlock { PrivateAddressController::PrivacyControlBlock {
PrivacyResolveAddress(const address_t &peer_address) : PrivacyResolveAddressOnHost(const address_t &peer_address) :
PrivacyControlBlock(), PrivacyControlBlock(),
peer_address(peer_address) peer_address(peer_address)
{ {
@ -508,7 +530,7 @@ private:
bool start_next_resolution_round(PrivateAddressController& self) { bool start_next_resolution_round(PrivateAddressController& self) {
do { do {
++resolving_list_index; ++resolving_list_index;
if (resolving_list_index == RESOLVING_LIST_SIZE) { if (resolving_list_index == BLE_SECURITY_DATABASE_MAX_ENTRIES) {
notify_completion(self, peer_address,false,nullptr); notify_completion(self, peer_address,false,nullptr);
return true; return true;
} }
@ -551,9 +573,9 @@ private:
bool require_restart = false; bool require_restart = false;
}; };
ble_error_t PrivateAddressController::queue_resolve_address(const address_t &peer_address) ble_error_t PrivateAddressController::queue_resolve_address_on_host(const address_t &peer_address)
{ {
auto *cb = new(std::nothrow) PrivacyResolveAddress(peer_address); auto *cb = new(std::nothrow) PrivacyResolveAddressOnHost(peer_address);
if (cb == nullptr) { if (cb == nullptr) {
// Cannot go further // Cannot go further
return BLE_ERROR_NO_MEM; return BLE_ERROR_NO_MEM;
@ -566,27 +588,27 @@ ble_error_t PrivateAddressController::queue_resolve_address(const address_t &pee
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
void PrivateAddressController::restart_resolution_process() void PrivateAddressController::restart_resolution_process_on_host()
{ {
// if processing is active, restart the one running. // if processing is active, restart the one running.
if (_processing_privacy_control_block && _pending_privacy_control_blocks) { if (_processing_privacy_control_block && _pending_privacy_control_blocks) {
static_cast<PrivacyResolveAddress*>(_pending_privacy_control_blocks)->invalidate(); static_cast<PrivacyResolveAddressOnHost*>(_pending_privacy_control_blocks)->invalidate();
} }
} }
void PrivateAddressController::on_private_address_resolved(bool success) void PrivateAddressController::on_private_address_resolved(bool success)
{ {
MBED_ASSERT(is_controller_privacy_supported() == false);
if (_pending_privacy_control_blocks == nullptr || if (_pending_privacy_control_blocks == nullptr ||
_processing_privacy_control_block == false _processing_privacy_control_block == false
) { ) {
return; return;
} }
auto* cb = static_cast<PrivacyResolveAddress*>(_pending_privacy_control_blocks); auto* cb = static_cast<PrivacyResolveAddressOnHost*>(_pending_privacy_control_blocks);
bool completed = cb->on_resolution_complete(*this, success); bool completed = cb->on_resolution_complete(*this, success);
process_privacy_control_blocks(completed); process_privacy_control_blocks(completed);
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
void PrivateAddressController::clear_privacy_control_blocks() void PrivateAddressController::clear_privacy_control_blocks()
{ {
@ -649,6 +671,8 @@ void PrivateAddressController::process_privacy_control_blocks(bool cb_completed)
_pending_privacy_control_blocks = cb; _pending_privacy_control_blocks = cb;
} }
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
template<typename Pred> template<typename Pred>
void PrivateAddressController::remove_resolution_entry_from_cache(const Pred &predicate) void PrivateAddressController::remove_resolution_entry_from_cache(const Pred &predicate)
{ {
@ -701,4 +725,6 @@ void PrivateAddressController::add_resolution_entry_to_cache(
_resolved_list = entry; _resolved_list = entry;
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
} // namespace ble } // namespace ble

View File

@ -52,7 +52,7 @@ public:
virtual void on_non_resolvable_private_addresses_generated( virtual void on_non_resolvable_private_addresses_generated(
const address_t &address const address_t &address
) = 0; ) = 0;
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
/** /**
* Called when address resolution has been completed by the host. * Called when address resolution has been completed by the host.
* *
@ -73,6 +73,7 @@ public:
target_peer_address_type_t identity_address_type, target_peer_address_type_t identity_address_type,
const address_t &identity_address const address_t &identity_address
) = 0; ) = 0;
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
}; };
/** /**
@ -139,10 +140,12 @@ public:
*/ */
bool is_controller_privacy_supported(); bool is_controller_privacy_supported();
#if !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
/** /**
* Enable address resolution by the controller. * Enable address resolution by the controller.
*/ */
ble_error_t enable_controller_address_resolution(bool enable); ble_error_t enable_controller_address_resolution(bool enable);
#endif //!BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
/** /**
* Read the number of entry that can be put in the resolving list. * Read the number of entry that can be put in the resolving list.
@ -178,6 +181,7 @@ public:
*/ */
ble_error_t clear_resolving_list(); ble_error_t clear_resolving_list();
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
/** /**
* Resolve a private resolvable address on the host. * Resolve a private resolvable address on the host.
* *
@ -196,13 +200,12 @@ public:
* input this will be set to null if the address has not been resolved with * input this will be set to null if the address has not been resolved with
* the local irks or a pointer to the identity address if it has been resolved. * the local irks or a pointer to the identity address if it has been resolved.
*/ */
ble_error_t resolve_address( ble_error_t resolve_address_on_host(
const address_t &peer_address, const address_t &peer_address,
bool *resolution_complete, bool *resolution_complete,
target_peer_address_type_t *retrieved_address_type, target_peer_address_type_t *retrieved_address_type,
const address_t **retrieved_address const address_t **retrieved_address
); );
/** /**
* Resolve a private address by looking in the cache. * Resolve a private address by looking in the cache.
* *
@ -215,7 +218,7 @@ public:
* *
* @return True if the address has been found in cache. * @return True if the address has been found in cache.
*/ */
bool resolve_address_in_cache( bool resolve_address_in_host_cache(
const address_t &peer_address, const address_t &peer_address,
target_peer_address_type_t *retrieved_address_type, target_peer_address_type_t *retrieved_address_type,
const address_t **retrieved_address const address_t **retrieved_address
@ -227,7 +230,8 @@ public:
* *
* @param peer_address the address to resolve. * @param peer_address the address to resolve.
*/ */
ble_error_t queue_resolve_address(const address_t &peer_address); ble_error_t queue_resolve_address_on_host(const address_t &peer_address);
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
private: private:
@ -238,7 +242,9 @@ private:
// EventHandler implementation // EventHandler implementation
void on_resolvable_private_address_generated(const address_t &rpa) final; void on_resolvable_private_address_generated(const address_t &rpa) final;
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
void on_private_address_resolved(bool success) final; void on_private_address_resolved(bool success) final;
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
void on_resolving_list_action_complete() final; void on_resolving_list_action_complete() final;
@ -269,9 +275,11 @@ private:
// Queue control block to clear resolving list // Queue control block to clear resolving list
ble_error_t queue_clear_resolving_list(); ble_error_t queue_clear_resolving_list();
struct PrivacyResolveAddress; #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
struct PrivacyResolveAddressOnHost;
void restart_resolution_process(); void restart_resolution_process_on_host();
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
// Clear all control blocks // Clear all control blocks
void clear_privacy_control_blocks(); void clear_privacy_control_blocks();
@ -283,12 +291,14 @@ private:
// cb_completed is set when the previous block has completed // cb_completed is set when the previous block has completed
void process_privacy_control_blocks(bool cb_completed); void process_privacy_control_blocks(bool cb_completed);
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
struct resolving_list_entry_t;
template<typename Pred> template<typename Pred>
void remove_resolution_entry_from_cache(const Pred& predicate); void remove_resolution_entry_from_cache(const Pred& predicate);
struct resolving_list_entry_t;
void add_resolution_entry_to_cache(const address_t& address, resolving_list_entry_t* identity); void add_resolution_entry_to_cache(const address_t& address, resolving_list_entry_t* identity);
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
PalPrivateAddressController &_pal; PalPrivateAddressController &_pal;
PalEventQueue &_event_queue; PalEventQueue &_event_queue;
@ -303,6 +313,7 @@ private:
PrivacyControlBlock *_pending_privacy_control_blocks = nullptr; PrivacyControlBlock *_pending_privacy_control_blocks = nullptr;
bool _processing_privacy_control_block = false; bool _processing_privacy_control_block = false;
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
struct resolving_list_entry_t { struct resolving_list_entry_t {
address_t peer_address = {}; address_t peer_address = {};
irk_t peer_irk = {}; irk_t peer_irk = {};
@ -310,10 +321,7 @@ private:
bool populated = false; bool populated = false;
}; };
// FIXME: Use configuration resolving_list_entry_t _resolving_list[BLE_SECURITY_DATABASE_MAX_ENTRIES];
static const size_t RESOLVING_LIST_SIZE = 8;
resolving_list_entry_t _resolving_list[RESOLVING_LIST_SIZE];
struct resolution_entry_t { struct resolution_entry_t {
address_t address = address_t {}; address_t address = address_t {};
@ -321,11 +329,10 @@ private:
resolving_list_entry_t *identity = nullptr; resolving_list_entry_t *identity = nullptr;
}; };
// FIXME: Use configuration resolution_entry_t _resolution_list[BLE_GAP_HOST_PRIVACY_RESOLVED_CACHE_SIZE];
static const size_t RESOLVED_ADDRESS_CACHE_SIZE = 16;
resolution_entry_t _resolution_list[RESOLVED_ADDRESS_CACHE_SIZE];
resolution_entry_t *_resolved_list = nullptr; resolution_entry_t *_resolved_list = nullptr;
resolution_entry_t *_free_resolution_entries = nullptr; resolution_entry_t *_free_resolution_entries = nullptr;
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
}; };
} }

View File

@ -30,11 +30,13 @@ namespace ble {
*/ */
struct PalPrivateAddressController { struct PalPrivateAddressController {
struct EventHandler { struct EventHandler {
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
/** Called when the address resolution request has completed. /** Called when the address resolution request has completed.
* *
* @param success true if the address has been resolved and false otherwise. * @param success true if the address has been resolved and false otherwise.
*/ */
virtual void on_private_address_resolved(bool success) = 0; virtual void on_private_address_resolved(bool success) = 0;
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
/** Called when the resolvable private address request has completed. /** Called when the resolvable private address request has completed.
* *