Bluetooth: L2CAP: Enable handle BR/EDR signal channel traffic
Separates LE and BR/EDR L2CAP signal channel context and starts accept incoming PDU traffic on BR/EDR signal channel. For now all valid L2CAP commands are send back as rejected on BR/EDR signal channel. Change-Id: If4392b2d3ccbe157cb7eeafcaa0804e90f44e2be Signed-off-by: Arkadiusz Lichwa <arkadiusz.lichwa@tieto.com>
This commit is contained in:
parent
32da5e6748
commit
742c71a186
1 changed files with 108 additions and 1 deletions
|
@ -57,6 +57,15 @@ static NET_BUF_POOL(br_sig_pool, CONFIG_BLUETOOTH_MAX_CONN,
|
|||
BT_L2CAP_BUF_SIZE(L2CAP_BR_MIN_MTU), &br_sig, NULL,
|
||||
BT_BUF_USER_DATA_MIN);
|
||||
|
||||
/* BR/EDR L2CAP signalling channel specific context */
|
||||
struct bt_l2cap {
|
||||
/* The channel this context is associated with */
|
||||
struct bt_l2cap_chan chan;
|
||||
uint8_t ident;
|
||||
};
|
||||
|
||||
static struct bt_l2cap bt_l2cap_br_pool[CONFIG_BLUETOOTH_MAX_CONN];
|
||||
|
||||
static void l2cap_br_chan_alloc_cid(struct bt_conn *conn,
|
||||
struct bt_l2cap_chan *chan)
|
||||
{
|
||||
|
@ -162,6 +171,104 @@ int bt_l2cap_br_server_register(struct bt_l2cap_server *server)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void l2cap_br_send_reject(struct bt_conn *conn, uint8_t ident,
|
||||
uint16_t reason)
|
||||
{
|
||||
struct bt_l2cap_cmd_reject *rej;
|
||||
struct bt_l2cap_sig_hdr *hdr;
|
||||
struct net_buf *buf;
|
||||
|
||||
buf = bt_l2cap_create_pdu(&br_sig);
|
||||
if (!buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
hdr = net_buf_add(buf, sizeof(*hdr));
|
||||
hdr->code = BT_L2CAP_CMD_REJECT;
|
||||
hdr->ident = ident;
|
||||
hdr->len = sys_cpu_to_le16(sizeof(*rej));
|
||||
|
||||
rej = net_buf_add(buf, sizeof(*rej));
|
||||
rej->reason = sys_cpu_to_le16(reason);
|
||||
|
||||
bt_l2cap_send(conn, BT_L2CAP_CID_BR_SIG, buf);
|
||||
}
|
||||
|
||||
static void l2cap_br_connected(struct bt_l2cap_chan *chan)
|
||||
{
|
||||
BT_DBG("chan %p cid 0x%04x", chan, chan->rx.cid);
|
||||
}
|
||||
|
||||
static void l2cap_br_disconnected(struct bt_l2cap_chan *chan)
|
||||
{
|
||||
BT_DBG("chan %p cid 0x%04x", chan, chan->rx.cid);
|
||||
}
|
||||
|
||||
static void l2cap_br_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
|
||||
{
|
||||
struct bt_l2cap_sig_hdr *hdr = (void *)buf->data;
|
||||
uint16_t len;
|
||||
|
||||
if (buf->len < sizeof(*hdr)) {
|
||||
BT_ERR("Too small L2CAP signaling PDU");
|
||||
return;
|
||||
}
|
||||
|
||||
len = sys_le16_to_cpu(hdr->len);
|
||||
net_buf_pull(buf, sizeof(*hdr));
|
||||
|
||||
BT_DBG("Signaling code 0x%02x ident %u len %u", hdr->code,
|
||||
hdr->ident, len);
|
||||
|
||||
if (buf->len != len) {
|
||||
BT_ERR("L2CAP length mismatch (%u != %u)", buf->len, len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hdr->ident) {
|
||||
BT_ERR("Invalid ident value in L2CAP PDU");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (hdr->code) {
|
||||
default:
|
||||
BT_WARN("Unknown/Unsupported L2CAP PDU code 0x%02x", hdr->code);
|
||||
l2cap_br_send_reject(chan->conn, hdr->ident,
|
||||
BT_L2CAP_REJ_NOT_UNDERSTOOD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int l2cap_br_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan)
|
||||
{
|
||||
int i;
|
||||
static struct bt_l2cap_chan_ops ops = {
|
||||
.connected = l2cap_br_connected,
|
||||
.disconnected = l2cap_br_disconnected,
|
||||
.recv = l2cap_br_recv,
|
||||
};
|
||||
|
||||
BT_DBG("conn %p handle %u", conn, conn->handle);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bt_l2cap_br_pool); i++) {
|
||||
struct bt_l2cap *l2cap = &bt_l2cap_br_pool[i];
|
||||
|
||||
if (l2cap->chan.conn) {
|
||||
continue;
|
||||
}
|
||||
|
||||
l2cap->chan.ops = &ops;
|
||||
|
||||
*chan = &l2cap->chan;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BT_ERR("No available L2CAP context for conn %p", conn);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void bt_l2cap_br_fixed_chan_register(struct bt_l2cap_fixed_chan *chan)
|
||||
{
|
||||
BT_DBG("CID 0x%04x", chan->cid);
|
||||
|
@ -175,7 +282,7 @@ void bt_l2cap_br_init(void)
|
|||
static struct bt_l2cap_fixed_chan chan_br = {
|
||||
.cid = BT_L2CAP_CID_BR_SIG,
|
||||
.mask = BT_L2CAP_MASK_BR_SIG,
|
||||
.accept = NULL,
|
||||
.accept = l2cap_br_accept,
|
||||
};
|
||||
|
||||
net_buf_pool_init(br_sig_pool);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue