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