Bluetooth: RFCOMM: Handle session disconnection from peer

UA response will be sent and session will be cleaned up.
Session will also be cleaned up if l2cap channel is disconnected.

> ACL Data RX: Handle 256 flags 0x02 dlen 8
      Channel: 64 len 4 [PSM 3 mode 0] {chan 0}
      RFCOMM: Disconnect (DISC) (0x43)
         Address: 0x03 cr 1 dlci 0x00
         Control: 0x53 poll/final 1
         Length: 0
         FCS: 0xfd

< ACL Data TX: Handle 256 flags 0x00 dlen 8
      Channel: 64 len 4 [PSM 3 mode 0] {chan 0}
      RFCOMM: Unnumbered Ack (UA) (0x63)
         Address: 0x03 cr 1 dlci 0x00
         Control: 0x73 poll/final 1
         Length: 0
         FCS: 0xd7

Change-Id: I44997d7d13c90a2a0814520ea11e6f14bc60271f
Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
This commit is contained in:
Jaganath Kanakkassery 2016-09-21 18:35:22 +05:30 committed by Johan Hedberg
commit 58d47f0b99

View file

@ -276,6 +276,32 @@ static void rfcomm_dlc_disconnected(struct bt_rfcomm_dlc *dlc)
rfcomm_dlc_unref(dlc);
}
static void rfcomm_session_disconnected(struct bt_rfcomm_session *session)
{
struct bt_rfcomm_dlc *dlc;
BT_DBG("Session %p", session);
if (session->state == BT_RFCOMM_STATE_DISCONNECTED) {
return;
}
for (dlc = session->dlcs; dlc;) {
struct bt_rfcomm_dlc *next;
/* prefetch since disconnected callback may cleanup */
next = dlc->_next;
dlc->_next = NULL;
rfcomm_dlc_disconnected(dlc);
dlc = next;
}
session->state = BT_RFCOMM_STATE_DISCONNECTED;
session->dlcs = NULL;
}
struct net_buf *bt_rfcomm_create_pdu(struct nano_fifo *fifo)
{
/* Length in RFCOMM header can be 2 bytes depending on length of user
@ -328,7 +354,12 @@ static void rfcomm_connected(struct bt_l2cap_chan *chan)
static void rfcomm_disconnected(struct bt_l2cap_chan *chan)
{
BT_DBG("Session %p", RFCOMM_SESSION(chan));
struct bt_rfcomm_session *session = RFCOMM_SESSION(chan);
BT_DBG("Session %p", session);
rfcomm_session_disconnected(session);
session->state = BT_RFCOMM_STATE_IDLE;
}
static struct bt_rfcomm_dlc *rfcomm_dlc_accept(struct bt_rfcomm_session *session,
@ -626,6 +657,9 @@ static void rfcomm_handle_disc(struct bt_rfcomm_session *session, uint8_t dlci)
rfcomm_send_ua(session, dlci);
rfcomm_dlc_disconnected(dlc);
} else {
rfcomm_send_ua(session, 0);
rfcomm_session_disconnected(session);
}
}