2010-06-01 08:04:00

by Suraj Sumangala

[permalink] [raw]
Subject: [PATCH 1/3] Rename hci_recv_fragment to hci_recv_packet_fragment

Renaming hci_recv_fragment to hci_recv_packet_fragment as it will be used
only for reassembling HCI fragments with know packet type.

Signed-off-by: suraj <[email protected]>
---
include/net/bluetooth/hci_core.h | 3 ++-
net/bluetooth/hci_core.c | 5 +++--
2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e42f6ed..65c3c13 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -427,7 +427,8 @@ int hci_inquiry(void __user *arg);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);

int hci_recv_frame(struct sk_buff *skb);
-int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
+int hci_recv_packet_fragment(struct hci_dev *hdev, int type, void *data,
+ int count);

int hci_register_sysfs(struct hci_dev *hdev);
void hci_unregister_sysfs(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5e83f8e..e7ce432 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1033,7 +1033,8 @@ EXPORT_SYMBOL(hci_recv_frame);
/* Receive packet type fragment */
#define __reassembly(hdev, type) ((hdev)->reassembly[(type) - 2])

-int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
+int hci_recv_packet_fragment(struct hci_dev *hdev, int type, void *data,
+ int count)
{
if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
return -EILSEQ;
@@ -1112,7 +1113,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)

return 0;
}
-EXPORT_SYMBOL(hci_recv_fragment);
+EXPORT_SYMBOL(hci_recv_packet_fragment);

/* ---- Interface to upper protocols ---- */

--
1.7.0


2010-06-02 04:11:04

by Suraj Sumangala

[permalink] [raw]
Subject: Re: [PATCH 2/3] Replace hci_recv_fragment calls

Hi Marcel,

On 6/2/2010 3:29 AM, Marcel Holtmann wrote:
> Hi Luis,
>
>>>> You want to unify patches 1 and 2. Patches upstream should be atomic so that if you apply it, it should make everything still work. Your first patch removes hci_recv_fragment() and then this one fixes the places that call it, you want to do both in one shot.
>>>
>>> actually I prefer to leave these two patches out for now. Since the
>>> renaming could be done easily later. The important part is actually the
>>> other implementation.
>>
>> Won't that break compilation on the first patch since all existing
>> code users no longer have the exported symbol available?
>
> no. The important change here is for the H4 specific stream fragment
> handling. The rest is just a renaming. So 3/3 is the important patch and
> 1/2 and 2/2 are just cosmetic changes.
>
> Regards
>
> Marcel
>
>

I will send 3/3 as a separate patch for you to verify.

Regards
Suraj

2010-06-01 21:59:09

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH 2/3] Replace hci_recv_fragment calls

Hi Luis,

> > > You want to unify patches 1 and 2. Patches upstream should be atomic so that if you apply it, it should make everything still work. Your first patch removes hci_recv_fragment() and then this one fixes the places that call it, you want to do both in one shot.
> >
> > actually I prefer to leave these two patches out for now. Since the
> > renaming could be done easily later. The important part is actually the
> > other implementation.
>
> Won't that break compilation on the first patch since all existing
> code users no longer have the exported symbol available?

no. The important change here is for the H4 specific stream fragment
handling. The rest is just a renaming. So 3/3 is the important patch and
1/2 and 2/2 are just cosmetic changes.

Regards

Marcel



2010-06-01 20:51:20

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 2/3] Replace hci_recv_fragment calls

On Tue, Jun 01, 2010 at 12:59:13PM -0700, Marcel Holtmann wrote:
> Hi Luis,
>
> > You want to unify patches 1 and 2. Patches upstream should be atomic so that if you apply it, it should make everything still work. Your first patch removes hci_recv_fragment() and then this one fixes the places that call it, you want to do both in one shot.
>
> actually I prefer to leave these two patches out for now. Since the
> renaming could be done easily later. The important part is actually the
> other implementation.

Won't that break compilation on the first patch since all existing
code users no longer have the exported symbol available?

Luis

2010-06-01 19:59:13

by Marcel Holtmann

[permalink] [raw]
Subject: RE: [PATCH 2/3] Replace hci_recv_fragment calls

Hi Luis,

> You want to unify patches 1 and 2. Patches upstream should be atomic so that if you apply it, it should make everything still work. Your first patch removes hci_recv_fragment() and then this one fixes the places that call it, you want to do both in one shot.

actually I prefer to leave these two patches out for now. Since the
renaming could be done easily later. The important part is actually the
other implementation.

Regards

Marcel



2010-06-01 14:29:33

by Luis Rodriguez

[permalink] [raw]
Subject: RE: [PATCH 2/3] Replace hci_recv_fragment calls


You want to unify patches 1 and 2. Patches upstream should be atomic so tha=
t if you apply it, it should make everything still work. Your first patch =
removes hci_recv_fragment() and then this one fixes the places that call it=
, you want to do both in one shot.

Luis
________________________________________
From: Suraj Sumangala
Sent: Tuesday, June 01, 2010 1:08 AM
To: [email protected]
Cc: [email protected]; Luis Rodriguez; Jothikumar Mothilal
Subject: [PATCH 2/3] Replace hci_recv_fragment calls

Replace all usages of hci_recv_fragment calls with
hci_recv_packet_fragment


Signed-off-by: suraj <[email protected]>
---
drivers/bluetooth/btusb.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 5d9cc53..50aa8d1 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -211,7 +211,7 @@ static void btusb_intr_complete(struct urb *urb)
if (urb->status =3D=3D 0) {
hdev->stat.byte_rx +=3D urb->actual_length;

- if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_EVENT_PKT,
urb->transfer_buffer,
urb->actual_length) < 0) {
BT_ERR("%s corrupted event packet", hdev->name);
@@ -295,7 +295,7 @@ static void btusb_bulk_complete(struct urb *urb)
if (urb->status =3D=3D 0) {
hdev->stat.byte_rx +=3D urb->actual_length;

- if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_ACLDATA_PKT,
urb->transfer_buffer,
urb->actual_length) < 0) {
BT_ERR("%s corrupted ACL packet", hdev->name);
@@ -384,7 +384,7 @@ static void btusb_isoc_complete(struct urb *urb)

hdev->stat.byte_rx +=3D length;

- if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_SCODATA_PKT,
urb->transfer_buffer + offs=
et,
length) < 0=
) {
BT_ERR("%s corrupted SCO packet", hdev->nam=
e);
--
1.7.0

2010-06-01 08:11:51

by Suraj Sumangala

[permalink] [raw]
Subject: [PATCH 3/3] frame reassembly implementation for data from stream

Implemented hci_recv_stream_fragment to reassemble HCI packets received from a data stream
with packet type not known.

Signed-off-by: suraj <[email protected]>
---
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_core.c | 104 ++++++++++++++++++++++++++++++++++++++
2 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 65c3c13..9892c26 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -429,6 +429,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
int hci_recv_frame(struct sk_buff *skb);
int hci_recv_packet_fragment(struct hci_dev *hdev, int type, void *data,
int count);
+int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count);

int hci_register_sysfs(struct hci_dev *hdev);
void hci_unregister_sysfs(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e7ce432..1587dc8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1033,6 +1033,110 @@ EXPORT_SYMBOL(hci_recv_frame);
/* Receive packet type fragment */
#define __reassembly(hdev, type) ((hdev)->reassembly[(type) - 2])

+#define __get_max_rx_size(type) \
+ (((type) == HCI_ACLDATA_PKT) ? \
+ HCI_MAX_FRAME_SIZE : \
+ ((type) == HCI_EVENT_PKT) ? HCI_MAX_EVENT_SIZE :\
+ HCI_MAX_SCO_SIZE)
+
+#define __get_header_len(type) \
+ (((type) == HCI_ACLDATA_PKT) ? \
+ HCI_ACL_HDR_SIZE : \
+ ((type) == HCI_EVENT_PKT) ? HCI_EVENT_HDR_SIZE :\
+ HCI_SCO_HDR_SIZE)
+
+/* Receive fragment from data streams */
+int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
+{
+ int type;
+
+ while (count) {
+ /*
+ * Reuse first pointer from reassembly array
+ */
+ struct sk_buff *skb = __reassembly(hdev, HCI_ACLDATA_PKT);
+
+ struct { int expect; int pkt_type; } *scb;
+ int len = 0;
+
+ if (!skb) {
+ struct { char type; } *pkt;
+
+ /* Start of the frame */
+ pkt = data;
+ type = pkt->type;
+
+ if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
+ return -EILSEQ;
+
+ len = __get_max_rx_size(type);
+
+ skb = bt_skb_alloc(len, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ scb = (void *) skb->cb;
+ scb->expect = __get_header_len(type);
+ scb->pkt_type = type;
+
+ skb->dev = (void *) hdev;
+ __reassembly(hdev, HCI_ACLDATA_PKT) = skb;
+
+ data++;
+ count--;
+
+ continue;
+ } else {
+ /* Continue of frame */
+ scb = (void *) skb->cb;
+ len = min(scb->expect, count);
+ type = scb->pkt_type;
+
+ memcpy(skb_put(skb, len), data, len);
+
+ count -= len;
+ data += len;
+ scb->expect -= len;
+ }
+
+ 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;
+ }
+ 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);
+ }
+ 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;
+ }
+ break;
+ }
+
+ if (scb->expect == 0) {
+ /* Complete frame */
+
+ __reassembly(hdev, HCI_ACLDATA_PKT) = NULL;
+
+ bt_cb(skb)->pkt_type = type;
+ hci_recv_frame(skb);
+ }
+
+ }
+ return 0;
+}
+EXPORT_SYMBOL(hci_recv_stream_fragment);
+
+/* Receive packet fragment with known packet type */
int hci_recv_packet_fragment(struct hci_dev *hdev, int type, void *data,
int count)
{
--
1.7.0

2010-06-01 08:08:54

by Suraj Sumangala

[permalink] [raw]
Subject: [PATCH 2/3] Replace hci_recv_fragment calls

Replace all usages of hci_recv_fragment calls with
hci_recv_packet_fragment


Signed-off-by: suraj <[email protected]>
---
drivers/bluetooth/btusb.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 5d9cc53..50aa8d1 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -211,7 +211,7 @@ static void btusb_intr_complete(struct urb *urb)
if (urb->status == 0) {
hdev->stat.byte_rx += urb->actual_length;

- if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_EVENT_PKT,
urb->transfer_buffer,
urb->actual_length) < 0) {
BT_ERR("%s corrupted event packet", hdev->name);
@@ -295,7 +295,7 @@ static void btusb_bulk_complete(struct urb *urb)
if (urb->status == 0) {
hdev->stat.byte_rx += urb->actual_length;

- if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_ACLDATA_PKT,
urb->transfer_buffer,
urb->actual_length) < 0) {
BT_ERR("%s corrupted ACL packet", hdev->name);
@@ -384,7 +384,7 @@ static void btusb_isoc_complete(struct urb *urb)

hdev->stat.byte_rx += length;

- if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_SCODATA_PKT,
urb->transfer_buffer + offset,
length) < 0) {
BT_ERR("%s corrupted SCO packet", hdev->name);
--
1.7.0