bluetooth: host: Dynamic bt_conn_le_create timeout

Extends the bt_conn_le_create_param struct to provide the option
to set a custom timeout for the initiation of the connection.

The logic for the default values of window_coded and interval_coded
were moved to conn.c in order to resolve all defaults for the
create_param struct at a single location.

Timeout is not added as a parameter to the BT_CONN_LE_CREATE_PARAM
macro due to the expectation that CONFIG_BT_CREATE_CONN_TIMEOUT
will be the typical value that users will expect.

Fixes #23468

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
This commit is contained in:
Jordan Yates 2020-03-30 19:23:16 +10:00 committed by Johan Hedberg
commit a038dc76f1
4 changed files with 62 additions and 20 deletions

View file

@ -328,6 +328,15 @@ struct bt_conn_le_create_param {
* Set zero to use same as LE 1M PHY scan window.
*/
u16_t window_coded;
/** Connection initiation timeout (N * 10 MS)
*
* Set zero to use the default :option:`CONFIG_BT_CREATE_CONN_TIMEOUT`
* timeout.
*
* @note Unused in @ref bt_conn_create_auto_le
*/
u16_t timeout;
};
/** Helper to declare create connection parameters inline
@ -343,6 +352,7 @@ struct bt_conn_le_create_param {
.window = (_window), \
.interval_coded = 0, \
.window_coded = 0, \
.timeout = 0, \
} })
/** Default LE create connection parameters.
@ -610,7 +620,8 @@ struct bt_conn_cb {
* - @ref BT_HCI_ERR_UNKNOWN_CONN_ID Creating the connection started by
* @ref bt_conn_create_le was canceled either by the user through
* @ref bt_conn_disconnect or by the timeout in the host through
* :option:`CONFIG_BT_CREATE_CONN_TIMEOUT`.
* @ref bt_conn_le_create_param timeout parameter, which defaults to
* :option:`CONFIG_BT_CREATE_CONN_TIMEOUT` seconds.
* - @p BT_HCI_ERR_ADV_TIMEOUT Directed advertiser started by @ref
* bt_conn_create_slave_le with high duty cycle timed out after 1.28
* seconds.

View file

@ -477,8 +477,8 @@ config BT_MAX_PAIRED
config BT_CREATE_CONN_TIMEOUT
int "Timeout for pending LE Create Connection command in seconds"
default 3
range 1 BT_RPA_TIMEOUT if BT_PRIVACY
range 1 65535
range 1 BT_RPA_TIMEOUT if BT_PRIVACY && (BT_RPA_TIMEOUT < 655)
range 1 655
config BT_CONN_PARAM_UPDATE_TIMEOUT
int "Peripheral connection parameter update timeout in milliseconds"

View file

@ -64,9 +64,6 @@ NET_BUF_POOL_FIXED_DEFINE(frag_pool, CONFIG_BT_L2CAP_TX_FRAG_COUNT, FRAG_SIZE,
#endif /* CONFIG_BT_L2CAP_TX_FRAG_COUNT > 0 */
/* How long until we cancel HCI_LE_Create_Connection */
#define CONN_TIMEOUT K_SECONDS(CONFIG_BT_CREATE_CONN_TIMEOUT)
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
const struct bt_conn_auth_cb *bt_auth;
#endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */
@ -1713,7 +1710,7 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state)
/* this indicate LE Create Connection with peer address
* has been stopped. This could either be triggered by
* the application through bt_conn_disconnect or by
* timeout set by CONFIG_BT_CREATE_CONN_TIMEOUT.
* timeout set by bt_conn_le_create_param.timeout.
*/
if (conn->err) {
notify_connected(conn);
@ -1765,7 +1762,8 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state)
*/
if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
conn->type == BT_CONN_TYPE_LE) {
k_delayed_work_submit(&conn->update_work, CONN_TIMEOUT);
k_delayed_work_submit(&conn->update_work,
K_MSEC(10 * bt_dev.create_param.timeout));
}
break;
@ -2122,6 +2120,40 @@ static void bt_conn_set_param_le(struct bt_conn *conn,
conn->le.timeout = param->timeout;
}
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 u32_t timeout_max = (MSEC_PER_SEC / 10) * CONFIG_BT_RPA_TIMEOUT;
if (param->timeout > timeout_max) {
return false;
}
#endif
return true;
}
static void create_param_setup(const struct bt_conn_le_create_param *param)
{
bt_dev.create_param = *param;
bt_dev.create_param.timeout =
(bt_dev.create_param.timeout != 0) ?
bt_dev.create_param.timeout :
(MSEC_PER_SEC / 10) * CONFIG_BT_CREATE_CONN_TIMEOUT;
bt_dev.create_param.interval_coded =
(bt_dev.create_param.interval_coded != 0) ?
bt_dev.create_param.interval_coded :
bt_dev.create_param.interval;
bt_dev.create_param.window_coded =
(bt_dev.create_param.window_coded != 0) ?
bt_dev.create_param.window_coded :
bt_dev.create_param.window;
}
#if defined(CONFIG_BT_WHITELIST)
int bt_conn_le_create_auto(const struct bt_conn_le_create_param *create_param,
const struct bt_le_conn_param *param)
@ -2165,7 +2197,7 @@ int bt_conn_le_create_auto(const struct bt_conn_le_create_param *create_param,
}
bt_conn_set_param_le(conn, param);
bt_dev.create_param = *create_param;
create_param_setup(create_param);
atomic_set_bit(conn->flags, BT_CONN_AUTO_CONNECT);
bt_conn_set_state(conn, BT_CONN_CONNECT_AUTO);
@ -2235,6 +2267,10 @@ int bt_conn_le_create(const bt_addr_le_t *peer,
return -EINVAL;
}
if (!create_param_validate(create_param)) {
return -EINVAL;
}
if (atomic_test_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) {
return -EINVAL;
}
@ -2278,7 +2314,7 @@ int bt_conn_le_create(const bt_addr_le_t *peer,
}
bt_conn_set_param_le(conn, conn_param);
bt_dev.create_param = *create_param;
create_param_setup(create_param);
#if defined(CONFIG_BT_SMP)
if (!bt_dev.le.rl_size || bt_dev.le.rl_entries > bt_dev.le.rl_size) {

View file

@ -1261,7 +1261,7 @@ static inline bool rpa_timeout_valid_check(void)
#if defined(CONFIG_BT_PRIVACY)
/* Check if create conn timeout will happen before RPA timeout. */
return k_delayed_work_remaining_get(&bt_dev.rpa_update) >
K_SECONDS(CONFIG_BT_CREATE_CONN_TIMEOUT);
(10 * bt_dev.create_param.timeout);
#else
return true;
#endif
@ -1401,17 +1401,12 @@ int bt_le_create_conn_ext(const struct bt_conn *conn)
}
if (bt_dev.create_param.options & BT_LE_CONN_OPT_CODED) {
u16_t interval = bt_dev.create_param.interval_coded ?
bt_dev.create_param.interval_coded :
bt_dev.create_param.interval;
u16_t window = bt_dev.create_param.window_coded ?
bt_dev.create_param.window_coded :
bt_dev.create_param.window;
cp->phys |= BT_HCI_LE_EXT_SCAN_PHY_CODED;
phy = net_buf_add(buf, sizeof(*phy));
phy->scan_interval = sys_cpu_to_le16(interval);
phy->scan_window = sys_cpu_to_le16(window);
phy->scan_interval = sys_cpu_to_le16(
bt_dev.create_param.interval_coded);
phy->scan_window = sys_cpu_to_le16(
bt_dev.create_param.window_coded);
set_phy_conn_param(conn, phy);
}