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
47typedef NetBufferField<uint16, offsetof(hci_acl_header, alen)> AclLenField;
48DoublyLinkedList<L2capEndpoint> EndpointList;
49
50extern net_protocol_module_info gL2CAPModule;
51
52// module references
53bluetooth_core_data_module_info* btCoreData;
54
55net_buffer_module_info* gBufferModule;
56net_stack_module_info* gStackModule;
57net_socket_module_info* gSocketModule;
58
59static struct net_domain* sDomain;
60
61net_protocol*
62l2cap_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
76status_t
77l2cap_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
92status_t
93l2cap_open(net_protocol* protocol)
94{
95	CALLED();
96
97	return B_OK;
98}
99
100
101status_t
102l2cap_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
114status_t
115l2cap_free(net_protocol* protocol)
116{
117	CALLED();
118
119	return B_OK;
120}
121
122
123status_t
124l2cap_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
138status_t
139l2cap_accept(net_protocol* protocol, struct net_socket** _acceptedSocket)
140{
141	CALLED();
142	return ((L2capEndpoint*)protocol)->Accept(_acceptedSocket);
143}
144
145
146status_t
147l2cap_control(net_protocol* protocol, int level, int option, void* value,
148	size_t* _length)
149{
150	CALLED();
151	return EOPNOTSUPP;
152}
153
154
155status_t
156l2cap_getsockopt(net_protocol* protocol, int level, int option,
157	void* value, int* length)
158{
159	CALLED();
160	return B_OK;
161}
162
163
164status_t
165l2cap_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
174status_t
175l2cap_bind(net_protocol* protocol, const struct sockaddr* address)
176{
177	CALLED();
178	return ((L2capEndpoint*)protocol)->Bind(address);
179}
180
181
182status_t
183l2cap_unbind(net_protocol* protocol, struct sockaddr* address)
184{
185	CALLED();
186	return B_ERROR;
187}
188
189
190status_t
191l2cap_listen(net_protocol* protocol, int count)
192{
193	CALLED();
194	return ((L2capEndpoint*)protocol)->Listen(count);
195}
196
197
198status_t
199l2cap_shutdown(net_protocol* protocol, int direction)
200{
201	CALLED();
202	return EOPNOTSUPP;
203}
204
205
206status_t
207l2cap_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
218status_t
219l2cap_send_routed_data(net_protocol* protocol, struct net_route* route,
220	net_buffer* buffer)
221{
222	CALLED();
223	return EOPNOTSUPP;
224}
225
226
227ssize_t
228l2cap_send_avail(net_protocol* protocol)
229{
230	CALLED();
231	return B_ERROR;
232}
233
234
235status_t
236l2cap_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
244ssize_t
245l2cap_read_avail(net_protocol* protocol)
246{
247	CALLED();
248	return B_ERROR;
249}
250
251
252struct net_domain*
253l2cap_get_domain(net_protocol* protocol)
254{
255	CALLED();
256	return sDomain;
257}
258
259
260size_t
261l2cap_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
268status_t
269l2cap_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
281status_t
282l2cap_error_received(net_error error, net_buffer* data)
283{
284	CALLED();
285
286	return B_ERROR;
287}
288
289
290status_t
291l2cap_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
303static status_t
304l2cap_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
352net_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
392module_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
400module_info* modules[] = {
401	(module_info*)&gL2CAPModule,
402	NULL
403};
404