diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp index 32e1e3df0c..8839fd19db 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp @@ -61,7 +61,7 @@ void app_error_handler(uint32_t error_code, uint32_t line_num, const extern "C" void SD_EVT_IRQHandler(void); // export the softdevice event handler for registration by nvic-set-vector. -static void btle_handler(ble_evt_t *p_ble_evt); +void btle_handler(ble_evt_t *p_ble_evt); static void sys_evt_dispatch(uint32_t sys_evt) { @@ -161,7 +161,7 @@ error_t btle_init(void) return btle_gap_init(); } -static void btle_handler(ble_evt_t *p_ble_evt) +void btle_handler(ble_evt_t *p_ble_evt) { using ble::pal::vendor::nordic::nRF5XGattClient; using ble::pal::vendor::nordic::nRF5xSecurityManager; @@ -189,38 +189,12 @@ static void btle_handler(ble_evt_t *p_ble_evt) /* Custom event handler */ switch (p_ble_evt->header.evt_id) { - case BLE_GAP_EVT_CONNECTED: { - Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle; -#if defined(TARGET_MCU_NRF51_16K_S110) || defined(TARGET_MCU_NRF51_32K_S110) - /* Only peripheral role is supported by S110 */ - Gap::Role_t role = Gap::PERIPHERAL; -#else - Gap::Role_t role = static_cast(p_ble_evt->evt.gap_evt.params.connected.role); -#endif - gap.setConnectionHandle(handle); - const Gap::ConnectionParams_t *params = reinterpret_cast(&(p_ble_evt->evt.gap_evt.params.connected.conn_params)); - const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr; -#if (NRF_SD_BLE_API_VERSION <= 2) - const ble_gap_addr_t *own = &p_ble_evt->evt.gap_evt.params.connected.own_addr; - - gap.processConnectionEvent(handle, - role, - static_cast(peer->addr_type), peer->addr, - static_cast(own->addr_type), own->addr, - params); -#else - Gap::AddressType_t addr_type; - Gap::Address_t own_address; - gap.getAddress(&addr_type, own_address); - - gap.processConnectionEvent(handle, - role, - static_cast(peer->addr_type), peer->addr, - addr_type, own_address, - params); -#endif + case BLE_GAP_EVT_CONNECTED: + gap.on_connection( + p_ble_evt->evt.gap_evt.conn_handle, + p_ble_evt->evt.gap_evt.params.connected + ); break; - } case BLE_GAP_EVT_DISCONNECTED: { Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle; @@ -266,17 +240,9 @@ static void btle_handler(ble_evt_t *p_ble_evt) // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION)); break; - case BLE_GAP_EVT_ADV_REPORT: { - const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report; - gap.processAdvertisementReport(advReport->peer_addr.addr, - advReport->rssi, - advReport->scan_rsp, - static_cast(advReport->type), - advReport->dlen, - advReport->data, - static_cast(advReport->peer_addr.addr_type)); + case BLE_GAP_EVT_ADV_REPORT: + gap.on_advertising_packet(p_ble_evt->evt.gap_evt.params.adv_report); break; - } default: break; diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp index bb38334b59..3d3c085adc 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp @@ -26,7 +26,66 @@ #include "ble_advdata.h" #include "headers/nrf_ble_hci.h" #include "ble/pal/ConnectionEventMonitor.h" +#include "nRF5XPalSecurityManager.h" +using ble::pal::vendor::nordic::nRF5xSecurityManager; +typedef nRF5xSecurityManager::resolving_list_entry_t resolving_list_entry_t; +using ble::ArrayView; +using ble::pal::advertising_peer_address_type_t; + +namespace { + +nRF5xSecurityManager& get_sm() { + return nRF5xSecurityManager::get_security_manager(); +} + +void set_private_resolvable_address() { + ble_gap_addr_t addr = { BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE }; + sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &addr); +} + +void set_private_non_resolvable_address() { + ble_gap_addr_t addr = { BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE }; + sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &addr); +} + +bool is_advertising_non_connectable(const GapAdvertisingParams ¶ms) { + switch (params.getAdvertisingType()) { + case GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED: + case GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED: + return true; + default: + return false; + } +} + +bool is_identity_address(BLEProtocol::AddressType_t address_type) { + switch (address_type) { + case BLEProtocol::AddressType::PUBLIC_IDENTITY: + case BLEProtocol::AddressType::RANDOM_STATIC_IDENTITY: + return true; + default: + return false; + } +} + +BLEProtocol::AddressType_t convert_nordic_address(uint8_t address) { + if (address == BLE_GAP_ADDR_TYPE_PUBLIC) { + return BLEProtocol::AddressType::PUBLIC; + } else { + return BLEProtocol::AddressType::RANDOM; + } +} + +BLEProtocol::AddressType_t convert_identity_address(advertising_peer_address_type_t address) { + if (address == advertising_peer_address_type_t::PUBLIC_ADDRESS) { + return BLEProtocol::AddressType::PUBLIC_IDENTITY; + } else { + return BLEProtocol::AddressType::RANDOM_STATIC_IDENTITY; + } +} + +} // namespace void radioNotificationStaticCallback(bool param) { nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap(); @@ -40,7 +99,11 @@ nRF5xGap::nRF5xGap() : Gap(), whitelistAddresses(), radioNotificationCallbackParam(false), radioNotificationTimeout(), - _connection_event_handler(NULL) + _connection_event_handler(NULL), + _privacy_enabled(false), + _peripheral_privacy_configuration(default_peripheral_privacy_configuration), + _central_privacy_configuration(default_central_privacy_configuration), + _non_private_type(BLEProtocol::AddressType::RANDOM) { m_connectionHandle = BLE_CONN_HANDLE_INVALID; } @@ -204,6 +267,29 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms) } } + if (_privacy_enabled) { + if (_peripheral_privacy_configuration.resolution_strategy != PeripheralPrivacyConfiguration_t::DO_NOT_RESOLVE) { + ArrayView entries = get_sm().get_resolving_list(); + + size_t limit = std::min( + entries.size(), (size_t) YOTTA_CFG_IRK_TABLE_MAX_SIZE + ); + + for (size_t i = 0; i < limit; ++i) { + whitelistIrkPtrs[i] = (ble_gap_irk_t*) entries[i].peer_irk.data(); + } + whitelist.irk_count = limit; + } + + if (_peripheral_privacy_configuration.use_non_resolvable_random_address && + is_advertising_non_connectable(params) + ) { + set_private_non_resolvable_address(); + } else { + set_private_resolvable_address(); + } + } + adv_para.p_whitelist = &whitelist; #endif /* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */ @@ -255,6 +341,8 @@ ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams) } } + // FIXME: fill the irk list once addresses are resolved by the softdevice. + scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */ scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */ #else @@ -270,6 +358,14 @@ ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams) scanParams.window = scanningParams.getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ scanParams.timeout = scanningParams.getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ + if (_privacy_enabled) { + if (_central_privacy_configuration.use_non_resolvable_random_address) { + set_private_non_resolvable_address(); + } else { + set_private_resolvable_address(); + } + } + if (sd_ble_gap_scan_start(&scanParams) != NRF_SUCCESS) { return BLE_ERROR_PARAM_OUT_OF_RANGE; } @@ -318,6 +414,7 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr, const GapScanningParams *scanParamsIn) { ble_gap_addr_t addr; + ble_gap_addr_t* addr_ptr = &addr; addr.addr_type = peerAddrType; memcpy(addr.addr, peerAddr, Gap::ADDR_LEN); @@ -354,9 +451,37 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr, return error; } } - scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */ scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */ + + if (_privacy_enabled) { + // configure the "whitelist" with the IRK associated with the identity + // address in input. + if (is_identity_address(peerAddrType)) { + ArrayView entries = get_sm().get_resolving_list(); + + size_t i; + for (i = 0; i < entries.size(); ++i) { + const ble::address_t& entry_address = entries[i].peer_identity_address; + + // entry found; fill the whitelist and invalidate addr_ptr + if (memcmp(entry_address.data(), peerAddr, entry_address.size_) == 0) { + whitelist.pp_irks[0] = (ble_gap_irk_t*) entries[i].peer_irk.data(); + whitelist.irk_count = 1; + scanParams.selective = 1; + addr_ptr = NULL; + break; + } + } + + // Occur only if the address in input hasn't been resolved. + if (i == entries.size()) { + return BLE_ERROR_INVALID_PARAM; + } + } + + set_private_resolvable_address(); + } #else /* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */ @@ -388,7 +513,7 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr, scanParams.timeout = _scanningParams.getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ } - uint32_t rc = sd_ble_gap_connect(&addr, &scanParams, &connParams); + uint32_t rc = sd_ble_gap_connect(addr_ptr, &scanParams, &connParams); if (rc == NRF_SUCCESS) { return BLE_ERROR_NONE; } @@ -543,52 +668,33 @@ uint16_t nRF5xGap::getConnectionHandle(void) /**************************************************************************/ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address) { -#if (NRF_SD_BLE_API_VERSION <= 2) - uint8_t cycle_mode; -#else - ble_gap_privacy_params_t privacy_params = {0}; -#endif + using BLEProtocol::AddressType; + if (type != AddressType::PUBLIC || type != AddressType::RANDOM_STATIC) { + return BLE_ERROR_INVALID_PARAM; + } + + if (_privacy_enabled) { + return BLE_ERROR_INVALID_STATE; + } ble_gap_addr_t dev_addr; + memcpy(dev_addr.addr, address, ADDR_LEN); + if (type == AddressType::PUBLIC) { + dev_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; + } else { + dev_addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC; + } - /* When using Public or Static addresses, the cycle mode must be None. - When using Random Private addresses, the cycle mode must be Auto. - In auto mode, the given address is ignored. - */ - if ((type == BLEProtocol::AddressType::PUBLIC) || (type == BLEProtocol::AddressType::RANDOM_STATIC)) - { - memcpy(dev_addr.addr, address, ADDR_LEN); #if (NRF_SD_BLE_API_VERSION <= 2) - cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_NONE; + ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE); #else - privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF; - dev_addr.addr_type = type; + // FIXME is there any reason to use the pm ? + ble_gap_privacy_params_t privacy_params = {0}; + privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF; - ASSERT_INT(ERROR_NONE, pm_id_addr_set(&dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE); - ASSERT_INT(ERROR_NONE, pm_privacy_set(&privacy_params), BLE_ERROR_PARAM_OUT_OF_RANGE); -#endif - } - else if ((type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) || (type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE)) - { -#if (NRF_SD_BLE_API_VERSION <= 2) - cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_AUTO; -#else - privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY; - privacy_params.private_addr_type = type; - - ASSERT_INT(ERROR_NONE, pm_privacy_set(&privacy_params), BLE_ERROR_PARAM_OUT_OF_RANGE); -#endif - // address is ignored when in auto mode - } - else - { - return BLE_ERROR_PARAM_OUT_OF_RANGE; - } - -#if (NRF_SD_BLE_API_VERSION <= 2) - dev_addr.addr_type = type; - ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(cycle_mode, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE); + ASSERT_INT(ERROR_NONE, pm_id_addr_set(&dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE); + ASSERT_INT(ERROR_NONE, pm_privacy_set(&privacy_params), BLE_ERROR_PARAM_OUT_OF_RANGE); #endif return BLE_ERROR_NONE; @@ -597,6 +703,7 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address) ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address) { ble_gap_addr_t dev_addr; + #if (NRF_SD_BLE_API_VERSION <= 2) if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) { #else @@ -606,11 +713,17 @@ ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address) } if (typeP != NULL) { - *typeP = static_cast(dev_addr.addr_type); + if (dev_addr.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC){ + *typeP = BLEProtocol::AddressType::PUBLIC; + } else { + *typeP = BLEProtocol::AddressType::RANDOM; + } } + if (address != NULL) { memcpy(address, dev_addr.addr, ADDR_LEN); } + return BLE_ERROR_NONE; } @@ -939,6 +1052,55 @@ Gap::InitiatorPolicyMode_t nRF5xGap::getInitiatorPolicyMode(void) const return Gap::INIT_POLICY_IGNORE_WHITELIST; } +ble_error_t nRF5xGap::enablePrivacy(bool enable) +{ + if (enable == _privacy_enabled) { + return BLE_ERROR_NONE; + } + + ble_error_t err = BLE_ERROR_UNSPECIFIED; + if (enable == false) { + err = setAddress(_non_private_type, _non_private_address); + } else { + err = getAddress(&_non_private_type, _non_private_address); + } + + if (err) { + return err; + } + + _privacy_enabled = enable; + return BLE_ERROR_NONE; +} + +ble_error_t nRF5xGap::setPeripheralPrivacyConfiguration( + const PeripheralPrivacyConfiguration_t *configuration +) { + _peripheral_privacy_configuration = *configuration; + return BLE_ERROR_NONE; +} + +ble_error_t nRF5xGap::getPeripheralPrivacyConfiguration( + PeripheralPrivacyConfiguration_t *configuration +) { + *configuration = _peripheral_privacy_configuration; + return BLE_ERROR_NONE; +} + +ble_error_t nRF5xGap::setCentralPrivacyConfiguration( + const CentralPrivacyConfiguration_t *configuration +) { + _central_privacy_configuration = *configuration; + return BLE_ERROR_NONE; +} + +ble_error_t nRF5xGap::getCentralPrivacyConfiguration( + CentralPrivacyConfiguration_t *configuration +) { + *configuration = _central_privacy_configuration; + return BLE_ERROR_NONE; +} + #if (NRF_SD_BLE_API_VERSION <= 2) /**************************************************************************/ /*! @@ -1055,38 +1217,6 @@ void nRF5xGap::set_connection_event_handler( _connection_event_handler = connection_event_handler; } -void nRF5xGap::processConnectionEvent( - Handle_t handle, - Role_t role, - BLEProtocol::AddressType_t peerAddrType, - const BLEProtocol::AddressBytes_t peerAddr, - BLEProtocol::AddressType_t ownAddrType, - const BLEProtocol::AddressBytes_t ownAddr, - const ConnectionParams_t *connectionParams -) { - if (_connection_event_handler) { - _connection_event_handler->on_connected( - handle, - role, - peerAddrType, - peerAddr, - ownAddrType, - ownAddr, - connectionParams - ); - } - - ::Gap::processConnectionEvent( - handle, - role, - peerAddrType, - peerAddr, - ownAddrType, - ownAddr, - connectionParams - ); -} - void nRF5xGap::processDisconnectionEvent( Handle_t handle, DisconnectionReason_t reason @@ -1103,3 +1233,155 @@ void nRF5xGap::processDisconnectionEvent( reason ); } + +void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t& evt) { + using BLEProtocol::AddressType; + + // set the new connection handle as the _default_ handle in gap + setConnectionHandle(handle); + + // deal with own address + AddressType_t own_addr_type; + Address_t own_address; + const uint8_t* own_resolvable_address = NULL; + +#if (NRF_SD_BLE_API_VERSION <= 2) + if (evt.own_addr.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC) { + own_addr_type = AddressType::PUBLIC; + } else { + own_addr_type = AddressType::RANDOM; + } + memcpy(own_address, evt.own_addr.addr, sizeof(own_address)); +#else + gap.getAddress(&addr_type, own_address); +#endif + + if (_privacy_enabled) { + own_resolvable_address = own_address; + } + + // deal with the peer address: If privacy is enabled then the softdevice + // indicates if the address has been resolved or not. If the address has + // been resolved then the identity address should be passed to the application. + // Depending on the privacy chosen by the application, connection request + // from privacy enabled peers may trigger a disconnection, the pairing procedure + // or the authentication procedure. + AddressType_t peer_addr_type; + const uint8_t* peer_address; + const uint8_t* peer_resolvable_address; + + if (evt.irk_match) { + const resolving_list_entry_t* entry = get_sm().resolve_address( + evt.peer_addr.addr + ); + MBED_ASSERT(entry == NULL); + + peer_addr_type = convert_identity_address(entry->peer_identity_address_type); + peer_address = entry->peer_identity_address.data(); + peer_resolvable_address = evt.peer_addr.addr; + } else { + if (_privacy_enabled && + evt.role == BLE_GAP_ROLE_PERIPH && + _peripheral_privacy_configuration.resolution_strategy == PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS && + evt.peer_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE && + get_sm().get_resolving_list().size() > 0 + ) { + // FIXME: should use BLE_HCI_AUTHENTICATION_FAILURE; not possible + // with the softdevice ... + sd_ble_gap_disconnect(handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + return; + } + + peer_addr_type = convert_nordic_address(evt.peer_addr.addr_type); + peer_address = evt.peer_addr.addr; + peer_resolvable_address = NULL; + } + + // notify internal event handler before applying the resolution strategy + if (_connection_event_handler) { + _connection_event_handler->on_connected( + handle, + static_cast(evt.role), + peer_addr_type, + peer_address, + own_addr_type, + own_address, + reinterpret_cast(&(evt.conn_params)) + ); + } + + // Apply authentication strategy before application notification + if (!evt.irk_match && + _privacy_enabled && + evt.role == BLE_GAP_ROLE_PERIPH && + evt.peer_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE + ) { + switch (_peripheral_privacy_configuration.resolution_strategy) { + case PeripheralPrivacyConfiguration_t::PERFORM_PAIRING_PROCEDURE: + nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getSecurityManager().requestPairing(handle); + break; + + case PeripheralPrivacyConfiguration_t::PERFORM_AUTHENTICATION_PROCEDURE: + // FIXME: lookup secure DB to know what to do. + break; + + default: + break; + } + } + + processConnectionEvent( + handle, + static_cast(evt.role), + peer_addr_type, + peer_address, + own_addr_type, + own_address, + reinterpret_cast(&(evt.conn_params)), + peer_resolvable_address, + own_resolvable_address + ); +} + +void nRF5xGap::on_advertising_packet(const ble_gap_evt_adv_report_t &evt) { + using BLEProtocol::AddressType; + + AddressType_t peer_addr_type; + const uint8_t* peer_address = evt.peer_addr.addr; + + if (_privacy_enabled && + evt.peer_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE && + _central_privacy_configuration.resolution_strategy != CentralPrivacyConfiguration_t::DO_NOT_RESOLVE + ) { + using ble::pal::vendor::nordic::nRF5xSecurityManager; + + const resolving_list_entry_t* entry = get_sm().resolve_address( + peer_address + ); + + if (entry) { + peer_address = entry->peer_identity_address.data(); + peer_addr_type = convert_identity_address(entry->peer_identity_address_type); + } else if (_central_privacy_configuration.resolution_strategy != CentralPrivacyConfiguration_t::RESOLVE_AND_FORWARD) { + peer_addr_type = convert_nordic_address(evt.peer_addr.addr_type); + } else { + // filter out the packet. + return; + } + } else { + peer_addr_type = convert_nordic_address(evt.peer_addr.addr_type); + } + + processAdvertisementReport( + peer_address, + evt.rssi, + evt.scan_rsp, + static_cast(evt.type), + evt.dlen, + evt.data, + peer_addr_type + ); +} + + + diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h index 9a6973331c..cb12a610f2 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h @@ -122,6 +122,24 @@ public: return BLE_ERROR_UNSPECIFIED; } + virtual ble_error_t enablePrivacy(bool enable); + + virtual ble_error_t setPeripheralPrivacyConfiguration( + const PeripheralPrivacyConfiguration_t *configuration + ); + + virtual ble_error_t getPeripheralPrivacyConfiguration( + PeripheralPrivacyConfiguration_t *configuration + ); + + virtual ble_error_t setCentralPrivacyConfiguration( + const CentralPrivacyConfiguration_t *configuration + ); + + virtual ble_error_t getCentralPrivacyConfiguration( + CentralPrivacyConfiguration_t *configuration + ); + /* Observer role is not supported by S110, return BLE_ERROR_NOT_IMPLEMENTED */ #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); @@ -260,23 +278,10 @@ public: /** @note Implements ConnectionEventMonitor. * @copydoc ConnectionEventMonitor::set_connection_event_handler */ - void set_connection_event_handler( + virtual void set_connection_event_handler( ConnectionEventMonitor::EventHandler* connection_event_handler ); - /** - * @copydoc ::Gap::processConnectionEvent - */ - void processConnectionEvent( - Handle_t handle, - Role_t role, - BLEProtocol::AddressType_t peerAddrType, - const BLEProtocol::AddressBytes_t peerAddr, - BLEProtocol::AddressType_t ownAddrType, - const BLEProtocol::AddressBytes_t ownAddr, - const ConnectionParams_t *connectionParams - ); - /** * @copydoc ::Gap::processDisconnectionEvent */ @@ -285,10 +290,22 @@ public: DisconnectionReason_t reason ); +private: + friend void btle_handler(ble_evt_t *p_ble_evt); + + void on_connection(Handle_t handle, const ble_gap_evt_connected_t& evt); + void on_advertising_packet(const ble_gap_evt_adv_report_t &evt); + uint16_t m_connectionHandle; ConnectionEventMonitor::EventHandler* _connection_event_handler; + bool _privacy_enabled; + PeripheralPrivacyConfiguration_t _peripheral_privacy_configuration; + CentralPrivacyConfiguration_t _central_privacy_configuration; + AddressType_t _non_private_type; + Address_t _non_private_address; + /* * Allow instantiation from nRF5xn when required. */