Skip to content

Commit

Permalink
bluetooth: host: smp: Add bondable flag overlay per connection
Browse files Browse the repository at this point in the history
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 <mateusz.kapala@nordicsemi.no>
  • Loading branch information
mkapala-nordic committed Jul 4, 2023
1 parent acde5fe commit bd45dc0
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
19 changes: 19 additions & 0 deletions include/zephyr/bluetooth/conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,25 @@ void bt_conn_cb_register(struct bt_conn_cb *cb);
*/
void bt_set_bondable(bool enable);

/** @brief Overlay the bonding flag for a given connection.
*
* Set/clear the Bonding flag in the Authentication Requirements of
* SMP Pairing Request/Response data for a given connection.
*
* The bonding flag for a given connection cannot be overlaid if
* security procedures in the SMP module have already started. This function
* can be called only once per connection.
*
* If the bonding flag is not overlaid, the value will depend on global
* configuration which is set using bt_set_bondable.
* The default value of the global configuration is defined using
* CONFIG_BT_BONDABLE Kconfig option.
*
* @param conn Connection object.
* @param enable Value allowing/disallowing to be bondable.
*/
int bt_bondable_overlay(struct bt_conn *conn, bool enable);

/** @brief Allow/disallow remote LE SC OOB data to be used for pairing.
*
* Set/clear the OOB data flag for LE SC SMP Pairing Request/Response data.
Expand Down
36 changes: 34 additions & 2 deletions subsys/bluetooth/host/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ struct bt_smp {

/* Used Bluetooth authentication callbacks. */
atomic_ptr_t auth_cb;

/* Bondable flag */
atomic_t bondable;
};

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

/* Value used to mark that per-connection bondable flag is not initialized.
* Value false/true represent if flag is cleared or set and cannot be used for that purpose.
*/
#define BT_SMP_BONDABLE_UNINITIALIZED ((atomic_val_t)-1)

static bool le_sc_supported(void)
{
/*
Expand All @@ -310,6 +318,13 @@ static const struct bt_conn_auth_cb *latch_auth_cb(struct bt_smp *smp)
return atomic_ptr_get(&smp->auth_cb);
}

static bool latch_bondable(struct bt_smp *smp)
{
atomic_cas(&smp->bondable, BT_SMP_BONDABLE_UNINITIALIZED, (atomic_val_t)bondable);

return atomic_get(&smp->bondable);
}

static uint8_t get_io_capa(struct bt_smp *smp)
{
const struct bt_conn_auth_cb *smp_auth_cb = latch_auth_cb(smp);
Expand Down Expand Up @@ -2592,7 +2607,7 @@ static uint8_t get_auth(struct bt_smp *smp, uint8_t auth)
auth |= BT_SMP_AUTH_MITM;
}

if (bondable) {
if (latch_bondable(smp)) {
auth |= BT_SMP_AUTH_BONDING;
} else {
auth &= ~BT_SMP_AUTH_BONDING;
Expand Down Expand Up @@ -3977,7 +3992,7 @@ static uint8_t smp_security_request(struct bt_smp *smp, struct net_buf *buf)
}

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

atomic_ptr_set(&smp->auth_cb, BT_SMP_AUTH_CB_UNINITIALIZED);
atomic_set(&smp->bondable, BT_SMP_BONDABLE_UNINITIALIZED);
}

static void bt_smp_disconnected(struct bt_l2cap_chan *chan)
Expand Down Expand Up @@ -5291,6 +5307,22 @@ static inline int smp_self_test(void)
}
#endif

int bt_bondable_overlay(struct bt_conn *conn, bool enable)
{
struct bt_smp *smp;

smp = smp_chan_get(conn);
if (!smp) {
return -EINVAL;
}

if (atomic_cas(&smp->bondable, BT_SMP_BONDABLE_UNINITIALIZED, (atomic_val_t)enable)) {
return 0;
} else {
return -EALREADY;
}
}

int bt_smp_auth_cb_overlay(struct bt_conn *conn, const struct bt_conn_auth_cb *cb)
{
struct bt_smp *smp;
Expand Down

0 comments on commit bd45dc0

Please sign in to comment.