Skip to content

Commit e2961ee

Browse files
jori-nordiccvinayak
authored andcommitted
Bluetooth: L2CAP: Don't try to send on disconnected channel
We could start executing the work item after the channel has been disconnected or destroyed, due to a race condition. Double-check we are connected before attempting to send data. Signed-off-by: Jonathan Rico <[email protected]> (cherry picked from commit e436441) Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 96073b8 commit e2961ee

File tree

1 file changed

+21
-16
lines changed

1 file changed

+21
-16
lines changed

subsys/bluetooth/host/l2cap.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -924,13 +924,34 @@ static struct net_buf *l2cap_chan_le_get_tx_buf(struct bt_l2cap_le_chan *ch)
924924
static int l2cap_chan_le_send_sdu(struct bt_l2cap_le_chan *ch,
925925
struct net_buf **buf, uint16_t sent);
926926

927+
/** @brief Get @c chan->state.
928+
*
929+
* This field does not exist when @kconfig{CONFIG_BT_L2CAP_DYNAMIC_CHANNEL} is
930+
* disabled. In that case, this function returns @ref BT_L2CAP_CONNECTED since
931+
* the struct can only represent static channels in that case and static
932+
* channels are always connected.
933+
*/
934+
static bt_l2cap_chan_state_t bt_l2cap_chan_get_state(struct bt_l2cap_chan *chan)
935+
{
936+
#if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
937+
return BT_L2CAP_LE_CHAN(chan)->state;
938+
#else
939+
return BT_L2CAP_CONNECTED;
940+
#endif
941+
}
942+
927943
static void l2cap_chan_tx_process(struct k_work *work)
928944
{
929945
struct bt_l2cap_le_chan *ch;
930946
struct net_buf *buf;
931947

932948
ch = CONTAINER_OF(k_work_delayable_from_work(work), struct bt_l2cap_le_chan, tx_work);
933949

950+
if (bt_l2cap_chan_get_state(&ch->chan) != BT_L2CAP_CONNECTED) {
951+
LOG_DBG("Cannot send on non-connected channel");
952+
return;
953+
}
954+
934955
/* Resume tx in case there are buffers in the queue */
935956
while ((buf = l2cap_chan_le_get_tx_buf(ch))) {
936957
int sent = l2cap_tx_meta_data(buf)->sent;
@@ -2295,22 +2316,6 @@ static void l2cap_chan_shutdown(struct bt_l2cap_chan *chan)
22952316
}
22962317
}
22972318

2298-
/** @brief Get @c chan->state.
2299-
*
2300-
* This field does not exist when @kconfig{CONFIG_BT_L2CAP_DYNAMIC_CHANNEL} is
2301-
* disabled. In that case, this function returns @ref BT_L2CAP_CONNECTED since
2302-
* the struct can only represent static channels in that case and static
2303-
* channels are always connected.
2304-
*/
2305-
static inline bt_l2cap_chan_state_t bt_l2cap_chan_get_state(struct bt_l2cap_chan *chan)
2306-
{
2307-
#if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
2308-
return BT_L2CAP_LE_CHAN(chan)->state;
2309-
#else
2310-
return BT_L2CAP_CONNECTED;
2311-
#endif
2312-
}
2313-
23142319
static void l2cap_chan_send_credits(struct bt_l2cap_le_chan *chan,
23152320
uint16_t credits)
23162321
{

0 commit comments

Comments
 (0)