xref: /haiku/src/add-ons/kernel/network/protocols/l2cap/l2cap.cpp (revision 4cf03112fa7d2fbd98d3248e2c8afd898c596665)
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 	flowf("\n");
130 
131 	return EOPNOTSUPP;
132 }
133 
134 
135 status_t
136 l2cap_control(net_protocol* protocol, int level, int option, void* value,
137 	size_t* _length)
138 {
139 	flowf("\n");
140 
141 /*	return protocol->next->module->control(protocol->next, level, option, value, _length); */
142 	return B_OK;
143 }
144 
145 
146 status_t
147 l2cap_getsockopt(net_protocol* protocol, int level, int option,
148 	void* value, int* length)
149 {
150 	flowf("\n");
151 
152 /*	return protocol->next->module->getsockopt(protocol->next, level, option, value, length); */
153 	return B_OK;
154 }
155 
156 
157 status_t
158 l2cap_setsockopt(net_protocol* protocol, int level, int option,
159 	const void* value, int length)
160 {
161 	flowf("\n");
162 
163 	((L2capEndpoint*)protocol)->configurationSet = true;
164 
165 /*	return protocol->next->module->setsockopt(protocol->next, level, option, value, length); */
166 	return EOPNOTSUPP;
167 }
168 
169 
170 status_t
171 l2cap_bind(net_protocol* protocol, const struct sockaddr* address)
172 {
173 	return ((L2capEndpoint*)protocol)->Bind(address);
174 }
175 
176 
177 status_t
178 l2cap_unbind(net_protocol* protocol, struct sockaddr* address)
179 {
180 	flowf("\n");
181 
182 	return B_ERROR;
183 }
184 
185 
186 status_t
187 l2cap_listen(net_protocol* protocol, int count)
188 {
189 	return ((L2capEndpoint*)protocol)->Listen(count);
190 }
191 
192 
193 status_t
194 l2cap_shutdown(net_protocol* protocol, int direction)
195 {
196 	flowf("\n");
197 
198 	return EOPNOTSUPP;
199 }
200 
201 
202 status_t
203 l2cap_send_data(net_protocol* protocol, net_buffer* buffer)
204 {
205 	flowf("\n");
206 
207 	return protocol->next->module->send_data(protocol->next, buffer);
208 }
209 
210 
211 status_t
212 l2cap_send_routed_data(net_protocol* protocol, struct net_route* route,
213 	net_buffer* buffer)
214 {
215 	flowf("\n");
216 
217 	return protocol->next->module->send_routed_data(protocol->next, route, buffer);
218 }
219 
220 
221 ssize_t
222 l2cap_send_avail(net_protocol* protocol)
223 {
224 	flowf("\n");
225 
226 	return B_ERROR;
227 }
228 
229 
230 status_t
231 l2cap_read_data(net_protocol* protocol, size_t numBytes, uint32 flags,
232 	net_buffer** _buffer)
233 {
234 	flowf("\n");
235 
236 	return ((L2capEndpoint*)protocol)->ReadData(numBytes, flags, _buffer);
237 }
238 
239 
240 ssize_t
241 l2cap_read_avail(net_protocol* protocol)
242 {
243 	flowf("\n");
244 
245 	return B_ERROR;
246 }
247 
248 
249 struct net_domain*
250 l2cap_get_domain(net_protocol* protocol)
251 {
252 	flowf("\n");
253 
254 	return sDomain;
255 }
256 
257 
258 size_t
259 l2cap_get_mtu(net_protocol* protocol, const struct sockaddr* address)
260 {
261 	flowf("\n");
262 
263 	return protocol->next->module->get_mtu(protocol->next, address);
264 }
265 
266 
267 status_t
268 l2cap_receive_data(net_buffer* buffer)
269 {
270 	HciConnection* conn = (HciConnection*)buffer;
271 	debugf("received some data, buffer length %lu\n", conn->currentRxPacket->size);
272 
273 	l2cap_receive(conn, conn->currentRxPacket);
274 
275 	return B_OK;
276 }
277 
278 
279 status_t
280 l2cap_error(uint32 code, net_buffer* data)
281 {
282 	flowf("\n");
283 
284 	return B_ERROR;
285 }
286 
287 
288 status_t
289 l2cap_error_reply(net_protocol* protocol, net_buffer* causedError, uint32 code,
290 	void* errorData)
291 {
292 	flowf("\n");
293 
294 	return B_ERROR;
295 }
296 
297 
298 #if 0
299 #pragma mark -
300 #endif
301 
302 static status_t
303 l2cap_std_ops(int32 op, ...)
304 {
305 	status_t error;
306 
307 	flowf("\n");
308 
309 	switch (op) {
310 		case B_MODULE_INIT:
311 		{
312 			error = gStackModule->register_domain_protocols(AF_BLUETOOTH, SOCK_STREAM, BLUETOOTH_PROTO_L2CAP,
313 				"network/protocols/l2cap/v1",
314 				NULL);
315 			if (error != B_OK) {
316 				return error;
317 			}
318 
319 			error = gStackModule->register_domain_receiving_protocol(AF_BLUETOOTH, BLUETOOTH_PROTO_L2CAP,
320 				"network/protocols/l2cap/v1");
321 			if (error != B_OK) {
322 				return error;
323 			}
324 
325 			error = gStackModule->register_domain(AF_BLUETOOTH, "l2cap", &gL2CAPModule,
326 								&gL2cap4AddressModule, &sDomain);
327 			if (error != B_OK) {
328 				return error;
329 			}
330 
331 			new (&EndpointList) DoublyLinkedList<L2capEndpoint>;
332 
333 			error = InitializeConnectionPurgeThread();
334 
335 			return B_OK;
336 		}
337 
338 		case B_MODULE_UNINIT:
339 
340 			error = QuitConnectionPurgeThread();
341 			gStackModule->unregister_domain(sDomain);
342 
343 			return B_OK;
344 
345 		default:
346 			return B_ERROR;
347 	}
348 }
349 
350 
351 net_protocol_module_info gL2CAPModule = {
352 	{
353 		NET_BLUETOOTH_L2CAP_NAME,
354 		B_KEEP_LOADED,
355 		l2cap_std_ops
356 	},
357 	NET_PROTOCOL_ATOMIC_MESSAGES,
358 
359 	l2cap_init_protocol,
360 	l2cap_uninit_protocol,
361 	l2cap_open,
362 	l2cap_close,
363 	l2cap_free,
364 	l2cap_connect,
365 	l2cap_accept,
366 	l2cap_control,
367 	l2cap_getsockopt,
368 	l2cap_setsockopt,
369 	l2cap_bind,
370 	l2cap_unbind,
371 	l2cap_listen,
372 	l2cap_shutdown,
373 	l2cap_send_data,
374 	l2cap_send_routed_data,
375 	l2cap_send_avail,
376 	l2cap_read_data,
377 	l2cap_read_avail,
378 	l2cap_get_domain,
379 	l2cap_get_mtu,
380 	l2cap_receive_data,
381 	NULL,		// deliver_data()
382 	l2cap_error,
383 	l2cap_error_reply,
384 	NULL,		// add_ancillary_data()
385 	NULL,		// process_ancillary_data()
386 	NULL,		// process_ancillary_data_no_container()
387 	NULL,		// send_data_no_buffer()
388 	NULL		// read_data_no_buffer()
389 };
390 
391 module_dependency module_dependencies[] = {
392 	{NET_STACK_MODULE_NAME, (module_info**)&gStackModule},
393 	{NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule},
394 	{BT_CORE_DATA_MODULE_NAME, (module_info**)&btCoreData},
395 	{NET_SOCKET_MODULE_NAME, (module_info**)&gSocketModule},
396 	{}
397 };
398 
399 module_info* modules[] = {
400 	(module_info*)&gL2CAPModule,
401 	NULL
402 };
403