Skip to content

Commit febf63b

Browse files
nvlsianpuadbridge
authored andcommitted
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
1 parent c4e6c0e commit febf63b

File tree

5 files changed

+46
-70
lines changed

5 files changed

+46
-70
lines changed

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5_SDK13/source/btle/btle_discovery.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
5757

5858
case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
5959
if (sdSingleton.isActive()) {
60-
sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt.params.char_val_by_uuid_read_rsp);
60+
sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt);
6161
}
6262
break;
6363

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5_SDK13/source/nRF5xGap.cpp

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams &params)
177177

178178
ble_gap_adv_params_t adv_para = {0};
179179

180-
#if (NRF_SD_BLE_API_VERSION <= 2)
180+
#if (NRF_SD_BLE_API_VERSION <= 2)
181181
/* Allocate the stack's whitelist statically */
182182
ble_gap_whitelist_t whitelist;
183183
ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
@@ -197,13 +197,9 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams &params)
197197
}
198198

199199
adv_para.p_whitelist = &whitelist;
200-
#else
201-
err = updateWhiteAndIdentityListInStack(nRF5xGap::purpose_avdvertising);
202-
203-
if (err != BLE_ERROR_NONE) {
204-
return (ble_error_t)err;
205-
}
206200
#endif
201+
/* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */
202+
207203
/* Start Advertising */
208204

209205

@@ -254,11 +250,7 @@ ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams)
254250
scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */
255251
scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */
256252
#else
257-
uint32_t err = updateWhiteAndIdentityListInStack(nRF5xGap::purpose_scan_connect);
258-
259-
if (err != BLE_ERROR_NONE) {
260-
return (ble_error_t)err;
261-
}
253+
/* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */
262254

263255
scanParams.use_whitelist = scanningPolicyMode;
264256
scanParams.adv_dir_report = 0;
@@ -318,6 +310,7 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr,
318310
const GapScanningParams *scanParamsIn)
319311
{
320312
ble_gap_addr_t addr;
313+
321314
addr.addr_type = peerAddrType;
322315
memcpy(addr.addr, peerAddr, Gap::ADDR_LEN);
323316

@@ -358,11 +351,7 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr,
358351
scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */
359352
scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */
360353
#else
361-
uint32_t err = updateWhiteAndIdentityListInStack(nRF5xGap::purpose_scan_connect);
362-
363-
if (err != BLE_ERROR_NONE) {
364-
return (ble_error_t)err;
365-
}
354+
/* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */
366355

367356
scanParams.use_whitelist = (whitelistAddressesSize) ? 1 : 0;
368357

@@ -504,6 +493,7 @@ ble_error_t nRF5xGap::reset(void)
504493

505494
/* Clear the internal whitelist */
506495
whitelistAddressesSize = 0;
496+
507497

508498
return BLE_ERROR_NONE;
509499
}
@@ -566,6 +556,7 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
566556
cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_NONE;
567557
#else
568558
privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF;
559+
dev_addr.addr_type = type;
569560

570561
ASSERT_INT(ERROR_NONE, pm_id_addr_set(&dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE);
571562
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)
588579
return BLE_ERROR_PARAM_OUT_OF_RANGE;
589580
}
590581

591-
dev_addr.addr_type = type;
592582
#if (NRF_SD_BLE_API_VERSION <= 2)
583+
dev_addr.addr_type = type;
593584
ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(cycle_mode, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE);
594585
#endif
595586

@@ -731,10 +722,10 @@ uint8_t nRF5xGap::getMaxWhitelistSize(void) const
731722
/**************************************************************************/
732723
ble_error_t nRF5xGap::getWhitelist(Gap::Whitelist_t &whitelistOut) const
733724
{
734-
uint8_t i;
725+
uint32_t i;
735726
for (i = 0; i < whitelistAddressesSize && i < whitelistOut.capacity; ++i) {
736-
memcpy( &whitelistOut.addresses[i].address, &whitelistAddresses[whitelistAddressesSize].addr, sizeof(whitelistOut.addresses[i].address));
737-
whitelistOut.addresses[i].type = static_cast<BLEProtocol::AddressType_t> (whitelistAddresses[whitelistAddressesSize].addr_type);
727+
memcpy( &whitelistOut.addresses[i].address, &whitelistAddresses[i].addr, sizeof(whitelistOut.addresses[0].address));
728+
whitelistOut.addresses[i].type = static_cast<BLEProtocol::AddressType_t> (whitelistAddresses[i].addr_type);
738729

739730

740731
}
@@ -780,20 +771,24 @@ ble_error_t nRF5xGap::setWhitelist(const Gap::Whitelist_t &whitelistIn)
780771
}
781772

782773
/* Test for invalid parameters before we change the internal state */
783-
for (uint8_t i = 0; i < whitelistIn.size; ++i) {
774+
for (uint32_t i = 0; i < whitelistIn.size; ++i) {
784775
if (whitelistIn.addresses[i].type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
785776
/* This is not allowed because it is completely meaningless */
786777
return BLE_ERROR_INVALID_PARAM;
787778
}
788779
}
789780

790-
whitelistAddressesSize = 0;
791-
for (uint8_t i = 0; i < whitelistIn.size; ++i) {
792-
memcpy(&whitelistAddresses[whitelistAddressesSize].addr , &whitelistIn.addresses[i].address , sizeof(whitelistAddresses[whitelistAddressesSize].addr));
793-
whitelistAddresses[whitelistAddressesSize].addr_type = static_cast<uint8_t> (whitelistIn.addresses[i].type);
794-
whitelistAddressesSize++;
781+
whitelistAddressesSize = whitelistIn.size;
782+
783+
for (uint32_t i = 0; i < whitelistIn.size; ++i) {
784+
memcpy(&whitelistAddresses[i].addr , &whitelistIn.addresses[i].address , sizeof(whitelistAddresses[0].addr));
785+
whitelistAddresses[i].addr_type = static_cast<uint8_t> (whitelistIn.addresses[i].type);
795786
}
796787

788+
#if (NRF_SD_BLE_API_VERSION >= 3)
789+
updateWhiteAndIdentityListInStack();
790+
#endif
791+
797792
return BLE_ERROR_NONE;
798793
}
799794

@@ -1183,32 +1178,17 @@ ble_error_t nRF5xGap::applyWhiteIdentityList(GapWhiteAndIdentityList_t &gapAdrHe
11831178
}
11841179
}
11851180

1186-
ble_error_t nRF5xGap::updateWhiteAndIdentityListInStack(whiteAndIdentityListPurpose_t purpose)
1181+
ble_error_t nRF5xGap::updateWhiteAndIdentityListInStack()
11871182
{
11881183
GapWhiteAndIdentityList_t whiteAndIdentityList;
1189-
uint32_t err;
1190-
bool provide_settings;
1191-
1192-
if (purpose == nRF5xGap::purpose_avdvertising) {
1193-
provide_settings = (advertisingPolicyMode != Gap::ADV_POLICY_IGNORE_WHITELIST) ? true : false;
1194-
} else { //It must be nRF5xGap::purpose_scan_connect.
1195-
provide_settings = (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) ? true : false;
1196-
}
1197-
1184+
uint32_t err;
11981185

1199-
/* Add missing IRKs to nRF5xGap's whitelist from the bond table held by the Peer Manager */
1200-
if (provide_settings) {
1201-
err = getStackWhiteIdentityList(whiteAndIdentityList);
1186+
err = getStackWhiteIdentityList(whiteAndIdentityList);
12021187

1203-
if (err != BLE_ERROR_NONE) {
1204-
return (ble_error_t)err;
1205-
}
1206-
} else {
1207-
whiteAndIdentityList.addrs_cnt = 0;
1208-
whiteAndIdentityList.identities_cnt = 0;
1188+
if (err != BLE_ERROR_NONE) {
1189+
return (ble_error_t)err;
12091190
}
1210-
1211-
1191+
12121192
return applyWhiteIdentityList(whiteAndIdentityList);
12131193
}
12141194
#endif

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5_SDK13/source/nRF5xGap.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,6 @@ class nRF5xGap : public Gap
160160
uint32_t identities_cnt;
161161
} GapWhiteAndIdentityList_t;
162162

163-
/* purpose of updating the whitelist and identities settings. */
164-
enum whiteAndIdentityListPurpose_t
165-
{
166-
purpose_scan_connect = 0,
167-
purpose_avdvertising
168-
} whiteAndIdentityListPurpose;
169-
170163
/* Function for preparing setting of the whitelist feature and the identity-resolving feature (privacy).*/
171164
ble_error_t getStackWhiteIdentityList(GapWhiteAndIdentityList_t &whiteAndIdentityList);
172165

@@ -175,9 +168,8 @@ class nRF5xGap : public Gap
175168

176169
/* Function for introducing whitelist feature and the identity-resolving feature setting into SoftDevice.
177170
*
178-
* Introduced settings are comply which scanning or advertising policies.
179171
* This function incorporates getStackWhiteIdentityList and applyWhiteIdentityList together. */
180-
ble_error_t updateWhiteAndIdentityListInStack(whiteAndIdentityListPurpose_t purpose);
172+
ble_error_t updateWhiteAndIdentityListInStack(void);
181173
#endif
182174

183175
private:

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5_SDK13/source/nRF5xServiceDiscovery.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ nRF5xServiceDiscovery::ServiceUUIDDiscoveryQueue::triggerFirst(void)
236236
.start_handle = parentDiscoveryObject->services[serviceIndex].getStartHandle(),
237237
.end_handle = parentDiscoveryObject->services[serviceIndex].getEndHandle(),
238238
};
239+
239240
if (sd_ble_gattc_char_value_by_uuid_read(parentDiscoveryObject->connHandle, &uuid, &handleRange) == NRF_SUCCESS) {
240241
return;
241242
}
@@ -281,19 +282,22 @@ nRF5xServiceDiscovery::CharUUIDDiscoveryQueue::triggerFirst(void)
281282
}
282283

283284
void
284-
nRF5xServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response)
285+
nRF5xServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_t *p_gattc_evt)
285286
{
287+
const ble_gattc_evt_char_val_by_uuid_read_rsp_t * response = &p_gattc_evt->params.char_val_by_uuid_read_rsp;
288+
286289
if (state == DISCOVER_SERVICE_UUIDS) {
287290
if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID)) {
288291
UUID::LongUUIDBytes_t uuid;
289292

290293
#if (NRF_SD_BLE_API_VERSION >= 3)
291-
ble_gattc_handle_value_t iter;
292-
memset(&iter, 0, sizeof(ble_gattc_handle_value_t));
293-
(void) sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter((ble_gattc_evt_t*)response, &iter);
294-
memcpy(uuid, iter.p_value, UUID::LENGTH_OF_LONG_UUID);
294+
/* 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,
295+
* but it's not reliable for c++ build.
296+
* Instead of it memcpy gets proper response's value field by offset from handle-value pair: [2 B handle|16 B value=uuid_128b] */
297+
298+
memcpy(uuid, (&response->handle_value + 2), UUID::LENGTH_OF_LONG_UUID);
295299
#else
296-
memcpy(uuid, response->handle_value[0].p_value, UUID::LENGTH_OF_LONG_UUID);
300+
memcpy(uuid, &(response->handle_value[0].p_value[0]), UUID::LENGTH_OF_LONG_UUID);
297301
#endif
298302

299303
unsigned serviceIndex = serviceUUIDDiscoveryQueue.dequeue();
@@ -307,11 +311,11 @@ nRF5xServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_char_val_
307311
if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID + 1 /* props */ + 2 /* value handle */)) {
308312
UUID::LongUUIDBytes_t uuid;
309313

310-
#if (NRF_SD_BLE_API_VERSION >= 3)
311-
ble_gattc_handle_value_t iter;
312-
memset(&iter, 0, sizeof(ble_gattc_handle_value_t));
313-
(void) sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter((ble_gattc_evt_t*)response, &iter);
314-
memcpy(uuid, &(iter.p_value[3]), UUID::LENGTH_OF_LONG_UUID);
314+
#if (NRF_SD_BLE_API_VERSION >= 3)
315+
/* 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,
316+
* but it's not reliable for c++ build.
317+
* 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] */
318+
memcpy(uuid, (&response->handle_value + 5), UUID::LENGTH_OF_LONG_UUID);
315319
#else
316320
memcpy(uuid, &(response->handle_value[0].p_value[3]), UUID::LENGTH_OF_LONG_UUID);
317321
#endif

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5_SDK13/source/nRF5xServiceDiscovery.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ class nRF5xServiceDiscovery : public ServiceDiscovery
139139
void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response);
140140

141141
void triggerServiceUUIDDiscovery(void);
142-
void processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response);
142+
void processDiscoverUUIDResponse(const ble_gattc_evt_t *p_gattc_evt);
143143
void removeFirstServiceNeedingUUIDDiscovery(void);
144144

145145
void terminateServiceDiscovery(void) {

0 commit comments

Comments
 (0)