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 <util/DoublyLinkedList.h>
8 #include <KernelExport.h>
10 #include <bluetooth/bluetooth.h>
11 #include <bluetooth/bdaddrUtils.h>
17 #include "ConnectionInterface.h"
20 void PurgeChannels(HciConnection
* conn
);
23 HciConnection::HciConnection()
25 mutex_init(&fLock
, "conn outgoing");
26 mutex_init(&fLockExpected
, "frame expected");
30 HciConnection::~HciConnection()
32 mutex_destroy(&fLock
);
33 mutex_destroy(&fLockExpected
);
38 AddConnection(uint16 handle
, int type
, const bdaddr_t
& dst
, hci_id hid
)
40 // Create connection descriptor
42 HciConnection
* conn
= ConnectionByHandle(handle
, hid
);
46 conn
= new (std::nothrow
) HciConnection
;
50 // memset(conn, 0, sizeof(HciConnection));
52 conn
->currentRxPacket
= NULL
;
53 conn
->currentRxExpectedLength
= 0;
56 bdaddrUtils::Copy(conn
->destination
, dst
);
58 conn
->handle
= handle
;
60 conn
->status
= HCI_CONN_OPEN
;
61 conn
->mtu
= L2CAP_MTU_MINIMUM
; // TODO: give the mtu to the connection
62 conn
->lastCid
= L2CAP_FIRST_CID
;
63 conn
->lastIdent
= L2CAP_FIRST_IDENT
;
65 sConnectionList
.Add(conn
);
73 RemoveConnection(const bdaddr_t
& destination
, hci_id hid
)
77 DoublyLinkedList
<HciConnection
>::Iterator iterator
78 = sConnectionList
.GetIterator();
80 while (iterator
.HasNext()) {
82 conn
= iterator
.Next();
84 && bdaddrUtils::Compare(conn
->destination
, destination
)) {
86 // if the device is still part of the list, remove it
87 if (conn
->GetDoublyLinkedListLink()->next
!= NULL
88 || conn
->GetDoublyLinkedListLink()->previous
!= NULL
89 || conn
== sConnectionList
.Head()) {
90 sConnectionList
.Remove(conn
);
102 RemoveConnection(uint16 handle
, hci_id hid
)
106 DoublyLinkedList
<HciConnection
>::Iterator iterator
107 = sConnectionList
.GetIterator();
108 while (iterator
.HasNext()) {
110 conn
= iterator
.Next();
111 if (conn
->Hid
== hid
&& conn
->handle
== handle
) {
113 // if the device is still part of the list, remove it
114 if (conn
->GetDoublyLinkedListLink()->next
!= NULL
115 || conn
->GetDoublyLinkedListLink()->previous
!= NULL
116 || conn
== sConnectionList
.Head()) {
117 sConnectionList
.Remove(conn
);
130 RouteConnection(const bdaddr_t
& destination
) {
134 DoublyLinkedList
<HciConnection
>::Iterator iterator
135 = sConnectionList
.GetIterator();
136 while (iterator
.HasNext()) {
138 conn
= iterator
.Next();
139 if (bdaddrUtils::Compare(conn
->destination
, destination
)) {
149 ConnectionByHandle(uint16 handle
, hci_id hid
)
153 DoublyLinkedList
<HciConnection
>::Iterator iterator
154 = sConnectionList
.GetIterator();
155 while (iterator
.HasNext()) {
157 conn
= iterator
.Next();
158 if (conn
->Hid
== hid
&& conn
->handle
== handle
) {
168 ConnectionByDestination(const bdaddr_t
& destination
, hci_id hid
)
172 DoublyLinkedList
<HciConnection
>::Iterator iterator
173 = sConnectionList
.GetIterator();
174 while (iterator
.HasNext()) {
176 conn
= iterator
.Next();
178 && bdaddrUtils::Compare(conn
->destination
, destination
)) {
188 #pragma mark - ACL helper funcs
192 SetAclBuffer(HciConnection
* conn
, net_buffer
* nbuf
)
194 conn
->currentRxPacket
= nbuf
;
199 SetAclExpectedSize(HciConnection
* conn
, size_t size
)
201 conn
->currentRxExpectedLength
= size
;
206 AclPutting(HciConnection
* conn
, size_t size
)
208 conn
->currentRxExpectedLength
-= size
;
213 AclComplete(HciConnection
* conn
)
215 return conn
->currentRxExpectedLength
== 0;
220 AclOverFlowed(HciConnection
* conn
)
222 return conn
->currentRxExpectedLength
< 0;
227 #pragma mark - private funcs
231 PurgeChannels(HciConnection
* conn
)