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