Bluetooth: L2CAP: Add bt_l2cap_chan_disconnect
This adds bt_l2cap_chan_disconnect which can be used to disconnect dynamic channels resulting in the following trace: < ACL Data TX: Handle 3585 flags 0x00 dlen 12 LE L2CAP: Disconnection Request (0x06) ident 2 len 4 Destination CID: 64 Source CID: 64 > ACL Data RX: Handle 3585 flags 0x02 dlen 12 LE L2CAP: Disconnection Response (0x07) ident 2 len 4 Destination CID: 64 Source CID: 64 Change-Id: I77ec29c8879a330b7f73e217621436045fa5163e Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
2902d5c3c3
commit
a983eff168
2 changed files with 74 additions and 0 deletions
|
@ -118,6 +118,17 @@ int bt_l2cap_server_register(struct bt_l2cap_server *server);
|
|||
int bt_l2cap_chan_connect(struct bt_conn *conn, struct bt_l2cap_chan *chan,
|
||||
uint16_t psm);
|
||||
|
||||
/** @brief Disconnect L2CAP channel
|
||||
*
|
||||
* Disconnect L2CAP channel, if the connection is pending it will be
|
||||
* canceled.
|
||||
*
|
||||
* @param chan Channel object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_l2cap_chan_disconnect(struct bt_l2cap_chan *chan);
|
||||
|
||||
#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */
|
||||
#endif /* CONFIG_BLUETOOTH_CENTRAL || CONFIG_BLUETOOTH_PERIPHERAL */
|
||||
#endif /* __BT_L2CAP_H */
|
||||
|
|
|
@ -615,6 +615,32 @@ static void le_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
|
|||
l2cap_chan_del(chan);
|
||||
}
|
||||
}
|
||||
|
||||
static void le_disconn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
|
||||
struct net_buf *buf)
|
||||
{
|
||||
struct bt_conn *conn = l2cap->chan.conn;
|
||||
struct bt_l2cap_chan *chan;
|
||||
struct bt_l2cap_disconn_rsp *rsp = (void *)buf->data;
|
||||
uint16_t dcid, scid;
|
||||
|
||||
if (buf->len < sizeof(*rsp)) {
|
||||
BT_ERR("Too small LE disconn rsp packet size\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dcid = sys_le16_to_cpu(rsp->dcid);
|
||||
scid = sys_le16_to_cpu(rsp->scid);
|
||||
|
||||
BT_DBG("dcid 0x%04x scid 0x%04x\n", dcid, scid);
|
||||
|
||||
chan = l2cap_remove_tx_cid(conn, scid);
|
||||
if (!chan) {
|
||||
return;
|
||||
}
|
||||
|
||||
l2cap_chan_del(chan);
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */
|
||||
|
||||
static void l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
|
||||
|
@ -663,6 +689,9 @@ static void l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
|
|||
case BT_L2CAP_DISCONN_REQ:
|
||||
le_disconn_req(l2cap, hdr->ident, buf);
|
||||
break;
|
||||
case BT_L2CAP_DISCONN_RSP:
|
||||
le_disconn_rsp(l2cap, hdr->ident, buf);
|
||||
break;
|
||||
#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */
|
||||
default:
|
||||
BT_WARN("Unknown L2CAP PDU code 0x%02x\n", hdr->code);
|
||||
|
@ -956,4 +985,38 @@ int bt_l2cap_chan_connect(struct bt_conn *conn, struct bt_l2cap_chan *chan,
|
|||
/* TODO: Check conn/address type when BR/EDR is introduced */
|
||||
return l2cap_le_connect(conn, chan, psm);
|
||||
}
|
||||
|
||||
int bt_l2cap_chan_disconnect(struct bt_l2cap_chan *chan)
|
||||
{
|
||||
struct bt_conn *conn = chan->conn;
|
||||
struct net_buf *buf;
|
||||
struct bt_l2cap_disconn_req *req;
|
||||
struct bt_l2cap_sig_hdr *hdr;
|
||||
|
||||
BT_DBG("chan %p scid 0x%04x dcid 0x%04x\n", chan, chan->rx.cid,
|
||||
chan->tx.cid);
|
||||
|
||||
if (!conn) {
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
buf = bt_l2cap_create_pdu(&le_sig);
|
||||
if (!buf) {
|
||||
BT_ERR("Unable to send L2CP disconnect request\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hdr = net_buf_add(buf, sizeof(*hdr));
|
||||
hdr->code = BT_L2CAP_DISCONN_REQ;
|
||||
hdr->ident = get_ident(conn);
|
||||
hdr->len = sys_cpu_to_le16(sizeof(*req));
|
||||
|
||||
req = net_buf_add(buf, sizeof(*req));
|
||||
req->dcid = sys_cpu_to_le16(chan->tx.cid);
|
||||
req->scid = sys_cpu_to_le16(chan->rx.cid);
|
||||
|
||||
bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue