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