@@ -467,7 +467,7 @@ ble_error_t Gap::stopScan()
467467{
468468 ble_error_t err;
469469
470- if ((!_scan_enabled && !_scan_pending) || _scan_pending) {
470+ if ((!_scan_enabled && !_scan_pending) || _scan_pending || _initiating ) {
471471 return BLE_STACK_BUSY;
472472 }
473473
@@ -494,6 +494,12 @@ ble_error_t Gap::connect(
494494 const ConnectionParameters &connectionParams
495495)
496496{
497+ #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
498+ if (_connect_to_host_resolved_address_state == ConnectionToHostResolvedAddressState::scan) {
499+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
500+ }
501+ #endif BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
502+
497503 if (!connectionParams.getNumberOfEnabledPhys ()) {
498504 return BLE_ERROR_INVALID_PARAM;
499505 }
@@ -521,6 +527,31 @@ ble_error_t Gap::connect(
521527
522528 ble_error_t ret = BLE_ERROR_INTERNAL_STACK_FAILURE;
523529
530+ #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
531+ /* if host resolution is used we need to connect in two passes, first we scan for addresses to find
532+ * a resolving match and then we call connect again with the correct address */
533+ if (_connect_to_host_resolved_address_state == ConnectionToHostResolvedAddressState::idle) {
534+ if (peerAddressType == peer_address_type_t ::RANDOM_STATIC_IDENTITY ||
535+ peerAddressType == peer_address_type_t ::PUBLIC_IDENTITY) {
536+
537+ _connect_to_host_resolved_address_parameters = new ConnectionParameters (connectionParams);
538+ if (!_connect_to_host_resolved_address_parameters) {
539+ return BLE_ERROR_NO_MEM;
540+ }
541+
542+ _connect_to_host_resolved_address_type = peerAddressType;
543+ _connect_to_host_resolved_address = peerAddress;
544+ _connect_to_host_resolved_address_state = ConnectionToHostResolvedAddressState::scan;
545+ }
546+ } else if (_connect_to_host_resolved_address_state == ConnectionToHostResolvedAddressState::connect) {
547+ /* the first pass of connect has completed and this is the second connect that doesn't require
548+ * address resolution */
549+ _connect_to_host_resolved_address_state = ConnectionToHostResolvedAddressState::idle;
550+ _initiating = false ;
551+ }
552+
553+ #endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
554+
524555 if (is_extended_advertising_available () == false ) {
525556 phy_set_t set (connectionParams.getPhySet ());
526557 if (set.count () != 1 || set.get_1m () == false ) {
@@ -530,35 +561,47 @@ ble_error_t Gap::connect(
530561 if (!_scan_enabled) {
531562 if (!_active_sets.get (LEGACY_ADVERTISING_HANDLE) &&
532563 !_pending_sets.get (LEGACY_ADVERTISING_HANDLE)
533- ) {
564+ ) {
534565 _pal_gap.set_random_address (*address);
535566 }
536567 } else {
537- // ensure scan is stopped.
538- _pal_gap.scan_enable (false , false );
568+ stopScan ();
569+ }
570+ #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
571+ if (_connect_to_host_resolved_address_state == ConnectionToHostResolvedAddressState::scan) {
572+ ret = startScan (
573+ scan_duration_t::forever (),
574+ duplicates_filter_t ::ENABLE,
575+ (scan_period_t )0
576+ );
577+ if (ret != BLE_ERROR_NONE) {
578+ _connect_to_host_resolved_address_state = ConnectionToHostResolvedAddressState::idle;
579+ }
580+ } else
581+ #endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
582+ {
583+ ret = _pal_gap.create_connection (
584+ connectionParams.getScanIntervalArray ()[0 ],
585+ connectionParams.getScanWindowArray ()[0 ],
586+ connectionParams.getFilter (),
587+ (connection_peer_address_type_t ::type) peerAddressType.value (),
588+ peerAddress,
589+ connectionParams.getOwnAddressType (),
590+ connectionParams.getMinConnectionIntervalArray ()[0 ],
591+ connectionParams.getMaxConnectionIntervalArray ()[0 ],
592+ connectionParams.getSlaveLatencyArray ()[0 ],
593+ connectionParams.getConnectionSupervisionTimeoutArray ()[0 ],
594+ connectionParams.getMinEventLengthArray ()[0 ],
595+ connectionParams.getMaxConnectionIntervalArray ()[0 ]
596+ );
539597 }
540-
541- ret = _pal_gap.create_connection (
542- connectionParams.getScanIntervalArray ()[0 ],
543- connectionParams.getScanWindowArray ()[0 ],
544- connectionParams.getFilter (),
545- (connection_peer_address_type_t ::type) peerAddressType.value (),
546- peerAddress,
547- connectionParams.getOwnAddressType (),
548- connectionParams.getMinConnectionIntervalArray ()[0 ],
549- connectionParams.getMaxConnectionIntervalArray ()[0 ],
550- connectionParams.getSlaveLatencyArray ()[0 ],
551- connectionParams.getConnectionSupervisionTimeoutArray ()[0 ],
552- connectionParams.getMinEventLengthArray ()[0 ],
553- connectionParams.getMaxConnectionIntervalArray ()[0 ]
554- );
555598 } else {
556599 // set the correct mac address before starting scanning.
557600 if (!_scan_enabled) {
558601 _pal_gap.set_random_address (*address);
559602 } else {
560603 // ensure scan is stopped.
561- _pal_gap. extended_scan_enable ( false , duplicates_filter_t ::DISABLE, 0 , 0 );
604+ stopScan ( );
562605 }
563606
564607 // reduce the address type to public or random
@@ -665,6 +708,14 @@ ble_error_t Gap::rejectConnectionParametersUpdate(
665708
666709ble_error_t Gap::cancelConnect ()
667710{
711+ #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
712+ if (_connect_to_host_resolved_address_state == ConnectionToHostResolvedAddressState::scan) {
713+ connecting_to_host_resolved_address_failed (false );
714+ stopScan ();
715+ return BLE_ERROR_NONE;
716+ }
717+ #endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
718+
668719 if (!_initiating) {
669720 return BLE_ERROR_NONE;
670721 }
@@ -981,10 +1032,15 @@ ble_error_t Gap::reset()
9811032 shutdownCallChain.clear ();
9821033
9831034 _event_handler = nullptr ;
984-
1035+ _initiating = false ;
9851036#if BLE_FEATURE_PRIVACY
9861037 _privacy_initialization_pending = false ;
987- #endif
1038+ #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
1039+ _connect_to_host_resolved_address_state = ConnectionToHostResolvedAddressState::idle;
1040+ delete _connect_to_host_resolved_address_parameters;
1041+ _connect_to_host_resolved_address_parameters = nullptr ;
1042+ #endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
1043+ #endif // BLE_FEATURE_PRIVACY
9881044
9891045#if BLE_ROLE_BROADCASTER
9901046 _advertising_timeout.detach ();
@@ -1104,6 +1160,32 @@ void Gap::on_scan_stopped(bool success)
11041160 }
11051161}
11061162
1163+ #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
1164+ void Gap::connecting_to_host_resolved_address_failed (bool inform_user)
1165+ {
1166+ if (inform_user && _event_handler) {
1167+ _event_handler->onConnectionComplete (
1168+ ConnectionCompleteEvent (
1169+ BLE_ERROR_NOT_FOUND,
1170+ INVALID_ADVERTISING_HANDLE,
1171+ connection_role_t ::CENTRAL,
1172+ peer_address_type_t ::ANONYMOUS,
1173+ ble::address_t (),
1174+ ble::address_t (),
1175+ ble::address_t (),
1176+ ble::conn_interval_t::max (),
1177+ /* dummy slave latency */ 0 ,
1178+ ble::supervision_timeout_t::max (),
1179+ /* master clock accuracy */ 0
1180+ )
1181+ );
1182+ }
1183+ _connect_to_host_resolved_address_state = ConnectionToHostResolvedAddressState::idle;
1184+ delete _connect_to_host_resolved_address_parameters;
1185+ _connect_to_host_resolved_address_parameters = nullptr ;
1186+ _initiating = false ;
1187+ }
1188+ #endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
11071189
11081190void Gap::on_scan_timeout ()
11091191{
@@ -2456,9 +2538,23 @@ void Gap::signal_advertising_report(
24562538
24572539 /* if successful then proceed to call the handler immediately same as for when privacy is disabled */
24582540 if (address_resolved) {
2459- _event_handler->onAdvertisingReport (
2460- event
2461- );
2541+ if (_connect_to_host_resolved_address_state == ConnectionToHostResolvedAddressState::scan) {
2542+ if (_connect_to_host_resolved_address_type == event.getDirectAddressType () &&
2543+ _connect_to_host_resolved_address == event.getDirectAddress ()) {
2544+ _connect_to_host_resolved_address_state = ConnectionToHostResolvedAddressState::connect;
2545+ connect (
2546+ _connect_to_host_resolved_address_type,
2547+ _connect_to_host_resolved_address,
2548+ *_connect_to_host_resolved_address_parameters
2549+ );
2550+ delete _connect_to_host_resolved_address_parameters;
2551+ _connect_to_host_resolved_address_parameters = nullptr ;
2552+ }
2553+ } else {
2554+ _event_handler->onAdvertisingReport (
2555+ event
2556+ );
2557+ }
24622558 } else {
24632559 /* check if there already is a RPA like that in the list of other pending reports */
24642560 PendingAdvertisingReportEvent *duplicate_pending_event = _reports_pending_address_resolution.find (
@@ -2507,12 +2603,30 @@ void Gap::conclude_signal_advertising_report_after_address_resolution(
25072603 const address_t *identity_address
25082604)
25092605{
2606+
2607+
25102608 /* fix the report with the new address if there's an identity found */
25112609 if (identity_address) {
2610+ const peer_address_type_t peer_address_type = (identity_address_type == target_peer_address_type_t ::RANDOM) ?
2611+ peer_address_type_t ::RANDOM_STATIC_IDENTITY
2612+ : peer_address_type_t ::PUBLIC_IDENTITY;
2613+
2614+ if (_connect_to_host_resolved_address_state == ConnectionToHostResolvedAddressState::scan) {
2615+ if (_connect_to_host_resolved_address_type == peer_address_type && _connect_to_host_resolved_address == *identity_address) {
2616+ _connect_to_host_resolved_address_state = ConnectionToHostResolvedAddressState::connect;
2617+ connect (
2618+ event.getPeerAddressType (),
2619+ event.getPeerAddress (),
2620+ *_connect_to_host_resolved_address_parameters
2621+ );
2622+ delete _connect_to_host_resolved_address_parameters;
2623+ _connect_to_host_resolved_address_parameters = nullptr ;
2624+ return ;
2625+ }
2626+ }
2627+
25122628 event.setPeerAddress (*identity_address);
2513- event.setPeerAddressType (identity_address_type == target_peer_address_type_t ::RANDOM ?
2514- peer_address_type_t ::RANDOM_STATIC_IDENTITY
2515- : peer_address_type_t ::PUBLIC_IDENTITY);
2629+ event.setPeerAddressType (peer_address_type);
25162630 } else if (_central_privacy_configuration.resolution_strategy ==
25172631 central_privacy_configuration_t ::RESOLVE_AND_FILTER &&
25182632 _address_registry.read_resolving_list_size () > 0 ) {
@@ -2788,7 +2902,7 @@ ble_error_t Gap::startScan(
27882902 scan_period_t period
27892903)
27902904{
2791- if (_scan_pending || _scan_address_refresh) {
2905+ if (_scan_pending || _scan_address_refresh || _initiating ) {
27922906 return BLE_STACK_BUSY;
27932907 }
27942908
0 commit comments