xref: /haiku/src/add-ons/kernel/network/protocols/l2cap/l2cap.cpp (revision d63ed5844d997a61afd7a6c4b7c9fad0dc01e9f3)
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 #include <btDebug.h>
45 
46 
47 typedef NetBufferField<uint16, offsetof(hci_acl_header, alen)> AclLenField;
48 DoublyLinkedList<L2capEndpoint> EndpointList;
49 
50 extern net_protocol_module_info gL2CAPModule;
51 
52 // module references
53 bluetooth_core_data_module_info* btCoreData;
54 
55 net_buffer_module_info* gBufferModule;
56 net_stack_module_info* gStackModule;
57 net_socket_module_info* gSocketModule;
58 
59 static struct net_domain* sDomain;
60 
61 net_protocol*
62 l2cap_init_protocol(net_socket* socket)
63 {
64 	CALLED();
65 
66 	L2capEndpoint* protocol = new(std::nothrow) L2capEndpoint(socket);
67 	if (protocol == NULL)
68 		return NULL;
69 
70 	EndpointList.Add(protocol);
71 
72 	return protocol;
73 }
74 
75 
76 status_t
77 l2cap_uninit_protocol(net_protocol* protocol)
78 {
79 	CALLED();
80 
81 	L2capEndpoint* endpoint = static_cast<L2capEndpoint*>(protocol);
82 
83 	// TODO: Some more checkins	/ uninit
84 	EndpointList.Remove(endpoint);
85 
86 	delete endpoint;
87 
88 	return B_OK;
89 }
90 
91 
92 status_t
93 l2cap_open(net_protocol* protocol)
94 {
95 	CALLED();
96 
97 	return B_OK;
98 }
99 
100 
101 status_t
102 l2cap_close(net_protocol* protocol)
103 {
104 	L2capEndpoint* endpoint = static_cast<L2capEndpoint*>(protocol);
105 
106 	CALLED();
107 
108 	endpoint->Close();
109 
110 	return B_OK;
111 }
112 
113 
114 status_t
115 l2cap_free(net_protocol* protocol)
116 {
117 	CALLED();
118 
119 	return B_OK;
120 }
121 
122 
123 status_t
124 l2cap_connect(net_protocol* protocol, const struct sockaddr* address)
125 {
126 	CALLED();
127 
128 	if (address == NULL)
129 		return EINVAL;
130 
131 	if (address->sa_family != AF_BLUETOOTH)
132 		return EAFNOSUPPORT;
133 
134 	return ((L2capEndpoint*)protocol)->Connect(address);;
135 }
136 
137 
138 status_t
139 l2cap_accept(net_protocol* protocol, struct net_socket** _acceptedSocket)
140 {
141 	CALLED();
142 	return ((L2capEndpoint*)protocol)->Accept(_acceptedSocket);
143 }
144 
145 
146 status_t
147 l2cap_control(net_protocol* protocol, int level, int option, void* value,
148 	size_t* _length)
149 {
150 	CALLED();
151 	return EOPNOTSUPP;
152 }
153 
154 
155 status_t
156 l2cap_getsockopt(net_protocol* protocol, int level, int option,
157 	void* value, int* length)
158 {
159 	CALLED();
160 	return B_OK;
161 }
162 
163 
164 status_t
165 l2cap_setsockopt(net_protocol* protocol, int level, int option,
166 	const void* value, int length)
167 {
168 	CALLED();
169 	((L2capEndpoint*)protocol)->fConfigurationSet = true;
170 	return B_OK;
171 }
172 
173 
174 status_t
175 l2cap_bind(net_protocol* protocol, const struct sockaddr* address)
176 {
177 	CALLED();
178 	return ((L2capEndpoint*)protocol)->Bind(address);
179 }
180 
181 
182 status_t
183 l2cap_unbind(net_protocol* protocol, struct sockaddr* address)
184 {
185 	CALLED();
186 	return B_ERROR;
187 }
188 
189 
190 status_t
191 l2cap_listen(net_protocol* protocol, int count)
192 {
193 	CALLED();
194 	return ((L2capEndpoint*)protocol)->Listen(count);
195 }
196 
197 
198 status_t
199 l2cap_shutdown(net_protocol* protocol, int direction)
200 {
201 	CALLED();
202 	return EOPNOTSUPP;
203 }
204 
205 
206 status_t
207 l2cap_send_data(net_protocol* protocol, net_buffer* buffer)
208 {
209 	CALLED();
210 
211 	if (buffer == NULL)
212 		return ENOBUFS;
213 
214 	return ((L2capEndpoint*)protocol)->SendData(buffer);
215 }
216 
217 
218 status_t
219 l2cap_send_routed_data(net_protocol* protocol, struct net_route* route,
220 	net_buffer* buffer)
221 {
222 	CALLED();
223 	return EOPNOTSUPP;
224 }
225 
226 
227 ssize_t
228 l2cap_send_avail(net_protocol* protocol)
229 {
230 	CALLED();
231 	return B_ERROR;
232 }
233 
234 
235 status_t
236 l2cap_read_data(net_protocol* protocol, size_t numBytes, uint32 flags,
237 	net_buffer** _buffer)
238 {
239 	CALLED();
240 	return ((L2capEndpoint*)protocol)->ReadData(numBytes, flags, _buffer);
241 }
242 
243 
244 ssize_t
245 l2cap_read_avail(net_protocol* protocol)
246 {
247 	CALLED();
248 	return B_ERROR;
249 }
250 
251 
252 struct net_domain*
253 l2cap_get_domain(net_protocol* protocol)
254 {
255 	CALLED();
256 	return sDomain;
257 }
258 
259 
260 size_t
261 l2cap_get_mtu(net_protocol* protocol, const struct sockaddr* address)
262 {
263 	CALLED();
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 	TRACE("%s: received some data, buffer length %" B_PRIu32 "\n", __func__,
273 		conn->currentRxPacket->size);
274 
275 	l2cap_receive(conn, conn->currentRxPacket);
276 
277 	return B_OK;
278 }
279 
280 
281 status_t
282 l2cap_error_received(net_error error, net_buffer* data)
283 {
284 	CALLED();
285 
286 	return B_ERROR;
287 }
288 
289 
290 status_t
291 l2cap_error_reply(net_protocol* protocol, net_buffer* cause, net_error error,
292 	net_error_data* errorData)
293 {
294 	CALLED();
295 
296 	return B_ERROR;
297 }
298 
299 
300 // #pragma mark -
301 
302 
303 static status_t
304 l2cap_std_ops(int32 op, ...)
305 {
306 	status_t error;
307 
308 	CALLED();
309 
310 	switch (op) {
311 		case B_MODULE_INIT:
312 		{
313 			error = gStackModule->register_domain_protocols(AF_BLUETOOTH,
314 				SOCK_STREAM, BLUETOOTH_PROTO_L2CAP,
315 				"network/protocols/l2cap/v1",
316 				NULL);
317 			if (error != B_OK)
318 				return error;
319 
320 			error = gStackModule->register_domain_receiving_protocol(
321 				AF_BLUETOOTH,
322 				BLUETOOTH_PROTO_L2CAP,
323 				"network/protocols/l2cap/v1");
324 			if (error != B_OK)
325 				return error;
326 
327 			error = gStackModule->register_domain(AF_BLUETOOTH, "l2cap",
328 				&gL2CAPModule, &gL2cap4AddressModule, &sDomain);
329 			if (error != B_OK)
330 				return error;
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_received,
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