Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
554 changes: 344 additions & 210 deletions doc/nrf/libraries/bluetooth/mesh/vnd/images/bt_mesh_le_pair_resp.svg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we show the usage of bt_mesh_le_pair_resp_passkey_get function on diagram? In the app_passkey callback.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 5 additions & 12 deletions doc/nrf/libraries/bluetooth/mesh/vnd/le_pair_resp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,15 @@ LE Pairing Responder
:local:
:depth: 2

The LE Pairing Responder model is a vendor model.
The LE Pairing Responder model is a vendor model and it requires :kconfig:option:`CONFIG_BT_APP_PASSKEY` option to be enabled.
This model can be used to hand over a passkey that will authenticate a Bluetooth LE connection over a mesh network when it is not possible to use other pairing methods.

Before the pairing is initiated, an initiator should send an LE Pairing message with Passkey Reset sub-opcode to set a new passkey for the next pairing request.
Before the pairing is initiated, an initiator should send an LE Pairing message with Passkey Reset sub-opcode. This will trigger random passkey generation by LE Pairing Responder model or return the passkey set by the app using :c:func:`bt_mesh_le_pair_resp_passkey_set` function.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Before the pairing is initiated, an initiator should send an LE Pairing message with Passkey Reset sub-opcode. This will trigger random passkey generation by LE Pairing Responder model or return the passkey set by the app using :c:func:`bt_mesh_le_pair_resp_passkey_set` function.
Before the pairing is initiated, an initiator should send an LE Pairing message with Passkey Reset sub-opcode. If the passkey has been set by the :c:func:`bt_mesh_le_pair_resp_passkey_set` function, the predefined passkey will be returned in the Passkey Status message. Otherwise, a new passkey will be generated by LE Pairing Responder model and returned in the Passkey Status message.

The passkey returned in the LE Pairing message with the Passkey Status sub-opcode should be used for the next pairing.

The passkey is generated using the :c:func:`bt_rand` function and set to the host using the :c:func:`bt_passkey_set` function.
The latter requires the :kconfig:option:`CONFIG_BT_FIXED_PASSKEY` option to be enabled.

.. note::
The warning generated by the :kconfig:option:`CONFIG_BT_FIXED_PASSKEY` option should be disregarded as long as the application always invalidates the previously used passkey by calling the :c:func:`bt_mesh_le_pair_resp_passkey_invalidate` function regardless of the pairing result (see below).

This model requires an application to only enable the display capability for the LE pairing by setting the :c:member:`bt_conn_auth_cb.pairing_display` callback.
After every pairing request, the application must invalidate the previously used passkey by calling the :c:func:`bt_mesh_le_pair_resp_passkey_invalidate` function.
This function can be called from callbacks :c:member:`bt_conn_auth_info_cb.pairing_complete` and :c:member:`bt_conn_auth_info_cb.pairing_failed`.
See the :file:`samples/bluetooth/mesh/common/smp_bt_auth.c` file for the reference.
This model requires an application to only enable the display capability for the LE pairing by setting the :c:member:`bt_conn_auth_cb.pairing_display` callback. The application must also set the :c:member:`bt_conn_auth_cb.app_passkey` callback to use the passkey generated by LE Pairing Responder model.
After every pairing request, the application must invalidate the previously used passkey by calling the :c:func:`bt_mesh_le_pair_resp_passkey_invalidate` function or calling :c:func:`bt_mesh_le_pair_resp_passkey_set` with :ref:`BT_PASSKEY_RAND` value.
Those functions can be called from callbacks :c:member:`bt_conn_auth_info_cb.pairing_complete` and :c:member:`bt_conn_auth_info_cb.pairing_failed`. See the :file:`samples/bluetooth/mesh/common/smp_bt_auth.c` file for the reference.

.. figure:: images/bt_mesh_le_pair_resp.svg
:alt: Diagram of interaction between an Initiator and the LE Pairing Responder model
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ Bluetooth Mesh
* Deprecated the :kconfig:option:`CONFIG_BT_MESH_NLC_PERF_CONF` and :kconfig:option:`CONFIG_BT_MESH_NLC_PERF_DEFAULT` Kconfig options.
Existing configurations continue to work but you should migrate to individual profile options.

* Update the LE Pairing Responder model:

* Deprecated the :kconfig:option:`CONFIG_BT_FIXED_PASSKEY` option in favor of the new and supported :kconfig:option:`CONFIG_BT_APP_PASSKEY` option.

DECT NR+
--------

Expand Down Expand Up @@ -386,6 +390,8 @@ Bluetooth Mesh samples
* Updated the :makevar:`FILE_SUFFIX` make variable to use more descriptive suffixes for external flash configurations.
The new suffixes are ``_dfu_ext_flash`` for external flash DFU storage and ``_ext_flash_settings`` for external flash settings storage.

* Updated the sample to use the :kconfig:option:`CONFIG_BT_APP_PASSKEY` option instead of the deprecated :kconfig:option:`CONFIG_BT_FIXED_PASSKEY` option.

* :ref:`ble_mesh_dfu_target` sample:

* Added:
Expand Down
15 changes: 14 additions & 1 deletion include/bluetooth/mesh/vnd/le_pair_resp.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extern "C" {
/* @brief Invalidate previously used passkey.
*
* A user must call this function when a pairing request completes regardless of the status.
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope

*/
void bt_mesh_le_pair_resp_passkey_invalidate(void);

Expand All @@ -43,11 +44,23 @@ void bt_mesh_le_pair_resp_passkey_invalidate(void);
* By default, passkeys will be randomly generated on every new request. This function allows to use
* pre-defined passkey instead.
*
* @params passkey Passkey to use for the pairing, or @ref BT_PASSKEY_INVALID to use randomly
* @params passkey Passkey to use for the pairing, or @ref BT_PASSKEY_RAND to use randomly
* generated passkey again.
*/
void bt_mesh_le_pair_resp_passkey_set(uint32_t passkey);

/** @brief Get passkey to be used in the very next pairing.
*
* This function will return the passkey set by the @ref bt_mesh_le_pair_resp_passkey_set function or it will return
* a randomly generated passkey by the Reset message.
*
* If the passkey has never been set or the Reset message has never been received, @ref BT_PASSKEY_RAND will be returned.
*
* @return Passkey to be used in the very next pairing;
* @ref BT_PASSKEY_RAND if passkey is not set.
*/
const uint32_t bt_mesh_le_pair_resp_passkey_get(void);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure const-qualifier is needed here.

Suggested change
const uint32_t bt_mesh_le_pair_resp_passkey_get(void);
uint32_t bt_mesh_le_pair_resp_passkey_get(void);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually not; initially I was using pointer I think it is leftover.


/** @cond INTERNAL_HIDDEN */

extern const struct bt_mesh_model_op _bt_mesh_le_pair_resp_op[];
Expand Down
6 changes: 6 additions & 0 deletions samples/bluetooth/mesh/common/smp_bt_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,18 @@ static void pairing_confirm(struct bt_conn *conn)
printk("Pairing confirmed: %s\n", addr);
}

static uint32_t app_passkey(struct bt_conn *conn)
{
return bt_mesh_le_pair_resp_passkey_get();
}

static struct bt_conn_auth_cb auth_cb = {
/* Enable passkey_display callback to enable the display capability. */
.passkey_display = passkey_display,
/* These 2 callbacks are required for passkey_display callback. */
.cancel = cancel,
.pairing_confirm = pairing_confirm,
.app_passkey = app_passkey,
};

static void pairing_complete(struct bt_conn *conn, bool bonded)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CONFIG_MCUMGR_TRANSPORT_BT_PERM_RW_AUTHEN=y
CONFIG_BT_SMP=y
CONFIG_BT_FIXED_PASSKEY=y
CONFIG_BT_APP_PASSKEY=y
CONFIG_BT_MESH_LE_PAIR_RESP=y
CONFIG_BT_SMP_SC_ONLY=y
CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE=n
11 changes: 6 additions & 5 deletions samples/matter/common/src/bt_nus/bt_nus_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ BT_CONN_CB_DEFINE(conn_callbacks) = {
bt_conn_auth_cb Nrf::NUSService::sConnAuthCallbacks = {
.passkey_display = AuthPasskeyDisplay,
.cancel = AuthCancel,
.app_passkey = AuthAppPasskey,
};
bt_conn_auth_info_cb Nrf::NUSService::sConnAuthInfoCallbacks = {
.pairing_complete = PairingComplete,
Expand Down Expand Up @@ -71,11 +72,6 @@ bool NUSService::Init(uint8_t priority, uint16_t minInterval, uint16_t maxInterv
LOG_DBG("NUS BLE advertising stopped");
};

#if defined(CONFIG_BT_FIXED_PASSKEY)
if (bt_passkey_set(CONFIG_CHIP_NUS_FIXED_PASSKEY) != 0)
return false;
#endif

return true;
}

Expand Down Expand Up @@ -234,6 +230,11 @@ void NUSService::AuthPasskeyDisplay(bt_conn *conn, unsigned int passkey)
LOG_INF("PROVIDE THE FOLLOWING CODE IN YOUR MOBILE APP: %d", passkey);
}

uint32_t NUSService::AuthAppPasskey(bt_conn *conn)
{
return CONFIG_CHIP_NUS_FIXED_PASSKEY;
}

void NUSService::AuthCancel(bt_conn *conn)
{
LOG_INF("NUS BT Pairing cancelled: %s", LogAddress(conn));
Expand Down
2 changes: 1 addition & 1 deletion samples/matter/lock/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ tests:
build_only: true
extra_args:
- CONFIG_CHIP_NUS=y
- CONFIG_BT_FIXED_PASSKEY=y
- CONFIG_BT_APP_PASSKEY=y
- CONFIG_CHIP_NUS_FIXED_PASSKEY=112233
integration_platforms:
- nrf52840dk/nrf52840
Expand Down
4 changes: 2 additions & 2 deletions subsys/bluetooth/mesh/vnd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ config BT_MESH_DM_SRV_REFLECTOR_RANGING_WINDOW_US
endif # BT_MESH_DM_SRV

config BT_MESH_LE_PAIR_RESP
bool "LE Pairing Responder model"
bool "LE Pairing Responder model [EXPERIMENTAL]"
select BT_MESH_VENDOR_MODELS
select EXPERIMENTAL
depends on BT_FIXED_PASSKEY
depends on BT_APP_PASSKEY
depends on BT_SMP_SC_ONLY
help
Enable the LE Pairing Responder model. The LE Pairing Responder model is used to generate
Expand Down
21 changes: 11 additions & 10 deletions subsys/bluetooth/mesh/vnd/le_pair_resp.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,27 @@ LOG_MODULE_REGISTER(bt_mesh_le_pair_resp);
#define STATUS_PASSKEY_SET 0x00
#define STATUS_PASSKEY_NOT_SET 0x01

static uint32_t predefined_passkey = BT_PASSKEY_INVALID;
static uint32_t predefined_passkey = BT_PASSKEY_RAND;

static int handle_reset(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
uint32_t passkey;
uint8_t status = STATUS_PASSKEY_SET;
int err;

if (buf->len != 0) {
return -EINVAL;
}

BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_LE_PAIR_OP, 5);

if (predefined_passkey != BT_PASSKEY_INVALID) {
if (predefined_passkey != BT_PASSKEY_RAND) {
passkey = predefined_passkey;
} else {
passkey = sys_rand32_get() % 1000000;
}

err = bt_passkey_set(passkey);
if (err) {
LOG_ERR("Unable to set passkey (err: %d)", err);
status = STATUS_PASSKEY_NOT_SET;
/* Overwrite the predefined passkey with the randomly generated passkey.
So the le pair responder can use the randomly generated passkey for the next pairing request.*/
predefined_passkey = passkey;
}

bt_mesh_model_msg_init(&rsp, BT_MESH_LE_PAIR_OP);
Expand Down Expand Up @@ -112,10 +108,15 @@ const struct bt_mesh_model_cb _bt_mesh_le_pair_resp_cb = {

void bt_mesh_le_pair_resp_passkey_invalidate(void)
{
(void)bt_passkey_set(BT_PASSKEY_INVALID);
predefined_passkey = BT_PASSKEY_RAND;
}

void bt_mesh_le_pair_resp_passkey_set(uint32_t passkey)
{
predefined_passkey = passkey;
}

const uint32_t bt_mesh_le_pair_resp_passkey_get(void)
{
return predefined_passkey;
}
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ manifest:
# https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/modules.html
- name: zephyr
repo-path: sdk-zephyr
revision: cefb2ed86ac723218c509ef7ceae2509bb1f89f6
revision: pull/3466/head
import:
# In addition to the zephyr repository itself, NCS also
# imports the contents of zephyr/west.yml at the above
Expand Down