summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2012-10-15 11:58:40 +0300
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2012-10-15 09:46:39 -0300
commitd73a098804b4d1d254b1caf1d114e5b707dee060 (patch)
tree019ccd495a41af86b8890a0aed7038ff4ba1cb91
parent204a6e54280d53e6990e536998fbf8dfba41ecd3 (diff)
Bluetooth: AMP: Handle complete frames in l2cap
Check flags type in switch statement and handle new frame type ACL_COMPLETE used for High Speed data over AMP. Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
-rw-r--r--include/net/bluetooth/hci.h1
-rw-r--r--net/bluetooth/l2cap_core.c15
2 files changed, 11 insertions, 5 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 77b6a197a6f6..88cbbda61027 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -198,6 +198,7 @@ enum {
#define ACL_START_NO_FLUSH 0x00
#define ACL_CONT 0x01
#define ACL_START 0x02
+#define ACL_COMPLETE 0x03
#define ACL_ACTIVE_BCAST 0x04
#define ACL_PICO_BCAST 0x08
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index fca407e17f16..8faa3121bb44 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5568,6 +5568,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
{
struct l2cap_conn *conn = hcon->l2cap_data;
+ struct l2cap_hdr *hdr;
+ int len;
if (!conn)
conn = l2cap_conn_add(hcon, 0);
@@ -5577,10 +5579,10 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
- if (!(flags & ACL_CONT)) {
- struct l2cap_hdr *hdr;
- int len;
-
+ switch (flags) {
+ case ACL_START:
+ case ACL_START_NO_FLUSH:
+ case ACL_COMPLETE:
if (conn->rx_len) {
BT_ERR("Unexpected start frame (len %d)", skb->len);
kfree_skb(conn->rx_skb);
@@ -5622,7 +5624,9 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
skb->len);
conn->rx_len = len - skb->len;
- } else {
+ break;
+
+ case ACL_CONT:
BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
if (!conn->rx_len) {
@@ -5650,6 +5654,7 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
l2cap_recv_frame(conn, conn->rx_skb);
conn->rx_skb = NULL;
}
+ break;
}
drop: