Skip to content

Commit 949f9f0

Browse files
authored
Merge pull request #13685 from paul-szczepanek-arm/host-privacy-feature
allow host resolved address to be used for connection
2 parents a609f9b + 0491817 commit 949f9f0

File tree

2 files changed

+159
-29
lines changed

2 files changed

+159
-29
lines changed

connectivity/FEATURE_BLE/source/generic/GapImpl.cpp

Lines changed: 143 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -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

666709
ble_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

11081190
void 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

connectivity/FEATURE_BLE/source/generic/GapImpl.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,10 @@ class Gap :
798798

799799
const address_t *get_random_address(controller_operation_t operation, size_t advertising_set = 0);
800800

801+
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
802+
void connecting_to_host_resolved_address_failed(bool inform_user = true);
803+
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
804+
801805
private:
802806
/**
803807
* Callchain containing all registered callback handlers for shutdown
@@ -847,6 +851,18 @@ class Gap :
847851
bool _scan_pending = false;
848852
bool _scan_interruptible = false;
849853
bool _scan_address_refresh = false;
854+
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
855+
enum class ConnectionToHostResolvedAddressState : uint8_t {
856+
idle,
857+
scan,
858+
connect
859+
};
860+
ble::address_t _connect_to_host_resolved_address;
861+
peer_address_type_t _connect_to_host_resolved_address_type = peer_address_type_t::ANONYMOUS;
862+
ConnectionToHostResolvedAddressState _connect_to_host_resolved_address_state = ConnectionToHostResolvedAddressState::idle;
863+
ConnectionParameters *_connect_to_host_resolved_address_parameters = nullptr;
864+
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
865+
850866
mbed::LowPowerTimeout _advertising_timeout;
851867
mbed::LowPowerTimeout _scan_timeout;
852868
mbed::LowPowerTicker _address_rotation_ticker;

0 commit comments

Comments
 (0)