xref: /haiku/src/add-ons/kernel/network/protocols/l2cap/l2cap.cpp (revision 746cac055adc6ac3308c7bc2d29040fb95689cc9)
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 
29 #include <new>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include <bluetooth/HCI/btHCI_acl.h>
34 
35 #include "l2cap_address.h"
36 
37 
38 #define BT_DEBUG_THIS_MODULE
39 #include <btDebug.h>
40 
41 
42 typedef NetBufferField<uint16, offsetof(hci_acl_header, alen)> AclLenField;
43 
44 
45 struct l2cap_protocol : net_protocol {
46 };
47 
48 
49 extern net_protocol_module_info gL2CAPModule;
50 
51 net_buffer_module_info *gBufferModule;
52 static net_stack_module_info *sStackModule;
53 
54 static struct net_domain *sDomain;
55 
56 net_protocol *
57 l2cap_init_protocol(net_socket *socket)
58 {
59 	flowf("\n");
60 
61 	l2cap_protocol *protocol = new (std::nothrow) l2cap_protocol;
62 	if (protocol == NULL)
63 		return NULL;
64 
65 	return protocol;
66 }
67 
68 
69 status_t
70 l2cap_uninit_protocol(net_protocol *protocol)
71 {
72 	flowf("\n");
73 
74 	delete protocol;
75 	return B_OK;
76 }
77 
78 
79 status_t
80 l2cap_open(net_protocol *protocol)
81 {
82 	flowf("\n");
83 
84 	return B_OK;
85 }
86 
87 
88 status_t
89 l2cap_close(net_protocol *protocol)
90 {
91 	flowf("\n");
92 
93 	return B_OK;
94 }
95 
96 
97 status_t
98 l2cap_free(net_protocol *protocol)
99 {
100 	flowf("\n");
101 
102 	return B_OK;
103 }
104 
105 
106 status_t
107 l2cap_connect(net_protocol *protocol, const struct sockaddr *address)
108 {
109 	flowf("\n");
110 
111 	return B_ERROR;
112 }
113 
114 
115 status_t
116 l2cap_accept(net_protocol *protocol, struct net_socket **_acceptedSocket)
117 {
118 	flowf("\n");
119 
120 	return EOPNOTSUPP;
121 }
122 
123 
124 status_t
125 l2cap_control(net_protocol *protocol, int level, int option, void *value,
126 	size_t *_length)
127 {
128 	flowf("\n");
129 
130 /*	return protocol->next->module->control(protocol->next, level, option, value, _length); */
131 	return EOPNOTSUPP;
132 }
133 
134 
135 status_t
136 l2cap_getsockopt(net_protocol *protocol, int level, int option,
137 	void *value, int *length)
138 {
139 	flowf("\n");
140 
141 /*	return protocol->next->module->getsockopt(protocol->next, level, option, value, length); */
142 	return EOPNOTSUPP;
143 }
144 
145 
146 status_t
147 l2cap_setsockopt(net_protocol *protocol, int level, int option,
148 	const void *value, int length)
149 {
150 	flowf("\n");
151 
152 /*	return protocol->next->module->setsockopt(protocol->next, level, option, value, length); */
153 	return EOPNOTSUPP;
154 }
155 
156 
157 status_t
158 l2cap_bind(net_protocol *protocol, const struct sockaddr *address)
159 {
160 	flowf("\n");
161 
162 	return B_ERROR;
163 }
164 
165 
166 status_t
167 l2cap_unbind(net_protocol *protocol, struct sockaddr *address)
168 {
169 	flowf("\n");
170 
171 	return B_ERROR;
172 }
173 
174 
175 status_t
176 l2cap_listen(net_protocol *protocol, int count)
177 {
178 	flowf("\n");
179 
180 	return EOPNOTSUPP;
181 }
182 
183 
184 status_t
185 l2cap_shutdown(net_protocol *protocol, int direction)
186 {
187 	flowf("\n");
188 
189 	return EOPNOTSUPP;
190 }
191 
192 
193 status_t
194 l2cap_send_data(net_protocol *protocol, net_buffer *buffer)
195 {
196 	flowf("\n");
197 
198 	return protocol->next->module->send_data(protocol->next, buffer);
199 }
200 
201 
202 status_t
203 l2cap_send_routed_data(net_protocol *protocol, struct net_route *route,
204 	net_buffer *buffer)
205 {
206 	flowf("\n");
207 
208 	return protocol->next->module->send_routed_data(protocol->next, route, buffer);
209 }
210 
211 
212 ssize_t
213 l2cap_send_avail(net_protocol *protocol)
214 {
215 	flowf("\n");
216 
217 	return B_ERROR;
218 }
219 
220 
221 status_t
222 l2cap_read_data(net_protocol *protocol, size_t numBytes, uint32 flags,
223 	net_buffer **_buffer)
224 {
225 	flowf("\n");
226 
227 	return B_ERROR;
228 }
229 
230 
231 ssize_t
232 l2cap_read_avail(net_protocol *protocol)
233 {
234 	flowf("\n");
235 
236 	return B_ERROR;
237 }
238 
239 
240 struct net_domain *
241 l2cap_get_domain(net_protocol *protocol)
242 {
243 	flowf("\n");
244 
245 	return sDomain;
246 }
247 
248 
249 size_t
250 l2cap_get_mtu(net_protocol *protocol, const struct sockaddr *address)
251 {
252 	flowf("\n");
253 
254 	return protocol->next->module->get_mtu(protocol->next, address);
255 }
256 
257 
258 status_t
259 l2cap_receive_data(net_buffer *buffer)
260 {
261 	debugf("received some data, buffer length %lu\n", buffer->size);
262 
263 	NetBufferHeaderReader<hci_acl_header> bufferHeader(buffer);
264 	if (bufferHeader.Status() < B_OK)
265 		return bufferHeader.Status();
266 
267 	hci_acl_header &header = bufferHeader.Data();
268 
269 	debugf("  got handle %u, len %u\n", header.handle, header.alen);
270 	debugf("  computed checksum: %ld\n", gBufferModule->checksum(buffer, 0, buffer->size, true));
271 
272 	if (gBufferModule->checksum(buffer, 0, buffer->size, true) != 0)
273 		return B_BAD_DATA;
274 
275 	gBufferModule->free(buffer);
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 	flowf("\n");
307 
308 	switch (op) {
309 		case B_MODULE_INIT:
310 		{
311 			status_t error;
312 
313 			error = sStackModule->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 = sStackModule->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 = sStackModule->register_domain(AF_BLUETOOTH, "l2cap", &gL2CAPModule,
327 								&gL2cap4AddressModule, &sDomain);
328 			if (error != B_OK) {
329 				return error;
330 			}
331 
332 
333 			return B_OK;
334 		}
335 
336 		case B_MODULE_UNINIT:
337 
338 			sStackModule->unregister_domain(sDomain);
339 			return B_OK;
340 
341 		default:
342 			return B_ERROR;
343 	}
344 }
345 
346 
347 net_protocol_module_info gL2CAPModule = {
348 	{
349 		"network/protocols/l2cap/v1",
350 		0,
351 		l2cap_std_ops
352 	},
353 	NET_PROTOCOL_ATOMIC_MESSAGES,
354 
355 	l2cap_init_protocol,
356 	l2cap_uninit_protocol,
357 	l2cap_open,
358 	l2cap_close,
359 	l2cap_free,
360 	l2cap_connect,
361 	l2cap_accept,
362 	l2cap_control,
363 	l2cap_getsockopt,
364 	l2cap_setsockopt,
365 	l2cap_bind,
366 	l2cap_unbind,
367 	l2cap_listen,
368 	l2cap_shutdown,
369 	l2cap_send_data,
370 	l2cap_send_routed_data,
371 	l2cap_send_avail,
372 	l2cap_read_data,
373 	l2cap_read_avail,
374 	l2cap_get_domain,
375 	l2cap_get_mtu,
376 	l2cap_receive_data,
377 	NULL,
378 	l2cap_error,
379 	l2cap_error_reply,
380 };
381 
382 module_dependency module_dependencies[] = {
383 	{NET_STACK_MODULE_NAME, (module_info **)&sStackModule},
384 	{NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule},
385 	{}
386 };
387 
388 module_info *modules[] = {
389 	(module_info *)&gL2CAPModule,
390 	NULL
391 };
392