Bluetooth: RFCOMM: Disconnect session after last dlc disconnection
As per the spec the station which disconnects last dlc should initiate session disconnection and then l2cap disconnection. < ACL Data TX: Handle 256 flags 0x00 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 RX: Handle 256 flags 0x02 dlen 8 Channel: 64 len 4 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Ack (UA) (0x63) Address: 0x01 cr 0 dlci 0x00 Control: 0x73 poll/final 1 Length: 0 FCS: 0xb6 Change-Id: I2d1d7d284995529d5d1522e0ca6082097db19bc2 Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
This commit is contained in:
parent
bc8ec12977
commit
a95de4360c
1 changed files with 34 additions and 10 deletions
|
@ -804,23 +804,46 @@ static int rfcomm_dlc_start(struct bt_rfcomm_dlc *dlc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void rfcomm_session_disconnect(struct bt_rfcomm_session *session)
|
||||
{
|
||||
if (session->dlcs) {
|
||||
return;
|
||||
}
|
||||
|
||||
session->state = BT_RFCOMM_STATE_DISCONNECTING;
|
||||
rfcomm_send_disc(session, 0);
|
||||
}
|
||||
|
||||
static void rfcomm_handle_ua(struct bt_rfcomm_session *session, uint8_t dlci)
|
||||
{
|
||||
struct bt_rfcomm_dlc *dlc, *tmp;
|
||||
int err;
|
||||
|
||||
if (!dlci) {
|
||||
if (session->state != BT_RFCOMM_STATE_CONNECTING) {
|
||||
return;
|
||||
}
|
||||
session->state = BT_RFCOMM_STATE_CONNECTED;
|
||||
for (dlc = session->dlcs; dlc; dlc = tmp) {
|
||||
tmp = dlc->_next;
|
||||
if (dlc->role == BT_RFCOMM_ROLE_INITIATOR &&
|
||||
dlc->state == BT_RFCOMM_STATE_INIT) {
|
||||
if (rfcomm_dlc_start(dlc) < 0) {
|
||||
rfcomm_dlc_drop(dlc);
|
||||
switch (session->state) {
|
||||
case BT_RFCOMM_STATE_CONNECTING:
|
||||
session->state = BT_RFCOMM_STATE_CONNECTED;
|
||||
for (dlc = session->dlcs; dlc; dlc = tmp) {
|
||||
tmp = dlc->_next;
|
||||
if (dlc->role == BT_RFCOMM_ROLE_INITIATOR &&
|
||||
dlc->state == BT_RFCOMM_STATE_INIT) {
|
||||
if (rfcomm_dlc_start(dlc) < 0) {
|
||||
rfcomm_dlc_drop(dlc);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Disconnect session if there is no dlcs left */
|
||||
rfcomm_session_disconnect(session);
|
||||
break;
|
||||
case BT_RFCOMM_STATE_DISCONNECTING:
|
||||
session->state = BT_RFCOMM_STATE_DISCONNECTED;
|
||||
err = bt_l2cap_chan_disconnect(&session->br_chan.chan);
|
||||
if (err < 0) {
|
||||
session->state = BT_RFCOMM_STATE_IDLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci);
|
||||
|
@ -834,6 +857,7 @@ static void rfcomm_handle_ua(struct bt_rfcomm_session *session, uint8_t dlci)
|
|||
break;
|
||||
case BT_RFCOMM_STATE_DISCONNECTING:
|
||||
rfcomm_dlc_drop(dlc);
|
||||
rfcomm_session_disconnect(session);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue