@@ -401,6 +401,9 @@ GenericGap::GenericGap(
401
401
_pal_gap.when_gap_event_received (
402
402
mbed::callback (this , &GenericGap::on_gap_event_received)
403
403
);
404
+
405
+ // Recover static random identity
406
+ _random_static_identity_address = _pal_gap.get_random_address ();
404
407
}
405
408
406
409
GenericGap::~GenericGap ()
@@ -432,6 +435,7 @@ ble_error_t GenericGap::setAddress(
432
435
433
436
_address_type = BLEProtocol::AddressType::RANDOM;
434
437
_address = ble::address_t (address);
438
+ _random_static_identity_address = ble::address_t (address);
435
439
return BLE_ERROR_NONE;
436
440
}
437
441
@@ -487,6 +491,10 @@ ble_error_t GenericGap::stopAdvertising()
487
491
}
488
492
_advertising_timeout.detach ();
489
493
state.advertising = false ;
494
+
495
+ // Stop address rotation if required
496
+ set_random_address_rotation (false );
497
+
490
498
return BLE_ERROR_NONE;
491
499
}
492
500
@@ -497,6 +505,9 @@ ble_error_t GenericGap::stopScan()
497
505
return err;
498
506
}
499
507
508
+ // Stop address rotation if required
509
+ set_random_address_rotation (false );
510
+
500
511
_scan_timeout.detach ();
501
512
return BLE_ERROR_NONE;
502
513
}
@@ -822,11 +833,19 @@ ble_error_t GenericGap::startRadioScan(const GapScanningParams &scanningParams)
822
833
return BLE_ERROR_INVALID_STATE;
823
834
}
824
835
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
+
825
844
ble_error_t err = _pal_gap.set_scan_parameters (
826
845
scanningParams.getActiveScanning (),
827
846
scanningParams.getInterval (),
828
847
scanningParams.getWindow (),
829
- get_own_address_type ( true /* central */ , true /* can use non resolvable address for scan requests */ ) ,
848
+ own_address_type ,
830
849
_scanning_filter_policy
831
850
);
832
851
@@ -930,6 +949,15 @@ ble_error_t GenericGap::startAdvertising(const GapAdvertisingParams& params)
930
949
return BLE_ERROR_INVALID_PARAM;
931
950
}
932
951
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
+
933
961
// TODO: fix the high level API to have a min/max range
934
962
// Going against recommendations (The Advertising_Interval_Min and
935
963
// Advertising_Interval_Max should not be the same value to enable the
@@ -940,8 +968,7 @@ ble_error_t GenericGap::startAdvertising(const GapAdvertisingParams& params)
940
968
/* advertising_interval_min */ params.getIntervalInADVUnits (),
941
969
/* advertising_interval_max */ params.getIntervalInADVUnits (),
942
970
(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,
945
972
pal::advertising_peer_address_type_t ::PUBLIC_ADDRESS,
946
973
ble::address_t (),
947
974
pal::advertising_channel_map_t ::ALL_ADVERTISING_CHANNELS,
@@ -1054,6 +1081,10 @@ void GenericGap::process_advertising_timeout()
1054
1081
if (err) {
1055
1082
// TODO: define the mechanism signaling the error
1056
1083
}
1084
+
1085
+ // Stop address rotation if required
1086
+ set_random_address_rotation (false );
1087
+
1057
1088
processTimeoutEvent (Gap::TIMEOUT_SRC_ADVERTISING);
1058
1089
}
1059
1090
@@ -1155,6 +1186,9 @@ void GenericGap::on_connection_complete(const pal::GapConnectionCompleteEvent& e
1155
1186
if (e.role .value () == e.role .SLAVE ) {
1156
1187
_advertising_timeout.detach ();
1157
1188
_pal_gap.advertising_enable (false );
1189
+
1190
+ // Stop address rotation if required
1191
+ set_random_address_rotation (false );
1158
1192
}
1159
1193
1160
1194
// using these parameters if stupid, there is no range for the
@@ -1309,6 +1343,64 @@ ble_error_t GenericGap::update_address_resolution_setting()
1309
1343
return _pal_gap.set_address_resolution (enable);
1310
1344
}
1311
1345
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
+
1312
1404
void GenericGap::set_connection_event_handler (pal::ConnectionEventMonitor::EventHandler *connection_event_handler)
1313
1405
{
1314
1406
_connection_event_handler = connection_event_handler;
0 commit comments