Commit c5623556 authored by Johan Hedberg's avatar Johan Hedberg Committed by Gustavo Padovan

Bluetooth: Handle LE L2CAP signalling in its own function

The LE L2CAP signalling channel follows its own rules and will continue
to evolve independently from the BR/EDR signalling channel. Therefore,
it makes sense to have a clear split from BR/EDR by having a dedicated
function for handling LE signalling commands.
Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
parent b887664d
...@@ -5292,7 +5292,7 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, ...@@ -5292,7 +5292,7 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
} }
} }
static inline void l2cap_sig_channel(struct l2cap_conn *conn, static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
struct sk_buff *skb) struct sk_buff *skb)
{ {
u8 *data = skb->data; u8 *data = skb->data;
...@@ -5318,11 +5318,52 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, ...@@ -5318,11 +5318,52 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn,
break; break;
} }
if (conn->hcon->type == LE_LINK)
err = l2cap_le_sig_cmd(conn, &cmd, data); err = l2cap_le_sig_cmd(conn, &cmd, data);
else if (err) {
err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); struct l2cap_cmd_rej_unk rej;
BT_ERR("Wrong link type (%d)", err);
/* FIXME: Map err to a valid reason */
rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
sizeof(rej), &rej);
}
data += cmd_len;
len -= cmd_len;
}
kfree_skb(skb);
}
static inline void l2cap_sig_channel(struct l2cap_conn *conn,
struct sk_buff *skb)
{
u8 *data = skb->data;
int len = skb->len;
struct l2cap_cmd_hdr cmd;
int err;
l2cap_raw_recv(conn, skb);
while (len >= L2CAP_CMD_HDR_SIZE) {
u16 cmd_len;
memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
data += L2CAP_CMD_HDR_SIZE;
len -= L2CAP_CMD_HDR_SIZE;
cmd_len = le16_to_cpu(cmd.len);
BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
cmd.ident);
if (cmd_len > len || !cmd.ident) {
BT_DBG("corrupted command");
break;
}
err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
if (err) { if (err) {
struct l2cap_cmd_rej_unk rej; struct l2cap_cmd_rej_unk rej;
...@@ -6395,6 +6436,8 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -6395,6 +6436,8 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
switch (cid) { switch (cid) {
case L2CAP_CID_LE_SIGNALING: case L2CAP_CID_LE_SIGNALING:
l2cap_le_sig_channel(conn, skb);
break;
case L2CAP_CID_SIGNALING: case L2CAP_CID_SIGNALING:
l2cap_sig_channel(conn, skb); l2cap_sig_channel(conn, skb);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment