xref: /haiku/src/add-ons/kernel/network/protocols/l2cap/l2cap.cpp (revision bb83316a5811a550c4f850d07fa8e328e7ac0a94)
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 
26 extern net_protocol_module_info gL2CAPModule;
27 
28 // module references
29 bluetooth_core_data_module_info* btCoreData;
30 bt_hci_module_info* btDevices;
31 
32 net_buffer_module_info* gBufferModule;
33 net_stack_module_info* gStackModule;
34 net_socket_module_info* gSocketModule;
35 
36 static struct net_domain* sDomain;
37 
38 
39 net_protocol*
l2cap_init_protocol(net_socket * socket)40 l2cap_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 
52 status_t
l2cap_uninit_protocol(net_protocol * protocol)53 l2cap_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 
64 status_t
l2cap_open(net_protocol * protocol)65 l2cap_open(net_protocol* protocol)
66 {
67 	return ((L2capEndpoint*)protocol)->Open();
68 }
69 
70 
71 status_t
l2cap_close(net_protocol * protocol)72 l2cap_close(net_protocol* protocol)
73 {
74 	return ((L2capEndpoint*)protocol)->Close();
75 }
76 
77 
78 status_t
l2cap_free(net_protocol * protocol)79 l2cap_free(net_protocol* protocol)
80 {
81 	return ((L2capEndpoint*)protocol)->Free();
82 }
83 
84 
85 status_t
l2cap_connect(net_protocol * protocol,const struct sockaddr * address)86 l2cap_connect(net_protocol* protocol, const struct sockaddr* address)
87 {
88 	return ((L2capEndpoint*)protocol)->Connect(address);
89 }
90 
91 
92 status_t
l2cap_accept(net_protocol * protocol,struct net_socket ** _acceptedSocket)93 l2cap_accept(net_protocol* protocol, struct net_socket** _acceptedSocket)
94 {
95 	return ((L2capEndpoint*)protocol)->Accept(_acceptedSocket);
96 }
97 
98 
99 status_t
l2cap_control(net_protocol * protocol,int level,int option,void * value,size_t * _length)100 l2cap_control(net_protocol* protocol, int level, int option, void* value,
101 	size_t* _length)
102 {
103 	CALLED();
104 	return EOPNOTSUPP;
105 }
106 
107 
108 status_t
l2cap_getsockopt(net_protocol * protocol,int level,int option,void * value,int * _length)109 l2cap_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 
118 status_t
l2cap_setsockopt(net_protocol * protocol,int level,int option,const void * _value,int length)119 l2cap_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 
128 status_t
l2cap_bind(net_protocol * protocol,const struct sockaddr * address)129 l2cap_bind(net_protocol* protocol, const struct sockaddr* address)
130 {
131 	return ((L2capEndpoint*)protocol)->Bind(address);
132 }
133 
134 
135 status_t
l2cap_unbind(net_protocol * protocol,struct sockaddr * address)136 l2cap_unbind(net_protocol* protocol, struct sockaddr* address)
137 {
138 	return ((L2capEndpoint*)protocol)->Unbind();
139 }
140 
141 
142 status_t
l2cap_listen(net_protocol * protocol,int count)143 l2cap_listen(net_protocol* protocol, int count)
144 {
145 	return ((L2capEndpoint*)protocol)->Listen(count);
146 }
147 
148 
149 status_t
l2cap_shutdown(net_protocol * protocol,int direction)150 l2cap_shutdown(net_protocol* protocol, int direction)
151 {
152 	if (direction != SHUT_RDWR)
153 		return EOPNOTSUPP;
154 	return ((L2capEndpoint*)protocol)->Shutdown();
155 }
156 
157 
158 status_t
l2cap_send_data(net_protocol * protocol,net_buffer * buffer)159 l2cap_send_data(net_protocol* protocol, net_buffer* buffer)
160 {
161 	return ((L2capEndpoint*)protocol)->SendData(buffer);
162 }
163 
164 
165 status_t
l2cap_send_routed_data(net_protocol * protocol,struct net_route * route,net_buffer * buffer)166 l2cap_send_routed_data(net_protocol* protocol, struct net_route* route,
167 	net_buffer* buffer)
168 {
169 	CALLED();
170 	return EOPNOTSUPP;
171 }
172 
173 
174 ssize_t
l2cap_send_avail(net_protocol * protocol)175 l2cap_send_avail(net_protocol* protocol)
176 {
177 	return ((L2capEndpoint*)protocol)->Sendable();
178 }
179 
180 
181 status_t
l2cap_read_data(net_protocol * protocol,size_t numBytes,uint32 flags,net_buffer ** _buffer)182 l2cap_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 
189 ssize_t
l2cap_read_avail(net_protocol * protocol)190 l2cap_read_avail(net_protocol* protocol)
191 {
192 	return ((L2capEndpoint*)protocol)->Receivable();
193 }
194 
195 
196 struct net_domain*
l2cap_get_domain(net_protocol * protocol)197 l2cap_get_domain(net_protocol* protocol)
198 {
199 	return sDomain;
200 }
201 
202 
203 size_t
l2cap_get_mtu(net_protocol * protocol,const struct sockaddr * address)204 l2cap_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 
211 static HciConnection*
connection_for(net_buffer * buffer)212 connection_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 
225 status_t
l2cap_receive_data(net_buffer * buffer)226 l2cap_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 
298 status_t
l2cap_error_received(net_error error,net_buffer * data)299 l2cap_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 
319 status_t
l2cap_error_reply(net_protocol * protocol,net_buffer * cause,net_error error,net_error_data * errorData)320 l2cap_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 
331 static status_t
l2cap_std_ops(int32 op,...)332 l2cap_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 
368 net_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 
408 module_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 
417 module_info* modules[] = {
418 	(module_info*)&gL2CAPModule,
419 	NULL
420 };
421