Skip to content

Commit 7e54f13

Browse files
lylezhu2012nashif
authored andcommitted
Bluetooth: l2cap_br: Support Multi-Command Packet
Improve L2CAP BR to handle more than one signaling command in one receiving L2CAP packet. Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
1 parent 3561540 commit 7e54f13

File tree

1 file changed

+41
-22
lines changed

1 file changed

+41
-22
lines changed

subsys/bluetooth/host/classic/l2cap_br.c

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,31 +1833,15 @@ int bt_l2cap_br_chan_send(struct bt_l2cap_chan *chan, struct net_buf *buf)
18331833
return bt_l2cap_br_chan_send_cb(chan, buf, NULL, NULL);
18341834
}
18351835

1836-
static int l2cap_br_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
1836+
static void l2cap_br_sig_handle(struct bt_l2cap_br *l2cap, struct bt_l2cap_sig_hdr *hdr,
1837+
struct net_buf *buf)
18371838
{
1838-
struct bt_l2cap_br *l2cap = CONTAINER_OF(chan, struct bt_l2cap_br, chan.chan);
1839-
struct bt_l2cap_sig_hdr *hdr;
18401839
uint16_t len;
1840+
struct net_buf_simple_state state;
18411841

1842-
if (buf->len < sizeof(*hdr)) {
1843-
LOG_ERR("Too small L2CAP signaling PDU");
1844-
return 0;
1845-
}
1846-
1847-
hdr = net_buf_pull_mem(buf, sizeof(*hdr));
18481842
len = sys_le16_to_cpu(hdr->len);
18491843

1850-
LOG_DBG("Signaling code 0x%02x ident %u len %u", hdr->code, hdr->ident, len);
1851-
1852-
if (buf->len != len) {
1853-
LOG_ERR("L2CAP length mismatch (%u != %u)", buf->len, len);
1854-
return 0;
1855-
}
1856-
1857-
if (!hdr->ident) {
1858-
LOG_ERR("Invalid ident value in L2CAP PDU");
1859-
return 0;
1860-
}
1844+
net_buf_simple_save(&buf->b, &state);
18611845

18621846
switch (hdr->code) {
18631847
case BT_L2CAP_INFO_RSP:
@@ -1886,11 +1870,46 @@ static int l2cap_br_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
18861870
break;
18871871
default:
18881872
LOG_WRN("Unknown/Unsupported L2CAP PDU code 0x%02x", hdr->code);
1889-
l2cap_br_send_reject(chan->conn, hdr->ident,
1890-
BT_L2CAP_REJ_NOT_UNDERSTOOD, NULL, 0);
1873+
l2cap_br_send_reject(l2cap->chan.chan.conn, hdr->ident,
1874+
BT_L2CAP_REJ_NOT_UNDERSTOOD, NULL, 0);
18911875
break;
18921876
}
18931877

1878+
net_buf_simple_restore(&buf->b, &state);
1879+
(void)net_buf_pull_mem(buf, len);
1880+
}
1881+
1882+
static int l2cap_br_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
1883+
{
1884+
struct bt_l2cap_br *l2cap = CONTAINER_OF(chan, struct bt_l2cap_br, chan.chan);
1885+
struct bt_l2cap_sig_hdr *hdr;
1886+
uint16_t len;
1887+
1888+
while (buf->len > 0) {
1889+
if (buf->len < sizeof(*hdr)) {
1890+
LOG_ERR("Too small L2CAP signaling PDU");
1891+
return 0;
1892+
}
1893+
1894+
hdr = net_buf_pull_mem(buf, sizeof(*hdr));
1895+
len = sys_le16_to_cpu(hdr->len);
1896+
1897+
LOG_DBG("Signaling code 0x%02x ident %u len %u", hdr->code, hdr->ident, len);
1898+
1899+
if (buf->len < len) {
1900+
LOG_ERR("L2CAP length is short (%u < %u)", buf->len, len);
1901+
return 0;
1902+
}
1903+
1904+
if (!hdr->ident) {
1905+
LOG_ERR("Invalid ident value in L2CAP PDU");
1906+
(void)net_buf_pull_mem(buf, len);
1907+
continue;
1908+
}
1909+
1910+
l2cap_br_sig_handle(l2cap, hdr, buf);
1911+
}
1912+
18941913
return 0;
18951914
}
18961915

0 commit comments

Comments
 (0)