Skip to content

Commit 5b44ebe

Browse files
mkapala-nordicjhedberg
authored andcommitted
bluetooth: host: smp: Add bondable flag overlay per connection
The current API for changing the bondable mode uses the global flag. With Zephyr support for multiple Bluetooth identities, the API for changing the bondable mode should be more fine-grained. The bondable requirements of one identity should not have an impact on another identity which can have a different set of requirements. This change introduces function to overlay bondable flag per connection. Signed-off-by: Mateusz Kapala <[email protected]>
1 parent b95cdb2 commit 5b44ebe

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

include/zephyr/bluetooth/conn.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,26 @@ void bt_conn_cb_register(struct bt_conn_cb *cb);
10821082
*/
10831083
void bt_set_bondable(bool enable);
10841084

1085+
/** @brief Set/clear the bonding flag for a given connection.
1086+
*
1087+
* Set/clear the Bonding flag in the Authentication Requirements of
1088+
* SMP Pairing Request/Response data for a given connection.
1089+
*
1090+
* The bonding flag for a given connection cannot be set/cleared if
1091+
* security procedures in the SMP module have already started.
1092+
* This function can be called only once per connection.
1093+
*
1094+
* If the bonding flag is not set/cleared for a given connection,
1095+
* the value will depend on global configuration which is set using
1096+
* bt_set_bondable.
1097+
* The default value of the global configuration is defined using
1098+
* CONFIG_BT_BONDABLE Kconfig option.
1099+
*
1100+
* @param conn Connection object.
1101+
* @param enable Value allowing/disallowing to be bondable.
1102+
*/
1103+
int bt_conn_set_bondable(struct bt_conn *conn, bool enable);
1104+
10851105
/** @brief Allow/disallow remote LE SC OOB data to be used for pairing.
10861106
*
10871107
* Set/clear the OOB data flag for LE SC SMP Pairing Request/Response data.

subsys/bluetooth/host/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,13 @@ config BT_BONDING_REQUIRED
600600
set the bondable flag in their pairing request. Any other kind of
601601
requests will be rejected.
602602

603+
config BT_BONDABLE_PER_CONNECTION
604+
bool "Set/clear the bonding flag per-connection [EXPERIMENTAL]"
605+
select EXPERIMENTAL
606+
help
607+
Enable support for the bt_conn_set_bondable API function that is
608+
used to set/clear the bonding flag on a per-connection basis.
609+
603610
config BT_STORE_DEBUG_KEYS
604611
bool "Store Debug Mode bonds"
605612
help

subsys/bluetooth/host/smp.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ struct bt_smp {
209209

210210
/* Used Bluetooth authentication callbacks. */
211211
atomic_ptr_t auth_cb;
212+
213+
/* Bondable flag */
214+
atomic_t bondable;
212215
};
213216

214217
static unsigned int fixed_passkey = BT_PASSKEY_INVALID;
@@ -288,6 +291,11 @@ static K_SEM_DEFINE(sc_local_pkey_ready, 0, 1);
288291
*/
289292
#define BT_SMP_AUTH_CB_UNINITIALIZED ((atomic_ptr_val_t)bt_smp_pool)
290293

294+
/* Value used to mark that per-connection bondable flag is not initialized.
295+
* Value false/true represent if flag is cleared or set and cannot be used for that purpose.
296+
*/
297+
#define BT_SMP_BONDABLE_UNINITIALIZED ((atomic_val_t)-1)
298+
291299
static bool le_sc_supported(void)
292300
{
293301
/*
@@ -310,6 +318,13 @@ static const struct bt_conn_auth_cb *latch_auth_cb(struct bt_smp *smp)
310318
return atomic_ptr_get(&smp->auth_cb);
311319
}
312320

321+
static bool latch_bondable(struct bt_smp *smp)
322+
{
323+
atomic_cas(&smp->bondable, BT_SMP_BONDABLE_UNINITIALIZED, (atomic_val_t)bondable);
324+
325+
return atomic_get(&smp->bondable);
326+
}
327+
313328
static uint8_t get_io_capa(struct bt_smp *smp)
314329
{
315330
const struct bt_conn_auth_cb *smp_auth_cb = latch_auth_cb(smp);
@@ -2592,7 +2607,7 @@ static uint8_t get_auth(struct bt_smp *smp, uint8_t auth)
25922607
auth |= BT_SMP_AUTH_MITM;
25932608
}
25942609

2595-
if (bondable) {
2610+
if (latch_bondable(smp)) {
25962611
auth |= BT_SMP_AUTH_BONDING;
25972612
} else {
25982613
auth &= ~BT_SMP_AUTH_BONDING;
@@ -3977,7 +3992,7 @@ static uint8_t smp_security_request(struct bt_smp *smp, struct net_buf *buf)
39773992
}
39783993

39793994
if (IS_ENABLED(CONFIG_BT_BONDING_REQUIRED) &&
3980-
!(bondable && (auth & BT_SMP_AUTH_BONDING))) {
3995+
!(latch_bondable(smp) && (auth & BT_SMP_AUTH_BONDING))) {
39813996
/* Reject security req if not both intend to bond */
39823997
LOG_DBG("Bonding required");
39833998
return BT_SMP_ERR_UNSPECIFIED;
@@ -4541,6 +4556,7 @@ static void bt_smp_connected(struct bt_l2cap_chan *chan)
45414556
smp_reset(smp);
45424557

45434558
atomic_ptr_set(&smp->auth_cb, BT_SMP_AUTH_CB_UNINITIALIZED);
4559+
atomic_set(&smp->bondable, BT_SMP_BONDABLE_UNINITIALIZED);
45444560
}
45454561

45464562
static void bt_smp_disconnected(struct bt_l2cap_chan *chan)
@@ -5291,6 +5307,24 @@ static inline int smp_self_test(void)
52915307
}
52925308
#endif
52935309

5310+
#if defined(CONFIG_BT_BONDABLE_PER_CONNECTION)
5311+
int bt_conn_set_bondable(struct bt_conn *conn, bool enable)
5312+
{
5313+
struct bt_smp *smp;
5314+
5315+
smp = smp_chan_get(conn);
5316+
if (!smp) {
5317+
return -EINVAL;
5318+
}
5319+
5320+
if (atomic_cas(&smp->bondable, BT_SMP_BONDABLE_UNINITIALIZED, (atomic_val_t)enable)) {
5321+
return 0;
5322+
} else {
5323+
return -EALREADY;
5324+
}
5325+
}
5326+
#endif
5327+
52945328
int bt_smp_auth_cb_overlay(struct bt_conn *conn, const struct bt_conn_auth_cb *cb)
52955329
{
52965330
struct bt_smp *smp;

0 commit comments

Comments
 (0)