Business logic for handling non-resolvable private addresses

pull/6932/head
Donatien Garnier 2018-05-14 13:26:39 +01:00
parent 69e35c49c8
commit a3d9d6cebd
3 changed files with 108 additions and 3 deletions

View File

@ -341,6 +341,12 @@ private:
ble_error_t update_address_resolution_setting();
void set_random_address_rotation(bool enable);
void update_random_address();
void on_address_rotation_timeout();
pal::EventQueue& _event_queue;
pal::Gap &_pal_gap;
pal::GenericAccessService &_gap_service;
@ -354,9 +360,12 @@ private:
bool _privacy_enabled;
PeripheralPrivacyConfiguration_t _peripheral_privacy_configuration;
CentralPrivacyConfiguration_t _central_privacy_configuration;
ble::address_t _random_static_identity_address;
bool _random_address_rotating;
mbed::Timeout _advertising_timeout;
mbed::Timeout _scan_timeout;
mbed::Ticker _address_rotation_ticker;
pal::ConnectionEventMonitor::EventHandler *_connection_event_handler;
};

View File

@ -401,6 +401,9 @@ GenericGap::GenericGap(
_pal_gap.when_gap_event_received(
mbed::callback(this, &GenericGap::on_gap_event_received)
);
// Recover static random identity
_random_static_identity_address = _pal_gap.get_random_address();
}
GenericGap::~GenericGap()
@ -432,6 +435,7 @@ ble_error_t GenericGap::setAddress(
_address_type = BLEProtocol::AddressType::RANDOM;
_address = ble::address_t(address);
_random_static_identity_address = ble::address_t(address);
return BLE_ERROR_NONE;
}
@ -487,6 +491,10 @@ ble_error_t GenericGap::stopAdvertising()
}
_advertising_timeout.detach();
state.advertising = false;
// Stop address rotation if required
set_random_address_rotation(false);
return BLE_ERROR_NONE;
}
@ -497,6 +505,9 @@ ble_error_t GenericGap::stopScan()
return err;
}
// Stop address rotation if required
set_random_address_rotation(false);
_scan_timeout.detach();
return BLE_ERROR_NONE;
}
@ -822,11 +833,19 @@ ble_error_t GenericGap::startRadioScan(const GapScanningParams &scanningParams)
return BLE_ERROR_INVALID_STATE;
}
pal::own_address_type_t own_address_type = get_own_address_type(true /* central */, true /* can use non resolvable address for scan requests */);
if(_privacy_enabled && (own_address_type == pal::own_address_type_t::RANDOM_ADDRESS))
{
// Use non-resolvable static random address
set_random_address_rotation(true);
}
ble_error_t err = _pal_gap.set_scan_parameters(
scanningParams.getActiveScanning(),
scanningParams.getInterval(),
scanningParams.getWindow(),
get_own_address_type(true /* central */, true /* can use non resolvable address for scan requests */),
own_address_type,
_scanning_filter_policy
);
@ -930,6 +949,15 @@ ble_error_t GenericGap::startAdvertising(const GapAdvertisingParams& params)
return BLE_ERROR_INVALID_PARAM;
}
pal::own_address_type_t own_address_type = get_own_address_type(false /* peripheral */,
params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED /* we can only use non resolvable addresses int this case */);
if(_privacy_enabled && (own_address_type == pal::own_address_type_t::RANDOM_ADDRESS))
{
// Use non-resolvable static random address
set_random_address_rotation(true);
}
// TODO: fix the high level API to have a min/max range
// Going against recommendations (The Advertising_Interval_Min and
// Advertising_Interval_Max should not be the same value to enable the
@ -940,8 +968,7 @@ ble_error_t GenericGap::startAdvertising(const GapAdvertisingParams& params)
/* advertising_interval_min */ params.getIntervalInADVUnits(),
/* advertising_interval_max */ params.getIntervalInADVUnits(),
(pal::advertising_type_t::type) params.getAdvertisingType(),
get_own_address_type(false /* peripheral */,
params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED /* we can only use non resolvable addresses int this case */),
own_address_type,
pal::advertising_peer_address_type_t::PUBLIC_ADDRESS,
ble::address_t(),
pal::advertising_channel_map_t::ALL_ADVERTISING_CHANNELS,
@ -1054,6 +1081,10 @@ void GenericGap::process_advertising_timeout()
if (err) {
// TODO: define the mechanism signaling the error
}
// Stop address rotation if required
set_random_address_rotation(false);
processTimeoutEvent(Gap::TIMEOUT_SRC_ADVERTISING);
}
@ -1155,6 +1186,9 @@ void GenericGap::on_connection_complete(const pal::GapConnectionCompleteEvent& e
if (e.role.value() == e.role.SLAVE) {
_advertising_timeout.detach();
_pal_gap.advertising_enable(false);
// Stop address rotation if required
set_random_address_rotation(false);
}
// using these parameters if stupid, there is no range for the
@ -1309,6 +1343,64 @@ ble_error_t GenericGap::update_address_resolution_setting()
return _pal_gap.set_address_resolution(enable);
}
void GenericGap::set_random_address_rotation(bool enable)
{
if(enable == _random_address_rotating) {
return;
}
_random_address_rotating = enable;
if(enable) {
// Set first address
update_random_address();
// Schedule rotations every 15 minutes as recomended by the spec
_address_rotation_ticker.attach_us(
mbed::callback(this, &GenericGap::on_address_rotation_timeout),
15 * 60 * 1000000U
);
}
else {
// Stop ticker
_address_rotation_ticker.detach();
// Set static random identity address
_pal_gap.set_random_address(
_random_static_identity_address
);
}
}
void GenericGap::update_random_address()
{
ble::address_t address;
if(!_random_address_rotating)
{
// This event might have been queued before we disabled address rotation
return;
}
// TODO: Placeholder: Get random data
// Build a non-resolvable private address
ble_error_t err = _pal_gap.set_random_address(
address
);
if (err) {
return;
}
_address_type = BLEProtocol::AddressType::RANDOM;
_address = address;
}
void GenericGap::on_address_rotation_timeout()
{
_event_queue.post(mbed::callback(this, &GenericGap::update_random_address));
}
void GenericGap::set_connection_event_handler(pal::ConnectionEventMonitor::EventHandler *connection_event_handler)
{
_connection_event_handler = connection_event_handler;

View File

@ -311,6 +311,9 @@ public:
virtual ble_error_t set_privacy(
bool enable
) {
//
return BLE_ERROR_NONE;
}
@ -478,6 +481,7 @@ private:
};
private:
address_t device_random_static_identity_address;
address_t device_random_address;
bool use_active_scanning;
};