2 * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3 * All rights reserved. Distributed under the terms of the MIT License.
6 #include <KernelExport.h>
9 #include <NetBufferUtilities.h>
10 #include <net_protocol.h>
12 #include <bluetooth/HCI/btHCI_acl.h>
13 #include <bluetooth/HCI/btHCI_transport.h>
14 #include <bluetooth/HCI/btHCI_event.h>
15 #include <bluetooth/bdaddrUtils.h>
18 #include <btCoreData.h>
19 #include <btModules.h>
24 extern struct bluetooth_core_data_module_info
* btCoreData
;
26 struct net_protocol_module_info
* L2cap
= NULL
;
28 extern void RegisterConnection(hci_id hid
, uint16 handle
);
29 extern void unRegisterConnection(hci_id hid
, uint16 handle
);
31 status_t
PostToUpper(HciConnection
* conn
, net_buffer
* buf
);
34 AclAssembly(net_buffer
* nbuf
, hci_id hid
)
36 status_t error
= B_OK
;
38 // Check ACL data packet. Driver should ensure report complete ACL packets
39 if (nbuf
->size
< sizeof(struct hci_acl_header
)) {
40 ERROR("%s: Invalid ACL data packet, small length=%" B_PRIu32
"\n",
41 __func__
, nbuf
->size
);
42 gBufferModule
->free(nbuf
);
46 // Strip ACL data packet header
47 NetBufferHeaderReader
<struct hci_acl_header
> aclHeader(nbuf
);
48 status_t status
= aclHeader
.Status();
50 gBufferModule
->free(nbuf
);
55 // Get ACL connection handle, PB flag and payload length
56 aclHeader
->handle
= le16toh(aclHeader
->handle
);
58 uint16 con_handle
= get_acl_handle(aclHeader
->handle
);
59 uint16 pb
= get_acl_pb_flag(aclHeader
->handle
);
60 uint16 length
= le16toh(aclHeader
->alen
);
64 TRACE("%s: ACL data packet, handle=%#x, PB=%#x, length=%d\n", __func__
,
65 con_handle
, pb
, length
);
67 // a) Ensure there is HCI connection
68 // b) Get connection descriptor
69 // c) veryfy the status of the connection
71 HciConnection
* conn
= btCoreData
->ConnectionByHandle(con_handle
, hid
);
73 ERROR("%s: expected handle=%#x does not exist!\n", __func__
,
75 conn
= btCoreData
->AddConnection(con_handle
, BT_ACL
, BDADDR_NULL
, hid
);
78 // Verify connection state
79 if (conn
->status
!= HCI_CONN_OPEN
) {
80 ERROR("%s: unexpected ACL data packet. Connection not open\n",
82 gBufferModule
->free(nbuf
);
88 if (pb
== HCI_ACL_PACKET_START
) {
89 if (conn
->currentRxPacket
!= NULL
) {
90 TRACE("%s: Dropping incomplete L2CAP packet, got %" B_PRIu32
91 " want %d \n", __func__
, conn
->currentRxPacket
->size
, length
);
92 gBufferModule
->free(conn
->currentRxPacket
);
93 conn
->currentRxPacket
= NULL
;
94 conn
->currentRxExpectedLength
= 0;
97 // Get L2CAP header, ACL header was dimissed
98 if (nbuf
->size
< sizeof(l2cap_hdr_t
)) {
99 TRACE("%s: Invalid L2CAP start fragment, small, length=%" B_PRIu32
100 "\n", __func__
, nbuf
->size
);
101 gBufferModule
->free(nbuf
);
106 NetBufferHeaderReader
<l2cap_hdr_t
> l2capHeader(nbuf
);
107 status_t status
= l2capHeader
.Status();
109 gBufferModule
->free(nbuf
);
113 l2capHeader
->length
= le16toh(l2capHeader
->length
);
114 l2capHeader
->dcid
= le16toh(l2capHeader
->dcid
);
116 TRACE("%s: New L2CAP, handle=%#x length=%d\n", __func__
, con_handle
,
117 le16toh(l2capHeader
->length
));
119 // Start new L2CAP packet
120 conn
->currentRxPacket
= nbuf
;
121 conn
->currentRxExpectedLength
= l2capHeader
->length
+ sizeof(l2cap_hdr_t
);
124 } else if (pb
== HCI_ACL_PACKET_FRAGMENT
) {
125 if (conn
->currentRxPacket
== NULL
) {
126 gBufferModule
->free(nbuf
);
130 // Add fragment to the L2CAP packet
131 gBufferModule
->merge(conn
->currentRxPacket
, nbuf
, true);
134 ERROR("%s: invalid ACL data packet. Invalid PB flag=%#x\n", __func__
,
136 gBufferModule
->free(nbuf
);
140 // substract the length of content of the ACL packet
141 conn
->currentRxExpectedLength
-= length
;
143 if (conn
->currentRxExpectedLength
< 0) {
144 TRACE("%s: Mismatch. Got %" B_PRIu32
", expected %" B_PRIuSIZE
"\n",
145 __func__
, conn
->currentRxPacket
->size
,
146 conn
->currentRxExpectedLength
);
148 gBufferModule
->free(conn
->currentRxPacket
);
149 conn
->currentRxPacket
= NULL
;
150 conn
->currentRxExpectedLength
= 0;
152 } else if (conn
->currentRxExpectedLength
== 0) {
153 // OK, we have got complete L2CAP packet, so process it
154 TRACE("%s: L2cap packet ready %" B_PRIu32
" bytes\n", __func__
,
155 conn
->currentRxPacket
->size
);
156 error
= PostToUpper(conn
, conn
->currentRxPacket
);
158 conn
->currentRxPacket
= NULL
;
159 conn
->currentRxExpectedLength
= 0;
161 TRACE("%s: Expected %ld current adds %d\n", __func__
,
162 conn
->currentRxExpectedLength
, length
);
170 PostToUpper(HciConnection
* conn
, net_buffer
* buf
)
174 if (get_module(NET_BLUETOOTH_L2CAP_NAME
, (module_info
**)&L2cap
) != B_OK
) {
175 ERROR("%s: cannot get module \"%s\"\n", __func__
,
176 NET_BLUETOOTH_L2CAP_NAME
);
178 } // TODO: someone put it
180 return L2cap
->receive_data((net_buffer
*)conn
);// XXX pass handle in type