void bt_l2cap_recv(struct bt_conn *conn, struct net_buf *buf) { struct bt_l2cap_hdr *hdr = (void *)buf->data; struct bt_l2cap_chan *chan; uint16_t cid; if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && conn->type == BT_CONN_TYPE_BR) { bt_l2cap_br_recv(conn, buf); return; } if (buf->len < sizeof(*hdr)) { BT_ERR("Too small L2CAP PDU received"); net_buf_unref(buf); return; } cid = sys_le16_to_cpu(hdr->cid); net_buf_pull(buf, sizeof(*hdr)); BT_DBG("Packet for CID %u len %u", cid, buf->len); chan = bt_l2cap_le_lookup_rx_cid(conn, cid); if (!chan) { BT_WARN("Ignoring data for unknown CID 0x%04x", cid); net_buf_unref(buf); return; } l2cap_chan_recv(chan, buf); net_buf_unref(buf); }
void bt_l2cap_recv(struct bt_conn *conn, struct net_buf *buf) { struct bt_l2cap_hdr *hdr = (void *)buf->data; struct bt_l2cap_chan *chan; uint16_t cid; if (buf->len < sizeof(*hdr)) { BT_ERR("Too small L2CAP PDU received"); net_buf_unref(buf); return; } cid = sys_le16_to_cpu(hdr->cid); net_buf_pull(buf, sizeof(*hdr)); BT_DBG("Packet for CID %u len %u", cid, buf->len); switch (conn->type) { case BT_CONN_TYPE_LE: chan = bt_l2cap_le_lookup_rx_cid(conn, cid); break; #if defined(CONFIG_BLUETOOTH_BREDR) case BT_CONN_TYPE_BR: chan = bt_l2cap_br_lookup_rx_cid(conn, cid); break; #endif /* CONFIG_BLUETOOTH_BREDR */ default: chan = NULL; break; } if (!chan) { BT_WARN("Ignoring data for unknown CID 0x%04x", cid); net_buf_unref(buf); return; } l2cap_chan_recv(chan, buf); net_buf_unref(buf); }
static struct bt_l2cap_le_chan *l2cap_chan_alloc_cid(struct bt_conn *conn, struct bt_l2cap_chan *chan) { struct bt_l2cap_le_chan *ch = LE_CHAN(chan); uint16_t cid; /* * No action needed if there's already a CID allocated, e.g. in * the case of a fixed channel. */ if (ch && ch->rx.cid > 0) { return ch; } for (cid = L2CAP_LE_DYN_CID_START; cid <= L2CAP_LE_DYN_CID_END; cid++) { if (ch && !bt_l2cap_le_lookup_rx_cid(conn, cid)) { ch->rx.cid = cid; return ch; } } return NULL; }