1 /** @file
2  * @brief Bluetooth shell module
3  *
4  * Provide some Bluetooth shell commands that can be useful to applications.
5  */
6 
7 /*
8  * Copyright (c) 2017 Intel Corporation
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #include <errno.h>
14 #include <zephyr/types.h>
15 #include <stddef.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <zephyr/sys/byteorder.h>
19 #include <zephyr/kernel.h>
20 
21 #include <zephyr/settings/settings.h>
22 
23 #include <zephyr/bluetooth/hci.h>
24 #include <zephyr/bluetooth/bluetooth.h>
25 #include <zephyr/bluetooth/conn.h>
26 #include <zephyr/bluetooth/l2cap.h>
27 #include <zephyr/bluetooth/classic/rfcomm.h>
28 #include <zephyr/bluetooth/classic/sdp.h>
29 
30 #include <zephyr/shell/shell.h>
31 
32 #include "host/shell/bt.h"
33 #include "host/shell/bt_shell_private.h"
34 
35 #define CREDITS			10
36 #define DATA_MTU		(23 * CREDITS)
37 
38 #define L2CAP_POLICY_NONE		0x00
39 #define L2CAP_POLICY_ALLOWLIST		0x01
40 #define L2CAP_POLICY_16BYTE_KEY		0x02
41 
42 NET_BUF_POOL_FIXED_DEFINE(data_tx_pool, 1, BT_L2CAP_SDU_BUF_SIZE(DATA_MTU),
43 			  CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
44 NET_BUF_POOL_FIXED_DEFINE(data_rx_pool, 1, DATA_MTU, 8, NULL);
45 
46 static uint8_t l2cap_policy;
47 static struct bt_conn *l2cap_allowlist[CONFIG_BT_MAX_CONN];
48 
49 static uint32_t l2cap_rate;
50 static uint32_t l2cap_recv_delay_ms;
51 static K_FIFO_DEFINE(l2cap_recv_fifo);
52 struct l2ch {
53 	struct k_work_delayable recv_work;
54 	struct bt_l2cap_le_chan ch;
55 };
56 #define L2CH_CHAN(_chan) CONTAINER_OF(_chan, struct l2ch, ch.chan)
57 #define L2CH_WORK(_work) CONTAINER_OF(k_work_delayable_from_work(_work), \
58 				      struct l2ch, recv_work)
59 #define L2CAP_CHAN(_chan) _chan->ch.chan
60 
61 static bool metrics;
62 
l2cap_recv_metrics(struct bt_l2cap_chan * chan,struct net_buf * buf)63 static int l2cap_recv_metrics(struct bt_l2cap_chan *chan, struct net_buf *buf)
64 {
65 	static uint32_t len;
66 	static uint32_t cycle_stamp;
67 	uint32_t delta;
68 
69 	delta = k_cycle_get_32() - cycle_stamp;
70 	delta = (uint32_t)k_cyc_to_ns_floor64(delta);
71 
72 	/* if last data rx-ed was greater than 1 second in the past,
73 	 * reset the metrics.
74 	 */
75 	if (delta > 1000000000) {
76 		len = 0U;
77 		l2cap_rate = 0U;
78 		cycle_stamp = k_cycle_get_32();
79 	} else {
80 		len += buf->len;
81 		l2cap_rate = ((uint64_t)len << 3) * 1000000000U / delta;
82 	}
83 
84 	return 0;
85 }
86 
l2cap_recv_cb(struct k_work * work)87 static void l2cap_recv_cb(struct k_work *work)
88 {
89 	struct l2ch *c = L2CH_WORK(work);
90 	struct net_buf *buf;
91 
92 	while ((buf = k_fifo_get(&l2cap_recv_fifo, K_NO_WAIT))) {
93 		bt_shell_print("Confirming reception");
94 		bt_l2cap_chan_recv_complete(&c->ch.chan, buf);
95 	}
96 }
97 
l2cap_recv(struct bt_l2cap_chan * chan,struct net_buf * buf)98 static int l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
99 {
100 	struct l2ch *l2ch = L2CH_CHAN(chan);
101 
102 	if (metrics) {
103 		return l2cap_recv_metrics(chan, buf);
104 	}
105 
106 	bt_shell_print("Incoming data channel %p len %u",
107 		       chan, buf->len);
108 
109 	if (buf->len) {
110 		bt_shell_hexdump(buf->data, buf->len);
111 	}
112 
113 	if (l2cap_recv_delay_ms > 0) {
114 		/* Submit work only if queue is empty */
115 		if (k_fifo_is_empty(&l2cap_recv_fifo)) {
116 			bt_shell_print("Delaying response in %u ms...",
117 				       l2cap_recv_delay_ms);
118 		}
119 
120 		k_fifo_put(&l2cap_recv_fifo, buf);
121 		k_work_schedule(&l2ch->recv_work, K_MSEC(l2cap_recv_delay_ms));
122 
123 		return -EINPROGRESS;
124 	}
125 
126 	return 0;
127 }
128 
l2cap_sent(struct bt_l2cap_chan * chan)129 static void l2cap_sent(struct bt_l2cap_chan *chan)
130 {
131 	bt_shell_print("Outgoing data channel %p transmitted", chan);
132 }
133 
l2cap_status(struct bt_l2cap_chan * chan,atomic_t * status)134 static void l2cap_status(struct bt_l2cap_chan *chan, atomic_t *status)
135 {
136 	bt_shell_print("Channel %p status %u", chan, (uint32_t)*status);
137 }
138 
l2cap_connected(struct bt_l2cap_chan * chan)139 static void l2cap_connected(struct bt_l2cap_chan *chan)
140 {
141 	struct l2ch *c = L2CH_CHAN(chan);
142 
143 	k_work_init_delayable(&c->recv_work, l2cap_recv_cb);
144 
145 	bt_shell_print("Channel %p connected", chan);
146 }
147 
l2cap_disconnected(struct bt_l2cap_chan * chan)148 static void l2cap_disconnected(struct bt_l2cap_chan *chan)
149 {
150 	bt_shell_print("Channel %p disconnected", chan);
151 }
152 
l2cap_alloc_buf(struct bt_l2cap_chan * chan)153 static struct net_buf *l2cap_alloc_buf(struct bt_l2cap_chan *chan)
154 {
155 	/* print if metrics is disabled */
156 	if (!metrics) {
157 		bt_shell_print("Channel %p requires buffer", chan);
158 	}
159 
160 	return net_buf_alloc(&data_rx_pool, K_FOREVER);
161 }
162 
163 static const struct bt_l2cap_chan_ops l2cap_ops = {
164 	.alloc_buf	= l2cap_alloc_buf,
165 	.recv		= l2cap_recv,
166 	.sent		= l2cap_sent,
167 	.status		= l2cap_status,
168 	.connected	= l2cap_connected,
169 	.disconnected	= l2cap_disconnected,
170 };
171 
172 static struct l2ch l2ch_chan = {
173 	.ch.chan.ops	= &l2cap_ops,
174 	.ch.rx.mtu	= DATA_MTU,
175 };
176 
l2cap_allowlist_remove(struct bt_conn * conn,uint8_t reason)177 static void l2cap_allowlist_remove(struct bt_conn *conn, uint8_t reason)
178 {
179 	int i;
180 
181 	for (i = 0; i < ARRAY_SIZE(l2cap_allowlist); i++) {
182 		if (l2cap_allowlist[i] == conn) {
183 			bt_conn_unref(l2cap_allowlist[i]);
184 			l2cap_allowlist[i] = NULL;
185 		}
186 	}
187 }
188 
189 BT_CONN_CB_DEFINE(l2cap_conn_callbacks) = {
190 	.disconnected = l2cap_allowlist_remove,
191 };
192 
l2cap_accept_policy(struct bt_conn * conn)193 static int l2cap_accept_policy(struct bt_conn *conn)
194 {
195 	int i;
196 
197 	if (l2cap_policy == L2CAP_POLICY_16BYTE_KEY) {
198 		uint8_t enc_key_size = bt_conn_enc_key_size(conn);
199 
200 		if (enc_key_size && enc_key_size < BT_ENC_KEY_SIZE_MAX) {
201 			return -EPERM;
202 		}
203 	} else if (l2cap_policy == L2CAP_POLICY_ALLOWLIST) {
204 		for (i = 0; i < ARRAY_SIZE(l2cap_allowlist); i++) {
205 			if (l2cap_allowlist[i] == conn) {
206 				return 0;
207 			}
208 		}
209 
210 		return -EACCES;
211 	}
212 
213 	return 0;
214 }
215 
l2cap_accept(struct bt_conn * conn,struct bt_l2cap_server * server,struct bt_l2cap_chan ** chan)216 static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_server *server,
217 			struct bt_l2cap_chan **chan)
218 {
219 	int err;
220 
221 	bt_shell_print("Incoming conn %p", conn);
222 
223 	err = l2cap_accept_policy(conn);
224 	if (err < 0) {
225 		return err;
226 	}
227 
228 	if (l2ch_chan.ch.chan.conn) {
229 		bt_shell_print("No channels available");
230 		return -ENOMEM;
231 	}
232 
233 	*chan = &l2ch_chan.ch.chan;
234 
235 	return 0;
236 }
237 
238 static struct bt_l2cap_server server = {
239 	.accept		= l2cap_accept,
240 };
241 
cmd_register(const struct shell * sh,size_t argc,char * argv[])242 static int cmd_register(const struct shell *sh, size_t argc, char *argv[])
243 {
244 	const char *policy;
245 
246 	if (server.psm) {
247 		shell_error(sh, "Already registered");
248 		return -ENOEXEC;
249 	}
250 
251 	server.psm = strtoul(argv[1], NULL, 16);
252 
253 	if (argc > 2) {
254 		server.sec_level = strtoul(argv[2], NULL, 10);
255 	}
256 
257 	if (argc > 3) {
258 		policy = argv[3];
259 
260 		if (!strcmp(policy, "allowlist")) {
261 			l2cap_policy = L2CAP_POLICY_ALLOWLIST;
262 		} else if (!strcmp(policy, "16byte_key")) {
263 			l2cap_policy = L2CAP_POLICY_16BYTE_KEY;
264 		} else {
265 			return -EINVAL;
266 		}
267 	}
268 
269 	if (bt_l2cap_server_register(&server) < 0) {
270 		shell_error(sh, "Unable to register psm");
271 		server.psm = 0U;
272 		return -ENOEXEC;
273 	} else {
274 		shell_print(sh, "L2CAP psm %u sec_level %u registered",
275 			    server.psm, server.sec_level);
276 	}
277 
278 	return 0;
279 }
280 
281 #if defined(CONFIG_BT_L2CAP_ECRED)
cmd_ecred_reconfigure(const struct shell * sh,size_t argc,char * argv[])282 static int cmd_ecred_reconfigure(const struct shell *sh, size_t argc, char *argv[])
283 {
284 	struct bt_l2cap_chan *l2cap_ecred_chans[] = { &l2ch_chan.ch.chan, NULL };
285 	uint16_t mtu;
286 	int err = 0;
287 
288 	if (!default_conn) {
289 		shell_error(sh, "Not connected");
290 		return -ENOEXEC;
291 	}
292 
293 	if (!l2ch_chan.ch.chan.conn) {
294 		shell_error(sh, "Channel not connected");
295 		return -ENOEXEC;
296 	}
297 
298 	mtu = shell_strtoul(argv[1], 10, &err);
299 	if (err) {
300 		shell_error(sh, "Unable to parse MTU (err %d)", err);
301 
302 		return -ENOEXEC;
303 	}
304 
305 	err = bt_l2cap_ecred_chan_reconfigure(l2cap_ecred_chans, mtu);
306 	if (err < 0) {
307 		shell_error(sh, "Unable to reconfigure channel (err %d)", err);
308 	} else {
309 		shell_print(sh, "L2CAP reconfiguration pending");
310 	}
311 
312 	return err;
313 }
314 
cmd_ecred_connect(const struct shell * sh,size_t argc,char * argv[])315 static int cmd_ecred_connect(const struct shell *sh, size_t argc, char *argv[])
316 {
317 	struct bt_l2cap_chan *l2cap_ecred_chans[] = { &l2ch_chan.ch.chan, NULL };
318 	uint16_t psm;
319 	int err = 0;
320 
321 	if (!default_conn) {
322 		shell_error(sh, "Not connected");
323 
324 		return -ENOEXEC;
325 	}
326 
327 	if (l2ch_chan.ch.chan.conn) {
328 		shell_error(sh, "Channel already in use");
329 
330 		return -ENOEXEC;
331 	}
332 
333 	psm = shell_strtoul(argv[1], 16, &err);
334 	if (err) {
335 		shell_error(sh, "Unable to parse PSM (err %d)", err);
336 
337 		return err;
338 	}
339 
340 	if (argc > 2) {
341 		int sec;
342 
343 		sec = shell_strtoul(argv[2], 10, &err);
344 		if (err) {
345 			shell_error(sh, "Unable to parse security level (err %d)", err);
346 
347 			return err;
348 		}
349 
350 		l2ch_chan.ch.required_sec_level = sec;
351 	}
352 
353 	err = bt_l2cap_ecred_chan_connect(default_conn, l2cap_ecred_chans, psm);
354 	if (err < 0) {
355 		shell_error(sh, "Unable to connect to psm %u (err %d)", psm, err);
356 	} else {
357 		shell_print(sh, "L2CAP connection pending");
358 	}
359 
360 	return err;
361 }
362 #endif /* CONFIG_BT_L2CAP_ECRED */
363 
cmd_connect(const struct shell * sh,size_t argc,char * argv[])364 static int cmd_connect(const struct shell *sh, size_t argc, char *argv[])
365 {
366 	uint16_t psm;
367 	int err;
368 
369 	if (!default_conn) {
370 		shell_error(sh, "Not connected");
371 		return -ENOEXEC;
372 	}
373 
374 	if (l2ch_chan.ch.chan.conn) {
375 		shell_error(sh, "Channel already in use");
376 		return -ENOEXEC;
377 	}
378 
379 	psm = strtoul(argv[1], NULL, 16);
380 
381 	if (argc > 2) {
382 		int sec;
383 
384 		sec = *argv[2] - '0';
385 
386 		l2ch_chan.ch.required_sec_level = sec;
387 	}
388 
389 	err = bt_l2cap_chan_connect(default_conn, &l2ch_chan.ch.chan, psm);
390 	if (err < 0) {
391 		shell_error(sh, "Unable to connect to psm %u (err %d)", psm, err);
392 	} else {
393 		shell_print(sh, "L2CAP connection pending");
394 	}
395 
396 	return err;
397 }
398 
cmd_disconnect(const struct shell * sh,size_t argc,char * argv[])399 static int cmd_disconnect(const struct shell *sh, size_t argc, char *argv[])
400 {
401 	int err;
402 
403 	err = bt_l2cap_chan_disconnect(&l2ch_chan.ch.chan);
404 	if (err) {
405 		shell_print(sh, "Unable to disconnect: %u", -err);
406 	}
407 
408 	return err;
409 }
410 
cmd_send(const struct shell * sh,size_t argc,char * argv[])411 static int cmd_send(const struct shell *sh, size_t argc, char *argv[])
412 {
413 	static uint8_t buf_data[DATA_MTU] = { [0 ... (DATA_MTU - 1)] = 0xff };
414 	int ret, len = DATA_MTU, count = 1;
415 	struct net_buf *buf;
416 
417 	if (argc > 1) {
418 		count = strtoul(argv[1], NULL, 10);
419 	}
420 
421 	if (argc > 2) {
422 		len = strtoul(argv[2], NULL, 10);
423 		if (len > DATA_MTU) {
424 			shell_print(sh, "Length exceeds TX MTU for the channel");
425 			return -ENOEXEC;
426 		}
427 	}
428 
429 	len = MIN(l2ch_chan.ch.tx.mtu, len);
430 
431 	while (count--) {
432 		shell_print(sh, "Rem %d", count);
433 		buf = net_buf_alloc(&data_tx_pool, K_SECONDS(2));
434 		if (!buf) {
435 			if (l2ch_chan.ch.state != BT_L2CAP_CONNECTED) {
436 				shell_print(sh, "Channel disconnected, stopping TX");
437 
438 				return -EAGAIN;
439 			}
440 			shell_print(sh, "Allocation timeout, stopping TX");
441 
442 			return -EAGAIN;
443 		}
444 		net_buf_reserve(buf, BT_L2CAP_SDU_CHAN_SEND_RESERVE);
445 
446 		net_buf_add_mem(buf, buf_data, len);
447 		ret = bt_l2cap_chan_send(&l2ch_chan.ch.chan, buf);
448 		if (ret < 0) {
449 			shell_print(sh, "Unable to send: %d", -ret);
450 			net_buf_unref(buf);
451 			return -ENOEXEC;
452 		}
453 	}
454 
455 	return 0;
456 }
457 
cmd_recv(const struct shell * sh,size_t argc,char * argv[])458 static int cmd_recv(const struct shell *sh, size_t argc, char *argv[])
459 {
460 	if (argc > 1) {
461 		l2cap_recv_delay_ms = strtoul(argv[1], NULL, 10);
462 	} else {
463 		shell_print(sh, "l2cap receive delay: %u ms",
464 			    l2cap_recv_delay_ms);
465 	}
466 
467 	return 0;
468 }
469 
cmd_metrics(const struct shell * sh,size_t argc,char * argv[])470 static int cmd_metrics(const struct shell *sh, size_t argc, char *argv[])
471 {
472 	const char *action;
473 
474 	if (argc < 2) {
475 		shell_print(sh, "l2cap rate: %u bps.", l2cap_rate);
476 
477 		return 0;
478 	}
479 
480 	action = argv[1];
481 
482 	if (!strcmp(action, "on")) {
483 		metrics = true;
484 	} else if (!strcmp(action, "off")) {
485 		metrics = false;
486 	} else {
487 		shell_help(sh);
488 		return 0;
489 	}
490 
491 	shell_print(sh, "l2cap metrics %s.", action);
492 	return 0;
493 }
494 
cmd_allowlist_add(const struct shell * sh,size_t argc,char * argv[])495 static int cmd_allowlist_add(const struct shell *sh, size_t argc, char *argv[])
496 {
497 	int i;
498 
499 	if (!default_conn) {
500 		shell_error(sh, "Not connected");
501 		return 0;
502 	}
503 
504 	for (i = 0; i < ARRAY_SIZE(l2cap_allowlist); i++) {
505 		if (l2cap_allowlist[i] == NULL) {
506 			l2cap_allowlist[i] = bt_conn_ref(default_conn);
507 			return 0;
508 		}
509 	}
510 
511 	return -ENOMEM;
512 }
513 
cmd_allowlist_remove(const struct shell * sh,size_t argc,char * argv[])514 static int cmd_allowlist_remove(const struct shell *sh, size_t argc, char *argv[])
515 {
516 	if (!default_conn) {
517 		shell_error(sh, "Not connected");
518 		return 0;
519 	}
520 
521 	l2cap_allowlist_remove(default_conn, 0);
522 
523 	return 0;
524 }
525 
526 #define HELP_NONE "[none]"
527 
528 SHELL_STATIC_SUBCMD_SET_CREATE(allowlist_cmds,
529 	SHELL_CMD_ARG(add, NULL, HELP_NONE, cmd_allowlist_add, 1, 0),
530 	SHELL_CMD_ARG(remove, NULL, HELP_NONE, cmd_allowlist_remove, 1, 0),
531 	SHELL_SUBCMD_SET_END
532 );
533 
534 SHELL_STATIC_SUBCMD_SET_CREATE(l2cap_cmds,
535 	SHELL_CMD_ARG(connect, NULL, "<psm> [sec_level]", cmd_connect, 2, 1),
536 	SHELL_CMD_ARG(disconnect, NULL, HELP_NONE, cmd_disconnect, 1, 0),
537 	SHELL_CMD_ARG(metrics, NULL, "<value on, off>", cmd_metrics, 2, 0),
538 	SHELL_CMD_ARG(recv, NULL, "[delay (in milliseconds)", cmd_recv, 1, 1),
539 	SHELL_CMD_ARG(register, NULL, "<psm> [sec_level] "
540 		      "[policy: allowlist, 16byte_key]", cmd_register, 2, 2),
541 	SHELL_CMD_ARG(send, NULL, "[number of packets] [length of packet(s)]",
542 		      cmd_send, 1, 2),
543 	SHELL_CMD_ARG(allowlist, &allowlist_cmds, HELP_NONE, NULL, 1, 0),
544 #if defined(CONFIG_BT_L2CAP_ECRED)
545 	SHELL_CMD_ARG(ecred-connect, NULL, "<psm (hex)> [sec_level (dec)]",
546 		cmd_ecred_connect, 2, 1),
547 	SHELL_CMD_ARG(ecred-reconfigure, NULL, "<mtu (dec)>",
548 		cmd_ecred_reconfigure, 1, 1),
549 #endif /* CONFIG_BT_L2CAP_ECRED */
550 	SHELL_SUBCMD_SET_END
551 );
552 
cmd_l2cap(const struct shell * sh,size_t argc,char ** argv)553 static int cmd_l2cap(const struct shell *sh, size_t argc, char **argv)
554 {
555 	if (argc == 1) {
556 		shell_help(sh);
557 		/* shell returns 1 when help is printed */
558 		return 1;
559 	}
560 
561 	shell_error(sh, "%s unknown parameter: %s", argv[0], argv[1]);
562 
563 	return -ENOEXEC;
564 }
565 
566 SHELL_CMD_ARG_REGISTER(l2cap, &l2cap_cmds, "Bluetooth L2CAP shell commands",
567 		       cmd_l2cap, 1, 1);
568