[NRF52480] fix bugs:

- 128 bits service's UUID discovered by a GATT client was shifted.
- not possible to connect while being scanning.
- not possible to scanning while being connected.
    for sd >= 3 whitelisting is now setups into setWhitelist method
- Gap::setAddress could failed
- Gap::getWhitelist wron implemenation
pull/3841/head
Andrzej Puzdrowski 2017-02-22 15:04:56 +01:00
parent 9f0d754ab6
commit b1e55094aa
5 changed files with 46 additions and 70 deletions

View File

@ -57,7 +57,7 @@ void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
if (sdSingleton.isActive()) {
sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt.params.char_val_by_uuid_read_rsp);
sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt);
}
break;

View File

@ -177,7 +177,7 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams &params)
ble_gap_adv_params_t adv_para = {0};
#if (NRF_SD_BLE_API_VERSION <= 2)
#if (NRF_SD_BLE_API_VERSION <= 2)
/* Allocate the stack's whitelist statically */
ble_gap_whitelist_t whitelist;
ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
@ -197,13 +197,9 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams &params)
}
adv_para.p_whitelist = &whitelist;
#else
err = updateWhiteAndIdentityListInStack(nRF5xGap::purpose_avdvertising);
if (err != BLE_ERROR_NONE) {
return (ble_error_t)err;
}
#endif
/* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */
/* Start Advertising */
@ -254,11 +250,7 @@ ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams)
scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */
scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */
#else
uint32_t err = updateWhiteAndIdentityListInStack(nRF5xGap::purpose_scan_connect);
if (err != BLE_ERROR_NONE) {
return (ble_error_t)err;
}
/* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */
scanParams.use_whitelist = scanningPolicyMode;
scanParams.adv_dir_report = 0;
@ -318,6 +310,7 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr,
const GapScanningParams *scanParamsIn)
{
ble_gap_addr_t addr;
addr.addr_type = peerAddrType;
memcpy(addr.addr, peerAddr, Gap::ADDR_LEN);
@ -358,11 +351,7 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr,
scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */
scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */
#else
uint32_t err = updateWhiteAndIdentityListInStack(nRF5xGap::purpose_scan_connect);
if (err != BLE_ERROR_NONE) {
return (ble_error_t)err;
}
/* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */
scanParams.use_whitelist = (whitelistAddressesSize) ? 1 : 0;
@ -504,6 +493,7 @@ ble_error_t nRF5xGap::reset(void)
/* Clear the internal whitelist */
whitelistAddressesSize = 0;
return BLE_ERROR_NONE;
}
@ -566,6 +556,7 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_NONE;
#else
privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF;
dev_addr.addr_type = type;
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);
@ -588,8 +579,8 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
dev_addr.addr_type = type;
#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);
#endif
@ -731,10 +722,10 @@ uint8_t nRF5xGap::getMaxWhitelistSize(void) const
/**************************************************************************/
ble_error_t nRF5xGap::getWhitelist(Gap::Whitelist_t &whitelistOut) const
{
uint8_t i;
uint32_t i;
for (i = 0; i < whitelistAddressesSize && i < whitelistOut.capacity; ++i) {
memcpy( &whitelistOut.addresses[i].address, &whitelistAddresses[whitelistAddressesSize].addr, sizeof(whitelistOut.addresses[i].address));
whitelistOut.addresses[i].type = static_cast<BLEProtocol::AddressType_t> (whitelistAddresses[whitelistAddressesSize].addr_type);
memcpy( &whitelistOut.addresses[i].address, &whitelistAddresses[i].addr, sizeof(whitelistOut.addresses[0].address));
whitelistOut.addresses[i].type = static_cast<BLEProtocol::AddressType_t> (whitelistAddresses[i].addr_type);
}
@ -780,20 +771,24 @@ ble_error_t nRF5xGap::setWhitelist(const Gap::Whitelist_t &whitelistIn)
}
/* Test for invalid parameters before we change the internal state */
for (uint8_t i = 0; i < whitelistIn.size; ++i) {
for (uint32_t i = 0; i < whitelistIn.size; ++i) {
if (whitelistIn.addresses[i].type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
/* This is not allowed because it is completely meaningless */
return BLE_ERROR_INVALID_PARAM;
}
}
whitelistAddressesSize = 0;
for (uint8_t i = 0; i < whitelistIn.size; ++i) {
memcpy(&whitelistAddresses[whitelistAddressesSize].addr , &whitelistIn.addresses[i].address , sizeof(whitelistAddresses[whitelistAddressesSize].addr));
whitelistAddresses[whitelistAddressesSize].addr_type = static_cast<uint8_t> (whitelistIn.addresses[i].type);
whitelistAddressesSize++;
whitelistAddressesSize = whitelistIn.size;
for (uint32_t i = 0; i < whitelistIn.size; ++i) {
memcpy(&whitelistAddresses[i].addr , &whitelistIn.addresses[i].address , sizeof(whitelistAddresses[0].addr));
whitelistAddresses[i].addr_type = static_cast<uint8_t> (whitelistIn.addresses[i].type);
}
#if (NRF_SD_BLE_API_VERSION >= 3)
updateWhiteAndIdentityListInStack();
#endif
return BLE_ERROR_NONE;
}
@ -1183,32 +1178,17 @@ ble_error_t nRF5xGap::applyWhiteIdentityList(GapWhiteAndIdentityList_t &gapAdrHe
}
}
ble_error_t nRF5xGap::updateWhiteAndIdentityListInStack(whiteAndIdentityListPurpose_t purpose)
ble_error_t nRF5xGap::updateWhiteAndIdentityListInStack()
{
GapWhiteAndIdentityList_t whiteAndIdentityList;
uint32_t err;
bool provide_settings;
if (purpose == nRF5xGap::purpose_avdvertising) {
provide_settings = (advertisingPolicyMode != Gap::ADV_POLICY_IGNORE_WHITELIST) ? true : false;
} else { //It must be nRF5xGap::purpose_scan_connect.
provide_settings = (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) ? true : false;
}
uint32_t err;
/* Add missing IRKs to nRF5xGap's whitelist from the bond table held by the Peer Manager */
if (provide_settings) {
err = getStackWhiteIdentityList(whiteAndIdentityList);
err = getStackWhiteIdentityList(whiteAndIdentityList);
if (err != BLE_ERROR_NONE) {
return (ble_error_t)err;
}
} else {
whiteAndIdentityList.addrs_cnt = 0;
whiteAndIdentityList.identities_cnt = 0;
if (err != BLE_ERROR_NONE) {
return (ble_error_t)err;
}
return applyWhiteIdentityList(whiteAndIdentityList);
}
#endif

View File

@ -160,13 +160,6 @@ private:
uint32_t identities_cnt;
} GapWhiteAndIdentityList_t;
/* purpose of updating the whitelist and identities settings. */
enum whiteAndIdentityListPurpose_t
{
purpose_scan_connect = 0,
purpose_avdvertising
} whiteAndIdentityListPurpose;
/* Function for preparing setting of the whitelist feature and the identity-resolving feature (privacy).*/
ble_error_t getStackWhiteIdentityList(GapWhiteAndIdentityList_t &whiteAndIdentityList);
@ -175,9 +168,8 @@ private:
/* Function for introducing whitelist feature and the identity-resolving feature setting into SoftDevice.
*
* Introduced settings are comply which scanning or advertising policies.
* This function incorporates getStackWhiteIdentityList and applyWhiteIdentityList together. */
ble_error_t updateWhiteAndIdentityListInStack(whiteAndIdentityListPurpose_t purpose);
ble_error_t updateWhiteAndIdentityListInStack(void);
#endif
private:

View File

@ -236,6 +236,7 @@ nRF5xServiceDiscovery::ServiceUUIDDiscoveryQueue::triggerFirst(void)
.start_handle = parentDiscoveryObject->services[serviceIndex].getStartHandle(),
.end_handle = parentDiscoveryObject->services[serviceIndex].getEndHandle(),
};
if (sd_ble_gattc_char_value_by_uuid_read(parentDiscoveryObject->connHandle, &uuid, &handleRange) == NRF_SUCCESS) {
return;
}
@ -281,19 +282,22 @@ nRF5xServiceDiscovery::CharUUIDDiscoveryQueue::triggerFirst(void)
}
void
nRF5xServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response)
nRF5xServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_t *p_gattc_evt)
{
const ble_gattc_evt_char_val_by_uuid_read_rsp_t * response = &p_gattc_evt->params.char_val_by_uuid_read_rsp;
if (state == DISCOVER_SERVICE_UUIDS) {
if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID)) {
UUID::LongUUIDBytes_t uuid;
#if (NRF_SD_BLE_API_VERSION >= 3)
ble_gattc_handle_value_t iter;
memset(&iter, 0, sizeof(ble_gattc_handle_value_t));
(void) sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter((ble_gattc_evt_t*)response, &iter);
memcpy(uuid, iter.p_value, UUID::LENGTH_OF_LONG_UUID);
/* SoftDevice API since 3.0.0 (e.g. sd 140 5.0.0-1.alpha) provide sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter() helper function,
* but it's not reliable for c++ build.
* Instead of it memcpy gets proper response's value field by offset from handle-value pair: [2 B handle|16 B value=uuid_128b] */
memcpy(uuid, (&response->handle_value + 2), UUID::LENGTH_OF_LONG_UUID);
#else
memcpy(uuid, response->handle_value[0].p_value, UUID::LENGTH_OF_LONG_UUID);
memcpy(uuid, &(response->handle_value[0].p_value[0]), UUID::LENGTH_OF_LONG_UUID);
#endif
unsigned serviceIndex = serviceUUIDDiscoveryQueue.dequeue();
@ -307,11 +311,11 @@ nRF5xServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_char_val_
if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID + 1 /* props */ + 2 /* value handle */)) {
UUID::LongUUIDBytes_t uuid;
#if (NRF_SD_BLE_API_VERSION >= 3)
ble_gattc_handle_value_t iter;
memset(&iter, 0, sizeof(ble_gattc_handle_value_t));
(void) sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter((ble_gattc_evt_t*)response, &iter);
memcpy(uuid, &(iter.p_value[3]), UUID::LENGTH_OF_LONG_UUID);
#if (NRF_SD_BLE_API_VERSION >= 3)
/* SoftDevice API since 3.0.0 (e.g. sd 140 5.0.0-1.alpha) provide sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter() helper function,
* but it's not reliable for c++ build.
* Instead of it memcpy gets proper response's value by offset: [2 B type| 1B prop |2 B value handle| 16 B value=uuid_128b] */
memcpy(uuid, (&response->handle_value + 5), UUID::LENGTH_OF_LONG_UUID);
#else
memcpy(uuid, &(response->handle_value[0].p_value[3]), UUID::LENGTH_OF_LONG_UUID);
#endif

View File

@ -139,7 +139,7 @@ private:
void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response);
void triggerServiceUUIDDiscovery(void);
void processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response);
void processDiscoverUUIDResponse(const ble_gattc_evt_t *p_gattc_evt);
void removeFirstServiceNeedingUUIDDiscovery(void);
void terminateServiceDiscovery(void) {