Skip to content

Commit f0c3f14

Browse files
committed
Nordic BLE: Fix pairing cancellation.
Depending on the role and the current state of the local device; pairing cancelation should be made with a call to a specific function. Normally the Nordic stack would reject invalid calls if the device is not in the correct state; therefore it was assumed that it was possible to detect the state from sd errors. Unfortunatelly this is not true with the latest softdevices as some calls succeed even if the device is not in the right state. To solve that issue cancelation looks at the current state of the device first to select the right function that will trigger the pairing cancellation. Note: the call to sd_ble_gap_authenticate was missing in the previous algorithm
1 parent 301e527 commit f0c3f14

File tree

2 files changed

+56
-28
lines changed

2 files changed

+56
-28
lines changed

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF51/source/nRF5xPalSecurityManager.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
#include <stdint.h>
1818
#include "nRF5xPalSecurityManager.h"
19+
#include "nRF5xn.h"
20+
#include "ble/Gap.h"
21+
#include "nRF5xGap.h"
1922
#include "nrf_ble.h"
2023
#include "nrf_ble_gap.h"
2124
#include "nrf_soc.h"
@@ -339,22 +342,33 @@ ble_error_t nRF5xSecurityManager::send_pairing_response(
339342
ble_error_t nRF5xSecurityManager::cancel_pairing(
340343
connection_handle_t connection, pairing_failure_t reason
341344
) {
342-
// this is the default path except when a key is expected to be entered by
343-
// the user.
344-
uint32_t err = sd_ble_gap_sec_params_reply(
345-
connection,
346-
reason.value() | 0x80,
347-
/* sec params */ NULL,
348-
/* keyset */ NULL
349-
);
345+
uint32_t err = 0;
350346

351-
if (!err) {
352-
return BLE_ERROR_NONE;
353-
}
347+
pairing_control_block_t* pairing_cb = get_pairing_cb(connection);
354348

355-
// Failed because we're in the wrong state; try to cancel pairing with
356-
// sd_ble_gap_auth_key_reply
357-
if (err == NRF_ERROR_INVALID_STATE) {
349+
// If there is no control block yet then if the local device is a central
350+
// then we must reject the security request otherwise it is a response to
351+
// a pairing feature exchange from a central.
352+
if (!pairing_cb) {
353+
::Gap::Role_t current_role;
354+
if (!nRF5xn::Instance().getGap().get_role(connection, current_role)) {
355+
return BLE_ERROR_INVALID_PARAM;
356+
}
357+
358+
if (current_role == ::Gap::PERIPHERAL) {
359+
// response to a pairing feature request
360+
err = sd_ble_gap_sec_params_reply(
361+
connection,
362+
reason.value() | 0x80,
363+
/* sec params */ NULL,
364+
/* keyset */ NULL
365+
);
366+
} else {
367+
// response to a peripheral security request
368+
err = sd_ble_gap_authenticate(connection, NULL);
369+
}
370+
} else {
371+
// At this point this must be a response to a key
358372
err = sd_ble_gap_auth_key_reply(
359373
connection,
360374
/* key type */ BLE_GAP_AUTH_KEY_TYPE_NONE,

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF52/source/nRF5xPalSecurityManager.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
#include <stdint.h>
1818
#include "nRF5xPalSecurityManager.h"
19+
#include "nRF5xn.h"
20+
#include "ble/Gap.h"
21+
#include "nRF5xGap.h"
1922
#include "nrf_ble.h"
2023
#include "ble_gap.h"
2124
#include "nrf_soc.h"
@@ -316,22 +319,33 @@ ble_error_t nRF5xSecurityManager::send_pairing_response(
316319
ble_error_t nRF5xSecurityManager::cancel_pairing(
317320
connection_handle_t connection, pairing_failure_t reason
318321
) {
319-
// this is the default path except when a key is expected to be entered by
320-
// the user.
321-
uint32_t err = sd_ble_gap_sec_params_reply(
322-
connection,
323-
reason.value() | 0x80,
324-
/* sec params */ NULL,
325-
/* keyset */ NULL
326-
);
322+
uint32_t err = 0;
327323

328-
if (!err) {
329-
return BLE_ERROR_NONE;
330-
}
324+
pairing_control_block_t* pairing_cb = get_pairing_cb(connection);
331325

332-
// Failed because we're in the wrong state; try to cancel pairing with
333-
// sd_ble_gap_auth_key_reply
334-
if (err == NRF_ERROR_INVALID_STATE) {
326+
// If there is no control block yet then if the local device is a central
327+
// then we must reject the security request otherwise it is a response to
328+
// a pairing feature exchange from a central.
329+
if (!pairing_cb) {
330+
::Gap::Role_t current_role;
331+
if (!nRF5xn::Instance().getGap().get_role(connection, current_role)) {
332+
return BLE_ERROR_INVALID_PARAM;
333+
}
334+
335+
if (current_role == ::Gap::PERIPHERAL) {
336+
// response to a pairing feature request
337+
err = sd_ble_gap_sec_params_reply(
338+
connection,
339+
reason.value() | 0x80,
340+
/* sec params */ NULL,
341+
/* keyset */ NULL
342+
);
343+
} else {
344+
// response to a peripheral security request
345+
err = sd_ble_gap_authenticate(connection, NULL);
346+
}
347+
} else {
348+
// At this point this must be a response to a key
335349
err = sd_ble_gap_auth_key_reply(
336350
connection,
337351
/* key type */ BLE_GAP_AUTH_KEY_TYPE_NONE,

0 commit comments

Comments
 (0)