@@ -255,6 +255,8 @@ void bt_l2cap_chan_del(struct bt_l2cap_chan *chan)
255255 if (chan -> destroy ) {
256256 chan -> destroy (chan );
257257 }
258+
259+ atomic_clear (chan -> status );
258260}
259261
260262static void l2cap_rtx_timeout (struct k_work * work )
@@ -1503,6 +1505,44 @@ static int l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
15031505}
15041506
15051507#if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL )
1508+ static void l2cap_chan_shutdown (struct bt_l2cap_chan * chan )
1509+ {
1510+ struct bt_l2cap_le_chan * ch = BT_L2CAP_LE_CHAN (chan );
1511+ struct net_buf * buf ;
1512+
1513+ BT_DBG ("chan %p" , chan );
1514+
1515+ atomic_set_bit (chan -> status , BT_L2CAP_STATUS_SHUTDOWN );
1516+
1517+ /* Destroy segmented SDU if it exists */
1518+ if (ch -> _sdu ) {
1519+ net_buf_unref (ch -> _sdu );
1520+ ch -> _sdu = NULL ;
1521+ ch -> _sdu_len = 0U ;
1522+ }
1523+
1524+ /* Cleanup outstanding request */
1525+ if (ch -> tx_buf ) {
1526+ net_buf_unref (ch -> tx_buf );
1527+ ch -> tx_buf = NULL ;
1528+ }
1529+
1530+ /* Remove buffers on the TX queue */
1531+ while ((buf = net_buf_get (& ch -> tx_queue , K_NO_WAIT ))) {
1532+ net_buf_unref (buf );
1533+ }
1534+
1535+ /* Remove buffers on the RX queue */
1536+ while ((buf = net_buf_get (& ch -> rx_queue , K_NO_WAIT ))) {
1537+ net_buf_unref (buf );
1538+ }
1539+
1540+ /* Update status */
1541+ if (chan -> ops -> status ) {
1542+ chan -> ops -> status (chan , chan -> status );
1543+ }
1544+ }
1545+
15061546static void l2cap_chan_send_credits (struct bt_l2cap_le_chan * chan ,
15071547 struct net_buf * buf , u16_t credits )
15081548{
@@ -1517,7 +1557,10 @@ static void l2cap_chan_send_credits(struct bt_l2cap_le_chan *chan,
15171557 sizeof (* ev ));
15181558 if (!buf ) {
15191559 BT_ERR ("Unable to send credits update" );
1520- bt_l2cap_chan_disconnect (& chan -> chan );
1560+ /* Disconnect would probably not work either so the only
1561+ * option left is to shutdown the channel.
1562+ */
1563+ l2cap_chan_shutdown (& chan -> chan );
15211564 return ;
15221565 }
15231566
@@ -1727,6 +1770,12 @@ static void l2cap_chan_recv_queue(struct bt_l2cap_le_chan *chan,
17271770 return ;
17281771 }
17291772
1773+ if (atomic_test_bit (chan -> chan .status , BT_L2CAP_STATUS_SHUTDOWN )) {
1774+ BT_WARN ("Ignoring data received while channel has shutdown" );
1775+ net_buf_unref (buf );
1776+ return ;
1777+ }
1778+
17301779 net_buf_put (& chan -> rx_queue , buf );
17311780 k_work_submit (& chan -> rx_work );
17321781}
@@ -1956,6 +2005,10 @@ int bt_l2cap_chan_send(struct bt_l2cap_chan *chan, struct net_buf *buf)
19562005 return - ENOTCONN ;
19572006 }
19582007
2008+ if (atomic_test_bit (chan -> status , BT_L2CAP_STATUS_SHUTDOWN )) {
2009+ return - ESHUTDOWN ;
2010+ }
2011+
19592012 if (IS_ENABLED (CONFIG_BT_BREDR ) &&
19602013 chan -> conn -> type == BT_CONN_TYPE_BR ) {
19612014 return bt_l2cap_br_chan_send (chan , buf );
0 commit comments