All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/3] Implements hci_reassembly to reassemble Rx packets
@ 2010-07-09 10:49 suraj
  2010-07-09 10:51 ` [PATCH v4 2/3] Modified hci_recv_fragment() to use hci_reassembly suraj
  2010-07-09 13:16 ` [PATCH v4 1/3] Implements hci_reassembly to reassemble Rx packets Marcel Holtmann
  0 siblings, 2 replies; 5+ messages in thread
From: suraj @ 2010-07-09 10:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, Luis.Rodriguez, Jothikumar.Mothilal

Implements feature to reassemble HCI frames received from an input stream.

Signed-off-by: Suraj Sumangala <suraj@atheros.com>
---
 net/bluetooth/hci_core.c |  115 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5e83f8e..3eb4c1b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1030,6 +1030,121 @@ int hci_recv_frame(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(hci_recv_frame);
 
+static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
+			  int count, struct sk_buff **skb_ptr, int *remain)
+{
+	int len = 0;
+	int header_len = 0;
+	struct sk_buff *skb = *skb_ptr;
+	struct { struct bt_skb_cb cb_info; int expect; } *scb;
+
+	*remain = count;
+
+	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
+		return -EILSEQ;
+
+	if (!skb) {
+
+		switch (type) {
+		case HCI_ACLDATA_PKT:
+			len = HCI_MAX_FRAME_SIZE;
+			header_len = HCI_ACL_HDR_SIZE;
+		break;
+		case HCI_EVENT_PKT:
+			len = HCI_MAX_EVENT_SIZE;
+			header_len = HCI_EVENT_HDR_SIZE;
+		break;
+		case HCI_SCODATA_PKT:
+			len = HCI_MAX_SCO_SIZE;
+			header_len = HCI_SCO_HDR_SIZE;
+		break;
+		}
+
+		skb = bt_skb_alloc(len, GFP_ATOMIC);
+
+		if (!skb)
+			return -ENOMEM;
+
+		scb = (void *) skb->cb;
+		scb->expect = header_len;
+		scb->cb_info.pkt_type = (__u8)type;
+
+		skb->dev = (void *) hdev;
+		*skb_ptr = skb;
+
+	}
+
+	while (count) {
+
+		scb = (void *) skb->cb;
+		len = min(scb->expect, count);
+
+		memcpy(skb_put(skb, len), data, len);
+
+		count -= len;
+		data += len;
+		scb->expect -= len;
+		*remain = count;
+
+		switch (type) {
+		case HCI_EVENT_PKT:
+			if (skb->len == HCI_EVENT_HDR_SIZE) {
+				struct hci_event_hdr *h = hci_event_hdr(skb);
+				scb->expect = h->plen;
+
+				if (skb_tailroom(skb) < scb->expect) {
+					kfree_skb(skb);
+					*skb_ptr = NULL;
+
+					return -ENOMEM;
+				}
+			}
+			break;
+
+		case HCI_ACLDATA_PKT:
+			if (skb->len  == HCI_ACL_HDR_SIZE) {
+				struct hci_acl_hdr *h = hci_acl_hdr(skb);
+				scb->expect = __le16_to_cpu(h->dlen);
+
+				if (skb_tailroom(skb) < scb->expect) {
+					kfree_skb(skb);
+					*skb_ptr = NULL;
+
+					return -ENOMEM;
+				}
+			}
+			break;
+
+		case HCI_SCODATA_PKT:
+			if (skb->len == HCI_SCO_HDR_SIZE) {
+				struct hci_sco_hdr *h = hci_sco_hdr(skb);
+				scb->expect = h->dlen;
+
+				if (skb_tailroom(skb) < scb->expect) {
+					kfree_skb(skb);
+					*skb_ptr = NULL;
+
+					return -ENOMEM;
+				}
+			}
+			break;
+		}
+
+		if (scb->expect == 0) {
+
+			/* Complete frame */
+			bt_cb(skb)->pkt_type = type;
+			hci_recv_frame(skb);
+
+			*skb_ptr = NULL;
+
+			return 0;
+		}
+
+	}
+
+	return 0;
+}
 /* Receive packet type fragment */
 #define __reassembly(hdev, type)  ((hdev)->reassembly[(type) - 2])
 
-- 
1.7.0.4




^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-07-09 13:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-09 10:49 [PATCH v4 1/3] Implements hci_reassembly to reassemble Rx packets suraj
2010-07-09 10:51 ` [PATCH v4 2/3] Modified hci_recv_fragment() to use hci_reassembly suraj
2010-07-09 10:53   ` [PATCH v4 3/3] Implemented HCI frame reassembly for Rx from stream suraj
2010-07-09 12:59     ` Gustavo F. Padovan
2010-07-09 13:16 ` [PATCH v4 1/3] Implements hci_reassembly to reassemble Rx packets Marcel Holtmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.