Skip to content

Commit a3d9d6c

Browse files
author
Donatien Garnier
committed
Business logic for handling non-resolvable private addresses
1 parent 69e35c4 commit a3d9d6c

File tree

3 files changed

+108
-3
lines changed

3 files changed

+108
-3
lines changed

features/FEATURE_BLE/ble/generic/GenericGap.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,12 @@ class GenericGap : public ::Gap,
341341

342342
ble_error_t update_address_resolution_setting();
343343

344+
void set_random_address_rotation(bool enable);
345+
346+
void update_random_address();
347+
348+
void on_address_rotation_timeout();
349+
344350
pal::EventQueue& _event_queue;
345351
pal::Gap &_pal_gap;
346352
pal::GenericAccessService &_gap_service;
@@ -354,9 +360,12 @@ class GenericGap : public ::Gap,
354360
bool _privacy_enabled;
355361
PeripheralPrivacyConfiguration_t _peripheral_privacy_configuration;
356362
CentralPrivacyConfiguration_t _central_privacy_configuration;
363+
ble::address_t _random_static_identity_address;
364+
bool _random_address_rotating;
357365

358366
mbed::Timeout _advertising_timeout;
359367
mbed::Timeout _scan_timeout;
368+
mbed::Ticker _address_rotation_ticker;
360369
pal::ConnectionEventMonitor::EventHandler *_connection_event_handler;
361370
};
362371

features/FEATURE_BLE/source/generic/GenericGap.cpp

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,9 @@ GenericGap::GenericGap(
401401
_pal_gap.when_gap_event_received(
402402
mbed::callback(this, &GenericGap::on_gap_event_received)
403403
);
404+
405+
// Recover static random identity
406+
_random_static_identity_address = _pal_gap.get_random_address();
404407
}
405408

406409
GenericGap::~GenericGap()
@@ -432,6 +435,7 @@ ble_error_t GenericGap::setAddress(
432435

433436
_address_type = BLEProtocol::AddressType::RANDOM;
434437
_address = ble::address_t(address);
438+
_random_static_identity_address = ble::address_t(address);
435439
return BLE_ERROR_NONE;
436440
}
437441

@@ -487,6 +491,10 @@ ble_error_t GenericGap::stopAdvertising()
487491
}
488492
_advertising_timeout.detach();
489493
state.advertising = false;
494+
495+
// Stop address rotation if required
496+
set_random_address_rotation(false);
497+
490498
return BLE_ERROR_NONE;
491499
}
492500

@@ -497,6 +505,9 @@ ble_error_t GenericGap::stopScan()
497505
return err;
498506
}
499507

508+
// Stop address rotation if required
509+
set_random_address_rotation(false);
510+
500511
_scan_timeout.detach();
501512
return BLE_ERROR_NONE;
502513
}
@@ -822,11 +833,19 @@ ble_error_t GenericGap::startRadioScan(const GapScanningParams &scanningParams)
822833
return BLE_ERROR_INVALID_STATE;
823834
}
824835

836+
pal::own_address_type_t own_address_type = get_own_address_type(true /* central */, true /* can use non resolvable address for scan requests */);
837+
838+
if(_privacy_enabled && (own_address_type == pal::own_address_type_t::RANDOM_ADDRESS))
839+
{
840+
// Use non-resolvable static random address
841+
set_random_address_rotation(true);
842+
}
843+
825844
ble_error_t err = _pal_gap.set_scan_parameters(
826845
scanningParams.getActiveScanning(),
827846
scanningParams.getInterval(),
828847
scanningParams.getWindow(),
829-
get_own_address_type(true /* central */, true /* can use non resolvable address for scan requests */),
848+
own_address_type,
830849
_scanning_filter_policy
831850
);
832851

@@ -930,6 +949,15 @@ ble_error_t GenericGap::startAdvertising(const GapAdvertisingParams& params)
930949
return BLE_ERROR_INVALID_PARAM;
931950
}
932951

952+
pal::own_address_type_t own_address_type = get_own_address_type(false /* peripheral */,
953+
params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED /* we can only use non resolvable addresses int this case */);
954+
955+
if(_privacy_enabled && (own_address_type == pal::own_address_type_t::RANDOM_ADDRESS))
956+
{
957+
// Use non-resolvable static random address
958+
set_random_address_rotation(true);
959+
}
960+
933961
// TODO: fix the high level API to have a min/max range
934962
// Going against recommendations (The Advertising_Interval_Min and
935963
// Advertising_Interval_Max should not be the same value to enable the
@@ -940,8 +968,7 @@ ble_error_t GenericGap::startAdvertising(const GapAdvertisingParams& params)
940968
/* advertising_interval_min */ params.getIntervalInADVUnits(),
941969
/* advertising_interval_max */ params.getIntervalInADVUnits(),
942970
(pal::advertising_type_t::type) params.getAdvertisingType(),
943-
get_own_address_type(false /* peripheral */,
944-
params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED /* we can only use non resolvable addresses int this case */),
971+
own_address_type,
945972
pal::advertising_peer_address_type_t::PUBLIC_ADDRESS,
946973
ble::address_t(),
947974
pal::advertising_channel_map_t::ALL_ADVERTISING_CHANNELS,
@@ -1054,6 +1081,10 @@ void GenericGap::process_advertising_timeout()
10541081
if (err) {
10551082
// TODO: define the mechanism signaling the error
10561083
}
1084+
1085+
// Stop address rotation if required
1086+
set_random_address_rotation(false);
1087+
10571088
processTimeoutEvent(Gap::TIMEOUT_SRC_ADVERTISING);
10581089
}
10591090

@@ -1155,6 +1186,9 @@ void GenericGap::on_connection_complete(const pal::GapConnectionCompleteEvent& e
11551186
if (e.role.value() == e.role.SLAVE) {
11561187
_advertising_timeout.detach();
11571188
_pal_gap.advertising_enable(false);
1189+
1190+
// Stop address rotation if required
1191+
set_random_address_rotation(false);
11581192
}
11591193

11601194
// using these parameters if stupid, there is no range for the
@@ -1309,6 +1343,64 @@ ble_error_t GenericGap::update_address_resolution_setting()
13091343
return _pal_gap.set_address_resolution(enable);
13101344
}
13111345

1346+
void GenericGap::set_random_address_rotation(bool enable)
1347+
{
1348+
if(enable == _random_address_rotating) {
1349+
return;
1350+
}
1351+
1352+
_random_address_rotating = enable;
1353+
1354+
if(enable) {
1355+
// Set first address
1356+
update_random_address();
1357+
1358+
// Schedule rotations every 15 minutes as recomended by the spec
1359+
_address_rotation_ticker.attach_us(
1360+
mbed::callback(this, &GenericGap::on_address_rotation_timeout),
1361+
15 * 60 * 1000000U
1362+
);
1363+
}
1364+
else {
1365+
// Stop ticker
1366+
_address_rotation_ticker.detach();
1367+
1368+
// Set static random identity address
1369+
_pal_gap.set_random_address(
1370+
_random_static_identity_address
1371+
);
1372+
}
1373+
}
1374+
1375+
void GenericGap::update_random_address()
1376+
{
1377+
ble::address_t address;
1378+
1379+
if(!_random_address_rotating)
1380+
{
1381+
// This event might have been queued before we disabled address rotation
1382+
return;
1383+
}
1384+
1385+
// TODO: Placeholder: Get random data
1386+
// Build a non-resolvable private address
1387+
1388+
ble_error_t err = _pal_gap.set_random_address(
1389+
address
1390+
);
1391+
if (err) {
1392+
return;
1393+
}
1394+
1395+
_address_type = BLEProtocol::AddressType::RANDOM;
1396+
_address = address;
1397+
}
1398+
1399+
void GenericGap::on_address_rotation_timeout()
1400+
{
1401+
_event_queue.post(mbed::callback(this, &GenericGap::update_random_address));
1402+
}
1403+
13121404
void GenericGap::set_connection_event_handler(pal::ConnectionEventMonitor::EventHandler *connection_event_handler)
13131405
{
13141406
_connection_event_handler = connection_event_handler;

features/FEATURE_BLE/targets/TARGET_CORDIO/CordioPalGap.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ class Gap : public ::ble::pal::Gap {
311311
virtual ble_error_t set_privacy(
312312
bool enable
313313
) {
314+
//
315+
316+
314317
return BLE_ERROR_NONE;
315318
}
316319

@@ -478,6 +481,7 @@ class Gap : public ::ble::pal::Gap {
478481
};
479482

480483
private:
484+
address_t device_random_static_identity_address;
481485
address_t device_random_address;
482486
bool use_active_scanning;
483487
};

0 commit comments

Comments
 (0)