xref: /haiku/src/add-ons/kernel/network/protocols/l2cap/l2cap.cpp (revision 3be9edf8da228afd9fec0390f408c964766122aa)
1 /*
2  * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3  * All rights reserved. Distributed under the terms of the MIT License.
4  *
5  */
6 
7 /*-
8  * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19 */
20 
21 #include <net_datalink.h>
22 #include <net_protocol.h>
23 #include <net_stack.h>
24 #include <NetBufferUtilities.h>
25 
26 #include <KernelExport.h>
27 #include <util/list.h>
28 #include <util/DoublyLinkedList.h>
29 
30 #include <new>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include "l2cap_address.h"
35 #include "l2cap_internal.h"
36 #include "l2cap_lower.h"
37 #include "L2capEndpoint.h"
38 
39 #include <bluetooth/HCI/btHCI_acl.h>
40 #include <btModules.h>
41 
42 #define BT_DEBUG_THIS_MODULE
43 #define SUBMODULE_NAME "L2cap"
44 #define SUBMODULE_COLOR 32
45 #include <btDebug.h>
46 
47 
48 typedef NetBufferField<uint16, offsetof(hci_acl_header, alen)> AclLenField;
49 DoublyLinkedList<L2capEndpoint> EndpointList;
50 
51 extern net_protocol_module_info gL2CAPModule;
52 
53 // module references
54 bluetooth_core_data_module_info* btCoreData;
55 
56 net_buffer_module_info* gBufferModule;
57 net_stack_module_info* gStackModule;
58 net_socket_module_info* gSocketModule;
59 
60 static struct net_domain* sDomain;
61 
62 net_protocol*
63 l2cap_init_protocol(net_socket* socket)
64 {
65 	flowf("\n");
66 
67 	L2capEndpoint* protocol = new (std::nothrow) L2capEndpoint(socket);
68 	if (protocol == NULL)
69 		return NULL;
70 
71 	EndpointList.Add(protocol);
72 
73 	return protocol;
74 }
75 
76 
77 status_t
78 l2cap_uninit_protocol(net_protocol* protocol)
79 {
80 	flowf("\n");
81 
82 	// TODO: Some more checkins	/ uninit
83 	EndpointList.Remove((L2capEndpoint*)protocol);
84 
85 	delete protocol;
86 	return B_OK;
87 }
88 
89 
90 status_t
91 l2cap_open(net_protocol* protocol)
92 {
93 	flowf("\n");
94 
95 	return B_OK;
96 }
97 
98 
99 status_t
100 l2cap_close(net_protocol* protocol)
101 {
102 	flowf("\n");
103 
104 	return B_OK;
105 }
106 
107 
108 status_t
109 l2cap_free(net_protocol* protocol)
110 {
111 	flowf("\n");
112 
113 	return B_OK;
114 }
115 
116 
117 status_t
118 l2cap_connect(net_protocol* protocol, const struct sockaddr* address)
119 {
120 	flowf("\n");
121 
122 	return B_ERROR;
123 }
124 
125 
126 status_t
127 l2cap_accept(net_protocol* protocol, struct net_socket** _acceptedSocket)
128 {
129 	return ((L2capEndpoint*)protocol)->Accept(_acceptedSocket);
130 }
131 
132 
133 status_t
134 l2cap_control(net_protocol* protocol, int level, int option, void* value,
135 	size_t* _length)
136 {
137 	flowf("\n");
138 
139 /*	return protocol->next->module->control(protocol->next, level, option, value, _length); */
140 	return B_OK;
141 }
142 
143 
144 status_t
145 l2cap_getsockopt(net_protocol* protocol, int level, int option,
146 	void* value, int* length)
147 {
148 	flowf("\n");
149 
150 /*	return protocol->next->module->getsockopt(protocol->next, level, option, value, length); */
151 	return B_OK;
152 }
153 
154 
155 status_t
156 l2cap_setsockopt(net_protocol* protocol, int level, int option,
157 	const void* value, int length)
158 {
159 	flowf("\n");
160 
161 	((L2capEndpoint*)protocol)->fConfigurationSet = true;
162 
163 /*	return protocol->next->module->setsockopt(protocol->next, level, option, value, length); */
164 	return EOPNOTSUPP;
165 }
166 
167 
168 status_t
169 l2cap_bind(net_protocol* protocol, const struct sockaddr* address)
170 {
171 	return ((L2capEndpoint*)protocol)->Bind(address);
172 }
173 
174 
175 status_t
176 l2cap_unbind(net_protocol* protocol, struct sockaddr* address)
177 {
178 	flowf("\n");
179 
180 	return B_ERROR;
181 }
182 
183 
184 status_t
185 l2cap_listen(net_protocol* protocol, int count)
186 {
187 	return ((L2capEndpoint*)protocol)->Listen(count);
188 }
189 
190 
191 status_t
192 l2cap_shutdown(net_protocol* protocol, int direction)
193 {
194 	flowf("\n");
195 
196 	return EOPNOTSUPP;
197 }
198 
199 
200 status_t
201 l2cap_send_data(net_protocol* protocol, net_buffer* buffer)
202 {
203 	flowf("\n");
204 
205 	return protocol->next->module->send_data(protocol->next, buffer);
206 }
207 
208 
209 status_t
210 l2cap_send_routed_data(net_protocol* protocol, struct net_route* route,
211 	net_buffer* buffer)
212 {
213 	flowf("\n");
214 
215 	return protocol->next->module->send_routed_data(protocol->next, route, buffer);
216 }
217 
218 
219 ssize_t
220 l2cap_send_avail(net_protocol* protocol)
221 {
222 	flowf("\n");
223 
224 	return B_ERROR;
225 }
226 
227 
228 status_t
229 l2cap_read_data(net_protocol* protocol, size_t numBytes, uint32 flags,
230 	net_buffer** _buffer)
231 {
232 	flowf("\n");
233 
234 	return ((L2capEndpoint*)protocol)->ReadData(numBytes, flags, _buffer);
235 }
236 
237 
238 ssize_t
239 l2cap_read_avail(net_protocol* protocol)
240 {
241 	flowf("\n");
242 
243 	return B_ERROR;
244 }
245 
246 
247 struct net_domain*
248 l2cap_get_domain(net_protocol* protocol)
249 {
250 	flowf("\n");
251 
252 	return sDomain;
253 }
254 
255 
256 size_t
257 l2cap_get_mtu(net_protocol* protocol, const struct sockaddr* address)
258 {
259 	flowf("\n");
260 
261 	return protocol->next->module->get_mtu(protocol->next, address);
262 }
263 
264 
265 status_t
266 l2cap_receive_data(net_buffer* buffer)
267 {
268 	HciConnection* conn = (HciConnection*)buffer;
269 	debugf("received some data, buffer length %lu\n", conn->currentRxPacket->size);
270 
271 	l2cap_receive(conn, conn->currentRxPacket);
272 
273 	return B_OK;
274 }
275 
276 
277 status_t
278 l2cap_error(uint32 code, net_buffer* data)
279 {
280 	flowf("\n");
281 
282 	return B_ERROR;
283 }
284 
285 
286 status_t
287 l2cap_error_reply(net_protocol* protocol, net_buffer* causedError, uint32 code,
288 	void* errorData)
289 {
290 	flowf("\n");
291 
292 	return B_ERROR;
293 }
294 
295 
296 #if 0
297 #pragma mark -
298 #endif
299 
300 static status_t
301 l2cap_std_ops(int32 op, ...)
302 {
303 	status_t error;
304 
305 	flowf("\n");
306 
307 	switch (op) {
308 		case B_MODULE_INIT:
309 		{
310 			error = gStackModule->register_domain_protocols(AF_BLUETOOTH, SOCK_STREAM, BLUETOOTH_PROTO_L2CAP,
311 				"network/protocols/l2cap/v1",
312 				NULL);
313 			if (error != B_OK) {
314 				return error;
315 			}
316 
317 			error = gStackModule->register_domain_receiving_protocol(AF_BLUETOOTH, BLUETOOTH_PROTO_L2CAP,
318 				"network/protocols/l2cap/v1");
319 			if (error != B_OK) {
320 				return error;
321 			}
322 
323 			error = gStackModule->register_domain(AF_BLUETOOTH, "l2cap", &gL2CAPModule,
324 								&gL2cap4AddressModule, &sDomain);
325 			if (error != B_OK) {
326 				return error;
327 			}
328 
329 			new (&EndpointList) DoublyLinkedList<L2capEndpoint>;
330 
331 			error = InitializeConnectionPurgeThread();
332 
333 			return B_OK;
334 		}
335 
336 		case B_MODULE_UNINIT:
337 
338 			error = QuitConnectionPurgeThread();
339 			gStackModule->unregister_domain(sDomain);
340 
341 			return B_OK;
342 
343 		default:
344 			return B_ERROR;
345 	}
346 }
347 
348 
349 net_protocol_module_info gL2CAPModule = {
350 	{
351 		NET_BLUETOOTH_L2CAP_NAME,
352 		B_KEEP_LOADED,
353 		l2cap_std_ops
354 	},
355 	NET_PROTOCOL_ATOMIC_MESSAGES,
356 
357 	l2cap_init_protocol,
358 	l2cap_uninit_protocol,
359 	l2cap_open,
360 	l2cap_close,
361 	l2cap_free,
362 	l2cap_connect,
363 	l2cap_accept,
364 	l2cap_control,
365 	l2cap_getsockopt,
366 	l2cap_setsockopt,
367 	l2cap_bind,
368 	l2cap_unbind,
369 	l2cap_listen,
370 	l2cap_shutdown,
371 	l2cap_send_data,
372 	l2cap_send_routed_data,
373 	l2cap_send_avail,
374 	l2cap_read_data,
375 	l2cap_read_avail,
376 	l2cap_get_domain,
377 	l2cap_get_mtu,
378 	l2cap_receive_data,
379 	NULL,		// deliver_data()
380 	l2cap_error,
381 	l2cap_error_reply,
382 	NULL,		// add_ancillary_data()
383 	NULL,		// process_ancillary_data()
384 	NULL,		// process_ancillary_data_no_container()
385 	NULL,		// send_data_no_buffer()
386 	NULL		// read_data_no_buffer()
387 };
388 
389 module_dependency module_dependencies[] = {
390 	{NET_STACK_MODULE_NAME, (module_info**)&gStackModule},
391 	{NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule},
392 	{BT_CORE_DATA_MODULE_NAME, (module_info**)&btCoreData},
393 	{NET_SOCKET_MODULE_NAME, (module_info**)&gSocketModule},
394 	{}
395 };
396 
397 module_info* modules[] = {
398 	(module_info*)&gL2CAPModule,
399 	NULL
400 };
401