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