diff --git a/connectivity/FEATURE_BLE/include/ble/Gap.h b/connectivity/FEATURE_BLE/include/ble/Gap.h index 88dd9b58247..b056b399b0f 100644 --- a/connectivity/FEATURE_BLE/include/ble/Gap.h +++ b/connectivity/FEATURE_BLE/include/ble/Gap.h @@ -538,6 +538,14 @@ class Gap { ) { } + + /** + * Function invoked when the privacy subsystem has been enabled and is + * ready to be used. + */ + virtual void onPrivacyEnabled() + { + } protected: /** * Prevent polymorphic deletion and avoid unnecessary virtual destructor @@ -1244,6 +1252,14 @@ class Gap { * resolved and advertisement packets are forwarded to the application * even if the advertiser private address is unknown. * + * @par Initialization of the privacy subsystem + * + * When privacy is enabled, the system generates new resolvable and non + * resolvable private addresses. Scan, Advertising and Connecting to a peer + * won't be available until the generation process completes. When addresses + * have been generated, the application is notified that privacy + * initialisation as completed with a call to EventHandler::onPrivacyEnabled . + * * @param[in] enable Should be set to true to enable the privacy mode and * false to disable it. * diff --git a/connectivity/FEATURE_BLE/source/generic/GapImpl.cpp b/connectivity/FEATURE_BLE/source/generic/GapImpl.cpp index 06ac3ce0dd5..842c6d31801 100644 --- a/connectivity/FEATURE_BLE/source/generic/GapImpl.cpp +++ b/connectivity/FEATURE_BLE/source/generic/GapImpl.cpp @@ -896,8 +896,20 @@ ble_error_t Gap::enablePrivacy(bool enable) if (_privacy_enabled) { _address_registry.start_private_address_generation(); + if (_address_registry.get_non_resolvable_private_address() != address_t {} && + _address_registry.get_resolvable_private_address() != address_t{} + ) { + _event_queue.post([this] { + if (_event_handler) { + _event_handler->onPrivacyEnabled(); + } + }); + } else { + _privacy_initialization_pending = true; + } } else { _address_registry.stop_private_address_generation(); + _privacy_initialization_pending = false; } #if !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION @@ -970,6 +982,10 @@ ble_error_t Gap::reset() _event_handler = nullptr; +#if BLE_FEATURE_PRIVACY + _privacy_initialization_pending = false; +#endif + #if BLE_ROLE_BROADCASTER _advertising_timeout.detach(); #endif @@ -3042,6 +3058,15 @@ void Gap::on_private_address_generated(bool connectable) return; } + if (_privacy_initialization_pending && + _address_registry.get_resolvable_private_address() != address_t{} && + _address_registry.get_non_resolvable_private_address() != address_t{} + ) { + _privacy_initialization_pending = false; + if (_event_handler) { + _event_handler->onPrivacyEnabled(); + } + } // refresh for address for all connectable advertising sets for (size_t i = 0; i < BLE_GAP_MAX_ADVERTISING_SETS; ++i) { @@ -3240,6 +3265,10 @@ const address_t *Gap::get_random_address(controller_operation_t operation, size_ break; } + if (*desired_address == address_t{}) { + return nullptr; + } + if (!address_in_use) { return desired_address; } diff --git a/connectivity/FEATURE_BLE/source/generic/GapImpl.h b/connectivity/FEATURE_BLE/source/generic/GapImpl.h index c0ab2a9063e..2e841c81e64 100644 --- a/connectivity/FEATURE_BLE/source/generic/GapImpl.h +++ b/connectivity/FEATURE_BLE/source/generic/GapImpl.h @@ -832,6 +832,7 @@ class Gap : bool _privacy_enabled; #if BLE_FEATURE_PRIVACY + bool _privacy_initialization_pending = false; #if BLE_ROLE_PERIPHERAL peripheral_privacy_configuration_t _peripheral_privacy_configuration; #endif // BLE_ROLE_PERIPHERAL