bluetooth: add api for changing rpa timeout in runtime
Added a new Bluetooth API and Kconfig option for overriding the RPA timeout in runtime. Signed-off-by: Kamil Piszczek <Kamil.Piszczek@nordicsemi.no>
This commit is contained in:
parent
8bdf363c0c
commit
1eb9d36d46
|
@ -2021,6 +2021,26 @@ static inline int bt_le_whitelist_clear(void)
|
|||
*/
|
||||
int bt_le_set_chan_map(uint8_t chan_map[5]);
|
||||
|
||||
/**
|
||||
* @brief Set the Resolvable Private Address timeout in runtime
|
||||
*
|
||||
* The new RPA timeout value will be used for the next RPA rotation
|
||||
* and all subsequent rotations until another override is scheduled
|
||||
* with this API.
|
||||
*
|
||||
* Initially, the if @kconfig{CONFIG_BT_RPA_TIMEOUT} is used as the
|
||||
* RPA timeout.
|
||||
*
|
||||
* This symbol is linkable if @kconfig{CONFIG_BT_RPA_TIMEOUT_DYNAMIC}
|
||||
* is enabled.
|
||||
*
|
||||
* @param new_rpa_timeout Resolvable Private Address timeout in seconds
|
||||
*
|
||||
* @retval 0 Success.
|
||||
* @retval -EINVAL RPA timeout value is invalid. Valid range is 1s - 3600s.
|
||||
*/
|
||||
int bt_le_set_rpa_timeout(uint16_t new_rpa_timeout);
|
||||
|
||||
/**
|
||||
* @brief Helper for parsing advertising (or EIR or OOB) data.
|
||||
*
|
||||
|
|
|
@ -350,6 +350,13 @@ config BT_RPA_TIMEOUT
|
|||
This option defines how often resolvable private address is rotated.
|
||||
Value is provided in seconds and defaults to 900 seconds (15 minutes).
|
||||
|
||||
config BT_RPA_TIMEOUT_DYNAMIC
|
||||
bool "Support setting the Resolvable Private Address timeout at runtime"
|
||||
depends on BT_PRIVACY
|
||||
help
|
||||
This option allows the user to override the default value of
|
||||
the Resolvable Private Address timeout using dedicated APIs.
|
||||
|
||||
config BT_SIGNING
|
||||
bool "Data signing support"
|
||||
help
|
||||
|
|
|
@ -2492,7 +2492,7 @@ static bool create_param_validate(const struct bt_conn_le_create_param *param)
|
|||
{
|
||||
#if defined(CONFIG_BT_PRIVACY)
|
||||
/* Initiation timeout cannot be greater than the RPA timeout */
|
||||
const uint32_t timeout_max = (MSEC_PER_SEC / 10) * CONFIG_BT_RPA_TIMEOUT;
|
||||
const uint32_t timeout_max = (MSEC_PER_SEC / 10) * bt_dev.rpa_timeout;
|
||||
|
||||
if (param->timeout > timeout_max) {
|
||||
return false;
|
||||
|
|
|
@ -76,6 +76,9 @@ static void init_work(struct k_work *work);
|
|||
|
||||
struct bt_dev bt_dev = {
|
||||
.init = Z_WORK_INITIALIZER(init_work),
|
||||
#if defined(CONFIG_BT_PRIVACY)
|
||||
.rpa_timeout = CONFIG_BT_RPA_TIMEOUT,
|
||||
#endif
|
||||
#if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC)
|
||||
.appearance = CONFIG_BT_DEVICE_APPEARANCE,
|
||||
#endif
|
||||
|
@ -2975,7 +2978,7 @@ static int le_init(void)
|
|||
}
|
||||
|
||||
cp = net_buf_add(buf, sizeof(*cp));
|
||||
cp->rpa_timeout = sys_cpu_to_le16(CONFIG_BT_RPA_TIMEOUT);
|
||||
cp->rpa_timeout = sys_cpu_to_le16(bt_dev.rpa_timeout);
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_RPA_TIMEOUT, buf,
|
||||
NULL);
|
||||
if (err) {
|
||||
|
@ -3933,6 +3936,24 @@ int bt_le_set_chan_map(uint8_t chan_map[5])
|
|||
buf, NULL);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC)
|
||||
int bt_le_set_rpa_timeout(uint16_t new_rpa_timeout)
|
||||
{
|
||||
if ((new_rpa_timeout == 0) || (new_rpa_timeout > 3600)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (new_rpa_timeout == bt_dev.rpa_timeout) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bt_dev.rpa_timeout = new_rpa_timeout;
|
||||
atomic_set_bit(bt_dev.flags, BT_DEV_RPA_TIMEOUT_CHANGED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void bt_data_parse(struct net_buf_simple *ad,
|
||||
bool (*func)(struct bt_data *data, void *user_data),
|
||||
void *user_data)
|
||||
|
|
|
@ -44,6 +44,7 @@ enum {
|
|||
BT_DEV_INITIATING,
|
||||
|
||||
BT_DEV_RPA_VALID,
|
||||
BT_DEV_RPA_TIMEOUT_CHANGED,
|
||||
|
||||
BT_DEV_ID_PENDING,
|
||||
BT_DEV_STORE_ID,
|
||||
|
@ -358,6 +359,9 @@ struct bt_dev {
|
|||
|
||||
/* Work used for RPA rotation */
|
||||
struct k_work_delayable rpa_update;
|
||||
|
||||
/* The RPA timeout value. */
|
||||
uint16_t rpa_timeout;
|
||||
#endif
|
||||
|
||||
/* Local Name */
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <zephyr/settings/settings.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/hci_vs.h>
|
||||
|
@ -204,9 +205,47 @@ static void le_rpa_invalidate(void)
|
|||
}
|
||||
|
||||
#if defined(CONFIG_BT_PRIVACY)
|
||||
|
||||
#if defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC)
|
||||
static void le_rpa_timeout_update(void)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (atomic_test_and_clear_bit(bt_dev.flags, BT_DEV_RPA_TIMEOUT_CHANGED)) {
|
||||
struct net_buf *buf;
|
||||
struct bt_hci_cp_le_set_rpa_timeout *cp;
|
||||
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_RPA_TIMEOUT,
|
||||
sizeof(*cp));
|
||||
if (!buf) {
|
||||
BT_ERR("Failed to create HCI RPA timeout command");
|
||||
err = -ENOBUFS;
|
||||
goto submit;
|
||||
}
|
||||
|
||||
cp = net_buf_add(buf, sizeof(*cp));
|
||||
cp->rpa_timeout = sys_cpu_to_le16(bt_dev.rpa_timeout);
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_RPA_TIMEOUT, buf, NULL);
|
||||
if (err) {
|
||||
BT_ERR("Failed to send HCI RPA timeout command");
|
||||
goto submit;
|
||||
}
|
||||
}
|
||||
|
||||
submit:
|
||||
if (err) {
|
||||
atomic_set_bit(bt_dev.flags, BT_DEV_RPA_TIMEOUT_CHANGED);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void le_rpa_timeout_submit(void)
|
||||
{
|
||||
(void)k_work_schedule(&bt_dev.rpa_update, RPA_TIMEOUT);
|
||||
#if defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC)
|
||||
le_rpa_timeout_update();
|
||||
#endif
|
||||
|
||||
(void)k_work_schedule(&bt_dev.rpa_update, K_SECONDS(bt_dev.rpa_timeout));
|
||||
}
|
||||
|
||||
/* this function sets new RPA only if current one is no longer valid */
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define RPA_TIMEOUT_MS (CONFIG_BT_RPA_TIMEOUT * MSEC_PER_SEC)
|
||||
#define RPA_TIMEOUT K_MSEC(RPA_TIMEOUT_MS)
|
||||
#define RPA_TIMEOUT_MS(_rpa_timeout) (_rpa_timeout * MSEC_PER_SEC)
|
||||
|
||||
static inline bool bt_id_rpa_is_new(void)
|
||||
{
|
||||
|
@ -16,7 +15,7 @@ static inline bool bt_id_rpa_is_new(void)
|
|||
/* RPA is considered new if there is less than half a second since the
|
||||
* timeout was started.
|
||||
*/
|
||||
return remaining_ms > (RPA_TIMEOUT_MS - 500);
|
||||
return remaining_ms > (RPA_TIMEOUT_MS(bt_dev.rpa_timeout) - 500);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue