xref: /haiku/src/add-ons/kernel/bluetooth/btCoreData/ConnectionInterface.cpp (revision 9760dcae2038d47442f4658c2575844c6cf92c40)
1 /*
2  * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 
6 #include <util/DoublyLinkedList.h>
7 
8 #include <KernelExport.h>
9 
10 #include <bluetooth/bluetooth.h>
11 #include <bluetooth/bluetooth_util.h>
12 
13 #define BT_DEBUG_THIS_MODULE
14 #define SUBMODULE_NAME "Connection"
15 #define SUBMODULE_COLOR 31
16 #include <btDebug.h>
17 
18 #include <l2cap.h>
19 
20 #include "ConnectionInterface.h"
21 
22 void PurgeChannels(HciConnection* conn);
23 
24 
25 HciConnection::HciConnection()
26 {
27 	mutex_init(&fLock, "conn outgoing");
28 	mutex_init(&fLockExpected, "frame expected");
29 }
30 
31 
32 HciConnection::~HciConnection()
33 {
34 	mutex_destroy(&fLock);
35 	mutex_destroy(&fLockExpected);
36 }
37 
38 
39 HciConnection*
40 AddConnection(uint16 handle, int type, bdaddr_t* dst, hci_id hid)
41 {
42 	// Create connection descriptor
43 
44 	HciConnection* conn = ConnectionByHandle(handle, hid);
45 	if (conn != NULL)
46 		goto update;
47 
48 	conn = new (std::nothrow) HciConnection;
49 	if (conn == NULL)
50 		goto bail;
51 
52 	//memset(conn, 0, sizeof(HciConnection));
53 
54 	conn->currentRxPacket = NULL;
55 	conn->currentRxExpectedLength = 0;
56 update:
57 	// fill values
58 	bacpy(&conn->destination, dst);
59 	conn->type   	= type;
60 	conn->handle   = handle;
61 	conn->Hid   	= hid;
62 	conn->status  	= HCI_CONN_OPEN;
63 	conn->mtu	 	= L2CAP_MTU_MINIMUM; // TODO: give the mtu to the connection
64 	conn->lastCid   = L2CAP_FIRST_CID;
65 	conn->lastIdent = L2CAP_FIRST_IDENT;
66 
67 	sConnectionList.Add(conn);
68 
69 bail:
70 	return conn;
71 }
72 
73 
74 status_t
75 RemoveConnection(bdaddr_t* destination, hci_id hid)
76 {
77 	HciConnection*	conn;
78 
79 	DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
80 	while (iterator.HasNext()) {
81 
82 		conn = iterator.Next();
83 		if (conn->Hid == hid && bacmp(&conn->destination, destination)==0) {
84 
85 			// if the device is still part of the list, remove it
86 			if (conn->GetDoublyLinkedListLink()->next != NULL
87 				|| conn->GetDoublyLinkedListLink()->previous != NULL
88 				|| conn == sConnectionList.Head()) {
89 				sConnectionList.Remove(conn);
90 
91 				delete conn;
92 				return B_OK;
93 			}
94 		}
95 	}
96 	return B_ERROR;
97 }
98 
99 
100 status_t
101 RemoveConnection(uint16 handle, hci_id hid)
102 {
103 	HciConnection*	conn;
104 
105 	DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
106 	while (iterator.HasNext()) {
107 
108 		conn = iterator.Next();
109 		if (conn->Hid == hid && conn->handle == handle) {
110 
111 			// if the device is still part of the list, remove it
112 			if (conn->GetDoublyLinkedListLink()->next != NULL
113 				|| conn->GetDoublyLinkedListLink()->previous != NULL
114 				|| conn == sConnectionList.Head()) {
115 				sConnectionList.Remove(conn);
116 
117 				PurgeChannels(conn);
118 				delete conn;
119 				return B_OK;
120 			}
121 		}
122 	}
123 	return B_ERROR;
124 }
125 
126 
127 hci_id
128 RouteConnection(bdaddr_t* destination) {
129 
130 	HciConnection*	conn;
131 
132 	DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
133 	while (iterator.HasNext()) {
134 
135 		conn = iterator.Next();
136 		if (bacmp(&conn->destination, destination)==0) {
137 			return conn->Hid;
138 		}
139 	}
140 
141 	return -1;
142 }
143 
144 
145 HciConnection*
146 ConnectionByHandle(uint16 handle, hci_id hid)
147 {
148 	HciConnection*	conn;
149 
150 	DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
151 	while (iterator.HasNext()) {
152 
153 		conn = iterator.Next();
154 		if (conn->Hid == hid && conn->handle==handle) {
155 			return conn;
156 		}
157 	}
158 
159 	return NULL;
160 }
161 
162 
163 HciConnection*
164 ConnectionByDestination(bdaddr_t* destination, hci_id hid)
165 {
166 	HciConnection*	conn;
167 
168 	DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
169 	while (iterator.HasNext()) {
170 
171 		conn = iterator.Next();
172 		if (conn->Hid == hid && bacmp(&conn->destination, destination)==0) {
173 			return conn;
174 		}
175 	}
176 
177 	return NULL;
178 }
179 
180 #if 0
181 #pragma mark - ACL helper funcs
182 #endif
183 
184 void
185 SetAclBuffer(HciConnection* conn, net_buffer* nbuf)
186 {
187 	conn->currentRxPacket = nbuf;
188 }
189 
190 
191 void
192 SetAclExpectedSize(HciConnection* conn, size_t size)
193 {
194 	conn->currentRxExpectedLength = size;
195 }
196 
197 
198 void
199 AclPutting(HciConnection* conn, size_t size)
200 {
201 	conn->currentRxExpectedLength -= size;
202 }
203 
204 
205 bool
206 AclComplete(HciConnection* conn)
207 {
208 	return conn->currentRxExpectedLength == 0;
209 }
210 
211 
212 bool
213 AclOverFlowed(HciConnection* conn)
214 {
215 	return conn->currentRxExpectedLength < 0;
216 }
217 
218 #if 0
219 #pragma mark - private funcs
220 #endif
221 
222 void
223 PurgeChannels(HciConnection* conn)
224 {
225 
226 }
227