diff options
author | Suraj Sumangala <suraj@atheros.com> | 2010-07-14 03:32:19 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-07-21 13:39:12 -0400 |
commit | 9981151086385eecc2febf4ba95a14593f834b3d (patch) | |
tree | 3cdda7fe4c3d5d3bf05e9ca6fb8f9f1b6ab1c226 | |
parent | f39a3c06404d01ef2ce47e821bc778dfb1836df9 (diff) |
Bluetooth: Implemented HCI frame reassembly for RX from stream
Implemented frame reassembly implementation for reassembling fragments
received from stream.
Signed-off-by: Suraj Sumangala <suraj@atheros.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r-- | include/net/bluetooth/hci_core.h | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 35 |
2 files changed, 36 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 28e5eeefdec8..350b3e6964bd 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -437,6 +437,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); | |||
437 | 437 | ||
438 | int hci_recv_frame(struct sk_buff *skb); | 438 | int hci_recv_frame(struct sk_buff *skb); |
439 | int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); | 439 | int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); |
440 | int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count); | ||
440 | 441 | ||
441 | int hci_register_sysfs(struct hci_dev *hdev); | 442 | int hci_register_sysfs(struct hci_dev *hdev); |
442 | void hci_unregister_sysfs(struct hci_dev *hdev); | 443 | void hci_unregister_sysfs(struct hci_dev *hdev); |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 451e266840ad..995c9f9b84d0 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -1163,6 +1163,41 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) | |||
1163 | } | 1163 | } |
1164 | EXPORT_SYMBOL(hci_recv_fragment); | 1164 | EXPORT_SYMBOL(hci_recv_fragment); |
1165 | 1165 | ||
1166 | #define STREAM_REASSEMBLY 0 | ||
1167 | |||
1168 | int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) | ||
1169 | { | ||
1170 | int type; | ||
1171 | int rem = 0; | ||
1172 | |||
1173 | do { | ||
1174 | struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; | ||
1175 | |||
1176 | if (!skb) { | ||
1177 | struct { char type; } *pkt; | ||
1178 | |||
1179 | /* Start of the frame */ | ||
1180 | pkt = data; | ||
1181 | type = pkt->type; | ||
1182 | |||
1183 | data++; | ||
1184 | count--; | ||
1185 | } else | ||
1186 | type = bt_cb(skb)->pkt_type; | ||
1187 | |||
1188 | rem = hci_reassembly(hdev, type, data, | ||
1189 | count, STREAM_REASSEMBLY, GFP_ATOMIC); | ||
1190 | if (rem < 0) | ||
1191 | return rem; | ||
1192 | |||
1193 | data += (count - rem); | ||
1194 | count = rem; | ||
1195 | } while (count); | ||
1196 | |||
1197 | return rem; | ||
1198 | } | ||
1199 | EXPORT_SYMBOL(hci_recv_stream_fragment); | ||
1200 | |||
1166 | /* ---- Interface to upper protocols ---- */ | 1201 | /* ---- Interface to upper protocols ---- */ |
1167 | 1202 | ||
1168 | /* Register/Unregister protocols. | 1203 | /* Register/Unregister protocols. |