1/*
2 * Copyright 2007, Oliver Ruiz Dorantes. All rights reserved.
3 * Copyright 2024, Haiku, Inc. All rights reserved.
4 * Distributed under the terms of the MIT License.
5 */
6
7#include <net_datalink.h>
8#include <net_protocol.h>
9#include <net_stack.h>
10#include <NetBufferUtilities.h>
11
12#include <new>
13
14#include "l2cap_address.h"
15#include "l2cap_command.h"
16#include "l2cap_internal.h"
17#include "l2cap_signal.h"
18#include "L2capEndpoint.h"
19#include "L2capEndpointManager.h"
20
21#include <bluetooth/HCI/btHCI_acl.h>
22#include <btModules.h>
23#include <btDebug.h>
24
25
26extern net_protocol_module_info gL2CAPModule;
27
28// module references
29bluetooth_core_data_module_info* btCoreData;
30bt_hci_module_info* btDevices;
31
32net_buffer_module_info* gBufferModule;
33net_stack_module_info* gStackModule;
34net_socket_module_info* gSocketModule;
35
36static struct net_domain* sDomain;
37
38
39net_protocol*
40l2cap_init_protocol(net_socket* socket)
41{
42	CALLED();
43
44	L2capEndpoint* protocol = new(std::nothrow) L2capEndpoint(socket);
45	if (protocol == NULL)
46		return NULL;
47
48	return protocol;
49}
50
51
52status_t
53l2cap_uninit_protocol(net_protocol* protocol)
54{
55	CALLED();
56
57	L2capEndpoint* endpoint = static_cast<L2capEndpoint*>(protocol);
58	delete endpoint;
59
60	return B_OK;
61}
62
63
64status_t
65l2cap_open(net_protocol* protocol)
66{
67	return ((L2capEndpoint*)protocol)->Open();
68}
69
70
71status_t
72l2cap_close(net_protocol* protocol)
73{
74	return ((L2capEndpoint*)protocol)->Close();
75}
76
77
78status_t
79l2cap_free(net_protocol* protocol)
80{
81	return ((L2capEndpoint*)protocol)->Free();
82}
83
84
85status_t
86l2cap_connect(net_protocol* protocol, const struct sockaddr* address)
87{
88	return ((L2capEndpoint*)protocol)->Connect(address);
89}
90
91
92status_t
93l2cap_accept(net_protocol* protocol, struct net_socket** _acceptedSocket)
94{
95	return ((L2capEndpoint*)protocol)->Accept(_acceptedSocket);
96}
97
98
99status_t
100l2cap_control(net_protocol* protocol, int level, int option, void* value,
101	size_t* _length)
102{
103	CALLED();
104	return EOPNOTSUPP;
105}
106
107
108status_t
109l2cap_getsockopt(net_protocol* protocol, int level, int option,
110	void* value, int* _length)
111{
112	CALLED();
113	return gSocketModule->get_option(protocol->socket, level, option, value,
114		_length);
115}
116
117
118status_t
119l2cap_setsockopt(net_protocol* protocol, int level, int option,
120	const void* _value, int length)
121{
122	CALLED();
123	return gSocketModule->set_option(protocol->socket, level, option,
124		_value, length);
125}
126
127
128status_t
129l2cap_bind(net_protocol* protocol, const struct sockaddr* address)
130{
131	return ((L2capEndpoint*)protocol)->Bind(address);
132}
133
134
135status_t
136l2cap_unbind(net_protocol* protocol, struct sockaddr* address)
137{
138	return ((L2capEndpoint*)protocol)->Unbind();
139}
140
141
142status_t
143l2cap_listen(net_protocol* protocol, int count)
144{
145	return ((L2capEndpoint*)protocol)->Listen(count);
146}
147
148
149status_t
150l2cap_shutdown(net_protocol* protocol, int direction)
151{
152	if (direction != SHUT_RDWR)
153		return EOPNOTSUPP;
154	return ((L2capEndpoint*)protocol)->Shutdown();
155}
156
157
158status_t
159l2cap_send_data(net_protocol* protocol, net_buffer* buffer)
160{
161	return ((L2capEndpoint*)protocol)->SendData(buffer);
162}
163
164
165status_t
166l2cap_send_routed_data(net_protocol* protocol, struct net_route* route,
167	net_buffer* buffer)
168{
169	CALLED();
170	return EOPNOTSUPP;
171}
172
173
174ssize_t
175l2cap_send_avail(net_protocol* protocol)
176{
177	return ((L2capEndpoint*)protocol)->Sendable();
178}
179
180
181status_t
182l2cap_read_data(net_protocol* protocol, size_t numBytes, uint32 flags,
183	net_buffer** _buffer)
184{
185	return ((L2capEndpoint*)protocol)->ReadData(numBytes, flags, _buffer);
186}
187
188
189ssize_t
190l2cap_read_avail(net_protocol* protocol)
191{
192	return ((L2capEndpoint*)protocol)->Receivable();
193}
194
195
196struct net_domain*
197l2cap_get_domain(net_protocol* protocol)
198{
199	return sDomain;
200}
201
202
203size_t
204l2cap_get_mtu(net_protocol* protocol, const struct sockaddr* address)
205{
206	CALLED();
207	return protocol->next->module->get_mtu(protocol->next, address);
208}
209
210
211static HciConnection*
212connection_for(net_buffer* buffer)
213{
214	const sockaddr_l2cap* l2capAddr = (sockaddr_l2cap*)buffer->source;
215	const sockaddr_dl* interfaceAddr = (sockaddr_dl*)buffer->interface_address->local;
216	struct HciConnection* connection = btCoreData->ConnectionByDestination(
217		l2capAddr->l2cap_bdaddr, interfaceAddr->sdl_index);
218	buffer->interface_address = NULL;
219		// This isn't a real interface_address; it could confuse the buffer module.
220		// FIXME: We probably should have an alternate interface for passing along data.
221	return connection;
222}
223
224
225status_t
226l2cap_receive_data(net_buffer* buffer)
227{
228	if (buffer->size < sizeof(l2cap_basic_header)) {
229		ERROR("%s: invalid L2CAP packet: too small. len=%" B_PRIu32 "\n",
230			__func__, buffer->size);
231		gBufferModule->free(buffer);
232		return EMSGSIZE;
233	}
234
235	NetBufferHeaderReader<l2cap_basic_header> bufferHeader(buffer);
236	if (bufferHeader.Status() != B_OK)
237		return ENOBUFS;
238
239	uint16 length = le16toh(bufferHeader->length);
240	uint16 dcid = le16toh(bufferHeader->dcid);
241
242	TRACE("%s: len=%d cid=%x\n", __func__, length, dcid);
243
244	bufferHeader.Remove();
245
246	if (length != buffer->size) {
247		ERROR("l2cap: payload length mismatch, packetlen=%d, bufferlen=%" B_PRIu32 "\n",
248			length, buffer->size);
249		return EMSGSIZE;
250	}
251
252	status_t status = B_ERROR;
253	switch (dcid) {
254		case L2CAP_SIGNALING_CID:
255		{
256			// We need to find the connection this packet is associated with.
257			struct HciConnection* connection = connection_for(buffer);
258			if (connection == NULL) {
259				panic("no connection for received L2CAP command");
260				return ENOTCONN;
261			}
262
263			status = l2cap_handle_signaling_command(connection, buffer);
264			break;
265		}
266
267		case L2CAP_CONNECTIONLESS_CID:
268		{
269			NetBufferHeaderReader<l2cap_connectionless_header> connlessHeader(buffer);
270			const uint16 psm = le16toh(connlessHeader->psm);
271			L2capEndpoint* endpoint = gL2capEndpointManager.ForPSM(psm);
272			if (endpoint == NULL)
273				return ECONNRESET;
274
275			connlessHeader.Remove();
276			buffer->interface_address = NULL;
277
278			status = endpoint->ReceiveData(buffer);
279			break;
280		}
281
282		default:
283		{
284			L2capEndpoint* endpoint = gL2capEndpointManager.ForChannel(dcid);
285			if (endpoint == NULL)
286				return ECONNRESET;
287
288			buffer->interface_address = NULL;
289			status = endpoint->ReceiveData(buffer);
290			break;
291		}
292	}
293
294	return status;
295}
296
297
298status_t
299l2cap_error_received(net_error error, net_buffer* data)
300{
301	CALLED();
302
303	if (error == B_NET_ERROR_UNREACH_HOST) {
304		struct HciConnection* connection = connection_for(data);
305		if (connection == NULL)
306			return ENOTCONN;
307
308		// Disconnect all connections with this HciConnection.
309		gL2capEndpointManager.Disconnected(connection);
310
311		gBufferModule->free(data);
312		return B_OK;
313	}
314
315	return B_ERROR;
316}
317
318
319status_t
320l2cap_error_reply(net_protocol* protocol, net_buffer* cause, net_error error,
321	net_error_data* errorData)
322{
323	CALLED();
324	return B_ERROR;
325}
326
327
328// #pragma mark -
329
330
331static status_t
332l2cap_std_ops(int32 op, ...)
333{
334	status_t error;
335
336	CALLED();
337
338	switch (op) {
339		case B_MODULE_INIT:
340		{
341			new(&gL2capEndpointManager) L2capEndpointManager;
342
343			error = gStackModule->register_domain_protocols(AF_BLUETOOTH,
344				SOCK_STREAM, BLUETOOTH_PROTO_L2CAP,
345				NET_BLUETOOTH_L2CAP_NAME, NULL);
346			if (error != B_OK)
347				return error;
348
349			error = gStackModule->register_domain(AF_BLUETOOTH, "l2cap",
350				&gL2CAPModule, &gL2capAddressModule, &sDomain);
351			if (error != B_OK)
352				return error;
353
354			return B_OK;
355		}
356
357		case B_MODULE_UNINIT:
358			gL2capEndpointManager.~L2capEndpointManager();
359			gStackModule->unregister_domain(sDomain);
360			return B_OK;
361
362		default:
363			return B_ERROR;
364	}
365}
366
367
368net_protocol_module_info gL2CAPModule = {
369	{
370		NET_BLUETOOTH_L2CAP_NAME,
371		0,
372		l2cap_std_ops
373	},
374	NET_PROTOCOL_ATOMIC_MESSAGES,
375
376	l2cap_init_protocol,
377	l2cap_uninit_protocol,
378	l2cap_open,
379	l2cap_close,
380	l2cap_free,
381	l2cap_connect,
382	l2cap_accept,
383	l2cap_control,
384	l2cap_getsockopt,
385	l2cap_setsockopt,
386	l2cap_bind,
387	l2cap_unbind,
388	l2cap_listen,
389	l2cap_shutdown,
390	l2cap_send_data,
391	l2cap_send_routed_data,
392	l2cap_send_avail,
393	l2cap_read_data,
394	l2cap_read_avail,
395	l2cap_get_domain,
396	l2cap_get_mtu,
397	l2cap_receive_data,
398	NULL,		// deliver_data()
399	l2cap_error_received,
400	l2cap_error_reply,
401	NULL,		// add_ancillary_data()
402	NULL,		// process_ancillary_data()
403	NULL,		// process_ancillary_data_no_container()
404	NULL,		// send_data_no_buffer()
405	NULL		// read_data_no_buffer()
406};
407
408module_dependency module_dependencies[] = {
409	{NET_STACK_MODULE_NAME, (module_info**)&gStackModule},
410	{NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule},
411	{NET_SOCKET_MODULE_NAME, (module_info**)&gSocketModule},
412	{BT_CORE_DATA_MODULE_NAME, (module_info**)&btCoreData},
413	{BT_HCI_MODULE_NAME, (module_info**)&btDevices},
414	{}
415};
416
417module_info* modules[] = {
418	(module_info*)&gL2CAPModule,
419	NULL
420};
421