From 57ffa14b4baa6c6eaaf8e3a77d1e0dda83774abf Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Mon, 21 May 2018 13:21:46 +0100 Subject: [PATCH] Nordic BLE: Backport privacy backward compatibility to NRF51 --- .../TARGET_NRF51/source/nRF5xGap.cpp | 409 ++++++++---------- .../TARGET_NRF51/source/nRF5xGap.h | 36 +- 2 files changed, 186 insertions(+), 259 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF51/source/nRF5xGap.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF51/source/nRF5xGap.cpp index 9c3566625a..d6dfb883cf 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF51/source/nRF5xGap.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF51/source/nRF5xGap.cpp @@ -32,6 +32,10 @@ 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; +using ble::peer_address_type_t; + +typedef BLEProtocol::AddressType LegacyAddressType; +typedef BLEProtocol::AddressType_t LegacyAddressType_t; namespace { @@ -39,14 +43,16 @@ nRF5xSecurityManager& get_sm() { return nRF5xSecurityManager::get_security_manager(); } -void set_private_resolvable_address() { +ble_error_t 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); + uint32_t err = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &addr); + return err ? BLE_ERROR_UNSPECIFIED : BLE_ERROR_NONE; } -void set_private_non_resolvable_address() { +ble_error_t 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); + uint32_t err = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &addr); + return err ? BLE_ERROR_UNSPECIFIED : BLE_ERROR_NONE; } bool is_advertising_non_connectable(const GapAdvertisingParams ¶ms) { @@ -59,29 +65,24 @@ bool is_advertising_non_connectable(const GapAdvertisingParams ¶ms) { } } -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; - } +bool is_identity_address(peer_address_type_t address_type) { + return address_type == peer_address_type_t::PUBLIC_IDENTITY || + address_type == peer_address_type_t::RANDOM_STATIC_IDENTITY; } -BLEProtocol::AddressType_t convert_nordic_address(uint8_t address) { +peer_address_type_t convert_nordic_address(uint8_t address) { if (address == BLE_GAP_ADDR_TYPE_PUBLIC) { - return BLEProtocol::AddressType::PUBLIC; + return peer_address_type_t::PUBLIC; } else { - return BLEProtocol::AddressType::RANDOM; + return peer_address_type_t::RANDOM; } } -BLEProtocol::AddressType_t convert_identity_address(advertising_peer_address_type_t address) { +peer_address_type_t convert_identity_address(advertising_peer_address_type_t address) { if (address == advertising_peer_address_type_t::PUBLIC_ADDRESS) { - return BLEProtocol::AddressType::PUBLIC_IDENTITY; + return peer_address_type_t::PUBLIC_IDENTITY; } else { - return BLEProtocol::AddressType::RANDOM_STATIC_IDENTITY; + return peer_address_type_t::RANDOM_STATIC_IDENTITY; } } @@ -103,7 +104,7 @@ nRF5xGap::nRF5xGap() : Gap(), _privacy_enabled(false), _peripheral_privacy_configuration(default_peripheral_privacy_configuration), _central_privacy_configuration(default_central_privacy_configuration), - _non_private_type(BLEProtocol::AddressType::RANDOM) + _non_private_address_type(LegacyAddressType::RANDOM_STATIC) { m_connectionHandle = BLE_CONN_HANDLE_INVALID; } @@ -259,12 +260,10 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms) whitelist.addr_count = 0; whitelist.irk_count = 0; - /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */ - if (advertisingPolicyMode != Gap::ADV_POLICY_IGNORE_WHITELIST) { - ble_error_t error = generateStackWhitelist(whitelist); - if (error != BLE_ERROR_NONE) { - return error; - } + whitelist.addr_count = whitelistAddressesSize; + + for (uint32_t i = 0; i < whitelistAddressesSize; ++i) { + whitelistAddressPtrs[i] = &whitelistAddresses[i]; } if (_privacy_enabled) { @@ -295,15 +294,12 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms) /* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */ /* Start Advertising */ - - adv_para.type = params.getAdvertisingType(); adv_para.p_peer_addr = NULL; // Undirected advertisement adv_para.fp = advertisingPolicyMode; adv_para.interval = params.getIntervalInADVUnits(); // advertising interval (in units of 0.625 ms) adv_para.timeout = params.getTimeout(); - err = sd_ble_gap_adv_start(&adv_para); switch(err) { case ERROR_NONE: @@ -319,7 +315,6 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms) #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams) { - ble_gap_scan_params_t scanParams; #if (NRF_SD_BLE_API_VERSION <= 2) @@ -333,15 +328,26 @@ ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams) whitelist.addr_count = 0; whitelist.irk_count = 0; - /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */ - if (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) { - ble_error_t error = generateStackWhitelist(whitelist); - if (error != BLE_ERROR_NONE) { - return error; - } + whitelist.addr_count = whitelistAddressesSize; + + for (uint32_t i = 0; i < whitelistAddressesSize; ++i) { + whitelistAddressPtrs[i] = &whitelistAddresses[i]; } - // FIXME: fill the irk list once addresses are resolved by the softdevice. + if (_privacy_enabled) { + if (_central_privacy_configuration.resolution_strategy != CentralPrivacyConfiguration_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; + } + } scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */ scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */ @@ -408,11 +414,59 @@ ble_error_t nRF5xGap::stopAdvertising(void) return BLE_ERROR_NONE; } -ble_error_t nRF5xGap::connect(const Address_t peerAddr, - BLEProtocol::AddressType_t peerAddrType, - const ConnectionParams_t *connectionParams, - const GapScanningParams *scanParamsIn) -{ +ble_error_t nRF5xGap::connect( + const Address_t peerAddr, + peer_address_type_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParamsIn +) { + // NOTE: Nordic address type is an closer to LegacyAddressType: resolved + // address are treaded either as PUBLIC or RANDOM STATIC adresses. + // The idea is to get the conversion done here and call the legacy function. + + LegacyAddressType_t legacy_address; + + switch (peerAddrType.value()) { + case peer_address_type_t::PUBLIC: + case peer_address_type_t::PUBLIC_IDENTITY: + legacy_address = LegacyAddressType::PUBLIC; + break; + case peer_address_type_t::RANDOM_STATIC_IDENTITY: + legacy_address = LegacyAddressType::RANDOM_STATIC; + break; + case peer_address_type_t::RANDOM: { + RandomAddressType_t random_address_type(RandomAddressType_t::STATIC); + ble_error_t err = getRandomAddressType(peerAddr, &random_address_type); + if (err) { + return err; + } + switch (random_address_type.value()) { + case RandomAddressType_t::STATIC: + legacy_address = LegacyAddressType::RANDOM_STATIC; + break; + case RandomAddressType_t::NON_RESOLVABLE_PRIVATE: + legacy_address = LegacyAddressType::RANDOM_PRIVATE_NON_RESOLVABLE; + break; + case RandomAddressType_t::RESOLVABLE_PRIVATE: + legacy_address = LegacyAddressType::RANDOM_PRIVATE_RESOLVABLE; + break; + default: + return BLE_ERROR_UNSPECIFIED; + } + } break; + default: + return BLE_ERROR_INVALID_PARAM; + } + + return connect(peerAddr, legacy_address, connectionParams, scanParamsIn); +} + +ble_error_t nRF5xGap::connect( + const Address_t peerAddr, + LegacyAddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParamsIn +) { ble_gap_addr_t addr; ble_gap_addr_t* addr_ptr = &addr; addr.addr_type = peerAddrType; @@ -444,40 +498,21 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr, whitelist.addr_count = 0; whitelist.irk_count = 0; - /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */ - if (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) { - ble_error_t error = generateStackWhitelist(whitelist); - if (error != BLE_ERROR_NONE) { - 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)) { + if (_central_privacy_configuration.resolution_strategy != CentralPrivacyConfiguration_t::DO_NOT_RESOLVE) { 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; + size_t limit = std::min( + entries.size(), (size_t) YOTTA_CFG_IRK_TABLE_MAX_SIZE + ); - // 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; + for (size_t i = 0; i < limit; ++i) { + whitelistIrkPtrs[i] = (ble_gap_irk_t*) entries[i].peer_irk.data(); } + whitelist.irk_count = limit; } set_private_resolvable_address(); @@ -666,11 +701,11 @@ uint16_t nRF5xGap::getConnectionHandle(void) @endcode */ /**************************************************************************/ -ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address) +ble_error_t nRF5xGap::setAddress(LegacyAddressType_t type, const Address_t address) { - using BLEProtocol::AddressType; - - if (type != AddressType::PUBLIC || type != AddressType::RANDOM_STATIC) { + if (type != LegacyAddressType::PUBLIC && + type != LegacyAddressType::RANDOM_STATIC + ) { return BLE_ERROR_INVALID_PARAM; } @@ -680,30 +715,41 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address) ble_gap_addr_t dev_addr; memcpy(dev_addr.addr, address, ADDR_LEN); - if (type == AddressType::PUBLIC) { + if (type == LegacyAddressType::PUBLIC) { dev_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; } else { dev_addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC; } #if (NRF_SD_BLE_API_VERSION <= 2) - ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE); + uint32_t err = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &dev_addr); #else - // 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); + uint32_t err = sd_ble_gap_addr_set(&dev_addr); #endif - return BLE_ERROR_NONE; + switch (err) { + case NRF_SUCCESS: + return BLE_ERROR_NONE; + case NRF_ERROR_INVALID_ADDR: + return BLE_ERROR_INVALID_PARAM; + case BLE_ERROR_GAP_INVALID_BLE_ADDR: + return BLE_ERROR_PARAM_OUT_OF_RANGE; + case NRF_ERROR_BUSY: + return BLE_STACK_BUSY; + case NRF_ERROR_INVALID_STATE: + return BLE_ERROR_INVALID_STATE; + default: + return BLE_ERROR_UNSPECIFIED; + } } ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address) { - ble_gap_addr_t dev_addr; + if (typeP == NULL || address == NULL) { + return BLE_ERROR_INVALID_PARAM; + } + ble_gap_addr_t dev_addr; #if (NRF_SD_BLE_API_VERSION <= 2) if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) { #else @@ -712,17 +758,20 @@ ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address) return BLE_ERROR_PARAM_OUT_OF_RANGE; } - if (typeP != NULL) { - if (dev_addr.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC){ - *typeP = BLEProtocol::AddressType::PUBLIC; - } else { - *typeP = BLEProtocol::AddressType::RANDOM; - } + switch (dev_addr.addr_type) { + case BLE_GAP_ADDR_TYPE_PUBLIC: + *typeP = LegacyAddressType::PUBLIC; + break; + + case BLE_GAP_ADDR_TYPE_RANDOM_STATIC: + *typeP = LegacyAddressType::RANDOM_STATIC; + break; + + default: + return BLE_ERROR_INVALID_STATE; } - if (address != NULL) { - memcpy(address, dev_addr.addr, ADDR_LEN); - } + memcpy(address, dev_addr.addr, ADDR_LEN); return BLE_ERROR_NONE; } @@ -849,9 +898,7 @@ ble_error_t nRF5xGap::getWhitelist(Gap::Whitelist_t &whitelistOut) const uint32_t i; for (i = 0; i < whitelistAddressesSize && i < whitelistOut.capacity; ++i) { memcpy( &whitelistOut.addresses[i].address, &whitelistAddresses[i].addr, sizeof(whitelistOut.addresses[0].address)); - whitelistOut.addresses[i].type = static_cast (whitelistAddresses[i].addr_type); - - + whitelistOut.addresses[i].type = static_cast (whitelistAddresses[i].addr_type); } whitelistOut.size = i; @@ -896,7 +943,9 @@ ble_error_t nRF5xGap::setWhitelist(const Gap::Whitelist_t &whitelistIn) /* Test for invalid parameters before we change the internal state */ for (uint32_t i = 0; i < whitelistIn.size; ++i) { - if (whitelistIn.addresses[i].type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { + if (whitelistIn.addresses[i].type == LegacyAddressType::RANDOM_PRIVATE_NON_RESOLVABLE || + whitelistIn.addresses[i].type == LegacyAddressType::RANDOM_PRIVATE_RESOLVABLE + ) { /* This is not allowed because it is completely meaningless */ return BLE_ERROR_INVALID_PARAM; } @@ -1052,24 +1101,38 @@ Gap::InitiatorPolicyMode_t nRF5xGap::getInitiatorPolicyMode(void) const return Gap::INIT_POLICY_IGNORE_WHITELIST; } -ble_error_t nRF5xGap::enablePrivacy(bool enable) +ble_error_t nRF5xGap::enablePrivacy(bool enable_privacy) { - if (enable == _privacy_enabled) { + if (enable_privacy == _privacy_enabled) { return BLE_ERROR_NONE; } ble_error_t err = BLE_ERROR_UNSPECIFIED; - if (enable == false) { - err = setAddress(_non_private_type, _non_private_address); + if (enable_privacy == false) { + err = setAddress(_non_private_address_type, _non_private_address); } else { - err = getAddress(&_non_private_type, _non_private_address); + err = getAddress(&_non_private_address_type, _non_private_address); } if (err) { return err; } - _privacy_enabled = enable; +#if (NRF_SD_BLE_API_VERSION > 2) + ble_gap_privacy_params_t privacy_config = { 0 }; + if (sd_ble_gap_privacy_get(&privacy_config)) { + return BLE_ERROR_UNSPECIFIED; + } + + privacy_config.privacy_mode = enable_privacy ? + BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY : + BLE_GAP_PRIVACY_MODE_OFF; + if (sd_ble_gap_privacy_set(&privacy_config)) { + return BLE_ERROR_UNSPECIFIED; + } +#endif + + _privacy_enabled = enable_privacy; return BLE_ERROR_NONE; } @@ -1101,116 +1164,6 @@ ble_error_t nRF5xGap::getCentralPrivacyConfiguration( return BLE_ERROR_NONE; } -#if (NRF_SD_BLE_API_VERSION <= 2) -/**************************************************************************/ -/*! - @brief Helper function used to populate the ble_gap_whitelist_t that - will be used by the SoftDevice for filtering requests. - @returns \ref ble_error_t - @retval BLE_ERROR_NONE - Everything executed properly - @retval BLE_ERROR_INVALID_STATE - The internal stack was not initialized correctly. - @note Both the SecurityManager and Gap must initialize correctly for - this function to succeed. - @note This function is needed because for the BLE API the whitelist - is just a collection of keys, but for the stack it also includes - the IRK table. - @section EXAMPLE - @code - @endcode -*/ -/**************************************************************************/ -ble_error_t nRF5xGap::generateStackWhitelist(ble_gap_whitelist_t &whitelist) -{ - return BLE_ERROR_NOT_IMPLEMENTED; -} -#endif - -#if (NRF_SD_BLE_API_VERSION >= 3) - -/** - * Function for preparing settings of the whitelist feature and the identity-resolving feature (privacy) for the SoftDevice. - * - * Gap::setWhitelist provides the base for preparation of these settings. - * This function matches resolvable addresses (passed by Gap::setWhitelist) to IRK data in bonds table. - * Therefore resolvable addresses instead of being passed to the whitelist (intended to be passed to the Softdevice) - * are passed to the identities list (intended to be passed to the Softdevice). - * - * @param[out] gapAdrHelper Reference to the struct for storing settings. - */ - -ble_error_t nRF5xGap::getStackWhiteIdentityList(GapWhiteAndIdentityList_t &gapAdrHelper) -{ - BLE_ERROR_NOT_IMPLEMENTED; -} - -ble_error_t nRF5xGap::applyWhiteIdentityList(GapWhiteAndIdentityList_t &gapAdrHelper) -{ - uint32_t retc; - - if (gapAdrHelper.identities_cnt == 0) { - retc = sd_ble_gap_device_identities_set(NULL, NULL, 0); - } else { - ble_gap_id_key_t * pp_identities[YOTTA_CFG_IRK_TABLE_MAX_SIZE]; - - for (uint32_t i = 0; i < gapAdrHelper.identities_cnt; ++i) - { - pp_identities[i] = &gapAdrHelper.identities[i]; - } - - retc = sd_ble_gap_device_identities_set(pp_identities, NULL /* Don't use local IRKs*/,gapAdrHelper.identities_cnt); - } - - if (retc == NRF_SUCCESS) { - if (gapAdrHelper.addrs_cnt == 0) { - retc = sd_ble_gap_whitelist_set(NULL, 0); - } else { - ble_gap_addr_t * pp_addrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE]; - - for (uint32_t i = 0; i < gapAdrHelper.addrs_cnt; ++i) - { - pp_addrs[i] = &gapAdrHelper.addrs[i]; - } - - retc = sd_ble_gap_whitelist_set(pp_addrs, gapAdrHelper.addrs_cnt); - } - } - - switch(retc) { - case NRF_SUCCESS: - return BLE_ERROR_NONE; - - case BLE_ERROR_GAP_WHITELIST_IN_USE: //The whitelist is in use by a BLE role and cannot be set or cleared. - case BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE: //The device identity list is in use and cannot be set or cleared. - return BLE_ERROR_ALREADY_INITIALIZED; - - case NRF_ERROR_INVALID_ADDR: - case BLE_ERROR_GAP_INVALID_BLE_ADDR: //Invalid address type is supplied. - case NRF_ERROR_DATA_SIZE: - case BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE: //The device identity list contains multiple entries with the same identity address. - return BLE_ERROR_INVALID_PARAM; - - default: - return BLE_ERROR_UNSPECIFIED; - } -} - -ble_error_t nRF5xGap::updateWhiteAndIdentityListInStack() -{ - GapWhiteAndIdentityList_t whiteAndIdentityList; - uint32_t err; - - err = getStackWhiteIdentityList(whiteAndIdentityList); - - if (err != BLE_ERROR_NONE) { - return (ble_error_t)err; - } - - return applyWhiteIdentityList(whiteAndIdentityList); -} -#endif - void nRF5xGap::set_connection_event_handler( ConnectionEventMonitor::EventHandler* connection_event_handler ) { @@ -1241,36 +1194,44 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t setConnectionHandle(handle); // deal with own address - AddressType_t own_addr_type; + LegacyAddressType_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; + if (_privacy_enabled) { + own_addr_type = LegacyAddressType::RANDOM_PRIVATE_RESOLVABLE; } else { - own_addr_type = AddressType::RANDOM; + if (evt.own_addr.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC) { + own_addr_type = LegacyAddressType::PUBLIC; + } else { + own_addr_type = LegacyAddressType::RANDOM_STATIC; + } } + + // FIXME: is it the resolvable address or the identity address ? 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; + peer_address_type_t peer_addr_type(peer_address_type_t::PUBLIC); const uint8_t* peer_address; const uint8_t* peer_resolvable_address; - if (evt.irk_match) { +#if (NRF_SD_BLE_API_VERSION <= 2) + bool private_peer_known = evt.irk_match; +#else + bool private_peer_known = evt.peer_addr.addr_id_peer; +#endif + + if (private_peer_known) { const resolving_list_entry_t* entry = get_sm().resolve_address( evt.peer_addr.addr ); @@ -1311,14 +1272,14 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t } // Apply authentication strategy before application notification - if (!evt.irk_match && + if (!private_peer_known && _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); + nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getSecurityManager().requestAuthentication(handle); break; case PeripheralPrivacyConfiguration_t::PERFORM_AUTHENTICATION_PROCEDURE: @@ -1344,9 +1305,7 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t } void nRF5xGap::on_advertising_packet(const ble_gap_evt_adv_report_t &evt) { - using BLEProtocol::AddressType; - - AddressType_t peer_addr_type; + peer_address_type_t peer_addr_type(peer_address_type_t::PUBLIC); const uint8_t* peer_address = evt.peer_addr.addr; if (_privacy_enabled && diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF51/source/nRF5xGap.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF51/source/nRF5xGap.h index cb12a610f2..d595de6278 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF51/source/nRF5xGap.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF51/source/nRF5xGap.h @@ -78,6 +78,7 @@ public: virtual ble_error_t startAdvertising(const GapAdvertisingParams &); virtual ble_error_t stopAdvertising(void); + virtual ble_error_t connect(const Address_t, ble::peer_address_type_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams); virtual ble_error_t connect(const Address_t, BLEProtocol::AddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams); virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); virtual ble_error_t disconnect(DisconnectionReason_t reason); @@ -159,39 +160,6 @@ private: uint8_t whitelistAddressesSize; ble_gap_addr_t whitelistAddresses[YOTTA_CFG_WHITELIST_MAX_SIZE]; -#if (NRF_SD_BLE_API_VERSION <= 2) - /* - * An internal function used to populate the ble_gap_whitelist_t that will be used by - * the SoftDevice for filtering requests. This function is needed because for the BLE - * API the whitelist is just a collection of keys, but for the stack it also includes - * the IRK table. - */ - ble_error_t generateStackWhitelist(ble_gap_whitelist_t &whitelist); -#endif - -#if (NRF_SD_BLE_API_VERSION >= 3) - /* internal type for passing a whitelist and a identities list. */ - typedef struct - { - ble_gap_addr_t addrs[YOTTA_CFG_WHITELIST_MAX_SIZE]; - uint32_t addrs_cnt; - - ble_gap_id_key_t identities[YOTTA_CFG_IRK_TABLE_MAX_SIZE]; - uint32_t identities_cnt; - } GapWhiteAndIdentityList_t; - - /* Function for preparing setting of the whitelist feature and the identity-resolving feature (privacy).*/ - ble_error_t getStackWhiteIdentityList(GapWhiteAndIdentityList_t &whiteAndIdentityList); - - /* Function for applying setting of the whitelist feature and identity-resolving feature (privacy).*/ - ble_error_t applyWhiteIdentityList(GapWhiteAndIdentityList_t &whiteAndIdentityList); - - /* Function for introducing whitelist feature and the identity-resolving feature setting into SoftDevice. - * - * This function incorporates getStackWhiteIdentityList and applyWhiteIdentityList together. */ - ble_error_t updateWhiteAndIdentityListInStack(void); -#endif - private: bool radioNotificationCallbackParam; /* parameter to be passed into the Timeout-generated radio notification callback. */ Timeout radioNotificationTimeout; @@ -303,7 +271,7 @@ private: bool _privacy_enabled; PeripheralPrivacyConfiguration_t _peripheral_privacy_configuration; CentralPrivacyConfiguration_t _central_privacy_configuration; - AddressType_t _non_private_type; + AddressType_t _non_private_address_type; Address_t _non_private_address; /*