Bluetooth: conn: Use delayed work for LE connection timeout

Detaching the timeout from the tx_thread lets us prepare for merging
all TX threads into a single one with the help of k_poll(). There's no
need to define a new delayed work object since the existing connection
parameter update object and connection timeout will never need to run
in parallel. Additionally, but some CONFIG_BLUETOOTH_CENTRAL guards to
void pulling in unnecessary code when Central role is not enabled.

Change-Id: Ia1f222aa052edcecd484a924f2d9a63a3b8fd11f
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2017-01-31 09:41:35 +02:00
commit 192db7179c
2 changed files with 21 additions and 44 deletions

View file

@ -150,6 +150,12 @@ static void le_conn_update(struct k_work *work)
struct bt_conn *conn = CONTAINER_OF(le, struct bt_conn, le); struct bt_conn *conn = CONTAINER_OF(le, struct bt_conn, le);
const struct bt_le_conn_param *param; const struct bt_le_conn_param *param;
if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) &&
conn->state == BT_CONN_CONNECT) {
bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
return;
}
param = BT_LE_CONN_PARAM(conn->le.interval_min, param = BT_LE_CONN_PARAM(conn->le.interval_min,
conn->le.interval_max, conn->le.interval_max,
conn->le.latency, conn->le.latency,
@ -1066,19 +1072,6 @@ struct bt_conn *bt_conn_add_le(const bt_addr_le_t *peer)
return conn; return conn;
} }
static void timeout_thread(void *p1, void *p2, void *p3)
{
struct bt_conn *conn = p1;
ARG_UNUSED(p2);
ARG_UNUSED(p3);
conn->timeout = NULL;
bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
bt_conn_unref(conn);
}
void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state)
{ {
bt_conn_state_t old_state; bt_conn_state_t old_state;
@ -1103,12 +1096,9 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state)
bt_conn_ref(conn); bt_conn_ref(conn);
break; break;
case BT_CONN_CONNECT: case BT_CONN_CONNECT:
if (conn->timeout) { if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) &&
k_thread_cancel(conn->timeout); conn->type == BT_CONN_TYPE_LE) {
conn->timeout = NULL; k_delayed_work_cancel(&conn->le.update_work);
/* Drop the reference taken by timeout thread */
bt_conn_unref(conn);
} }
break; break;
default: default:
@ -1169,15 +1159,12 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state)
* Timer is needed only for LE. For other link types controller * Timer is needed only for LE. For other link types controller
* will handle connection timeout. * will handle connection timeout.
*/ */
if (conn->type != BT_CONN_TYPE_LE) { if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) &&
break; conn->type == BT_CONN_TYPE_LE) {
k_delayed_work_submit(&conn->le.update_work,
CONN_TIMEOUT);
} }
/* Add LE Create Connection timeout */
conn->timeout = k_thread_spawn(conn->stack, sizeof(conn->stack),
timeout_thread,
bt_conn_ref(conn), NULL, NULL,
K_PRIO_COOP(7), 0, CONN_TIMEOUT);
break; break;
case BT_CONN_DISCONNECT: case BT_CONN_DISCONNECT:
break; break;
@ -1365,19 +1352,6 @@ static int bt_hci_disconnect(struct bt_conn *conn, uint8_t reason)
return 0; return 0;
} }
static int bt_hci_connect_le_cancel(struct bt_conn *conn)
{
if (conn->timeout) {
k_thread_cancel(conn->timeout);
conn->timeout = NULL;
/* Drop the reference took by timeout thread */
bt_conn_unref(conn);
}
return bt_hci_cmd_send(BT_HCI_OP_LE_CREATE_CONN_CANCEL, NULL);
}
int bt_conn_le_param_update(struct bt_conn *conn, int bt_conn_le_param_update(struct bt_conn *conn,
const struct bt_le_conn_param *param) const struct bt_le_conn_param *param)
{ {
@ -1435,7 +1409,13 @@ int bt_conn_disconnect(struct bt_conn *conn, uint8_t reason)
} }
#endif /* CONFIG_BLUETOOTH_BREDR */ #endif /* CONFIG_BLUETOOTH_BREDR */
return bt_hci_connect_le_cancel(conn); if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL)) {
k_delayed_work_cancel(&conn->le.update_work);
return bt_hci_cmd_send(BT_HCI_OP_LE_CREATE_CONN_CANCEL,
NULL);
}
return 0;
case BT_CONN_CONNECTED: case BT_CONN_CONNECTED:
return bt_hci_disconnect(conn, reason); return bt_hci_disconnect(conn, reason);
case BT_CONN_DISCONNECT: case BT_CONN_DISCONNECT:

View file

@ -45,7 +45,7 @@ struct bt_conn_le {
struct bt_keys *keys; struct bt_keys *keys;
/* Delayed work for connection update handling */ /* Delayed work for connection update and timeout handling */
struct k_delayed_work update_work; struct k_delayed_work update_work;
}; };
@ -96,9 +96,6 @@ struct bt_conn {
bt_conn_state_t state; bt_conn_state_t state;
/* Handle allowing to cancel timeout thread */
k_tid_t timeout;
union { union {
struct bt_conn_le le; struct bt_conn_le le;
#if defined(CONFIG_BLUETOOTH_BREDR) #if defined(CONFIG_BLUETOOTH_BREDR)