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
50typedef NetBufferField<uint16, offsetof(hci_acl_header, alen)> AclLenField;
51DoublyLinkedList<L2capEndpoint> EndpointList;
52
53extern net_protocol_module_info gL2CAPModule;
54
55// module references
56bluetooth_core_data_module_info* btCoreData;
57
58net_buffer_module_info* gBufferModule;
59net_stack_module_info* gStackModule;
60net_socket_module_info* gSocketModule;
61
62static struct net_domain* sDomain;
63
64net_protocol*
65l2cap_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
78status_t
79l2cap_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
94status_t
95l2cap_open(net_protocol* protocol)
96{
97	flowf("\n");
98
99	return B_OK;
100}
101
102
103status_t
104l2cap_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
116status_t
117l2cap_free(net_protocol* protocol)
118{
119	flowf("\n");
120
121	return B_OK;
122}
123
124
125status_t
126l2cap_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
141status_t
142l2cap_accept(net_protocol* protocol, struct net_socket** _acceptedSocket)
143{
144	return ((L2capEndpoint*)protocol)->Accept(_acceptedSocket);
145}
146
147
148status_t
149l2cap_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
158status_t
159l2cap_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
168status_t
169l2cap_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
180status_t
181l2cap_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
189status_t
190l2cap_unbind(net_protocol* protocol, struct sockaddr* address)
191{
192	flowf("\n");
193
194	return B_ERROR;
195}
196
197
198status_t
199l2cap_listen(net_protocol* protocol, int count)
200{
201	return ((L2capEndpoint*)protocol)->Listen(count);
202}
203
204
205status_t
206l2cap_shutdown(net_protocol* protocol, int direction)
207{
208	flowf("\n");
209
210	return EOPNOTSUPP;
211}
212
213
214status_t
215l2cap_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
226status_t
227l2cap_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
236ssize_t
237l2cap_send_avail(net_protocol* protocol)
238{
239	flowf("\n");
240
241	return B_ERROR;
242}
243
244
245status_t
246l2cap_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
255ssize_t
256l2cap_read_avail(net_protocol* protocol)
257{
258	flowf("\n");
259
260	return B_ERROR;
261}
262
263
264struct net_domain*
265l2cap_get_domain(net_protocol* protocol)
266{
267	flowf("\n");
268
269	return sDomain;
270}
271
272
273size_t
274l2cap_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
282status_t
283l2cap_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
295status_t
296l2cap_error_received(net_error error, net_buffer* data)
297{
298	flowf("\n");
299
300	return B_ERROR;
301}
302
303
304status_t
305l2cap_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
317static status_t
318l2cap_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
366net_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
406module_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
414module_info* modules[] = {
415	(module_info*)&gL2CAPModule,
416	NULL
417};
418