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  * Copyright (c) 2018 Nordic Semiconductor ASA
10  *
11  * SPDX-License-Identifier: Apache-2.0
12  */
13 
14 #include <errno.h>
15 #include <zephyr/types.h>
16 #include <ctype.h>
17 #include <stddef.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <strings.h>
21 #include <zephyr/sys/printk.h>
22 #include <zephyr/sys/byteorder.h>
23 #include <zephyr/sys/util.h>
24 #include <zephyr/sys/util_macro.h>
25 #include <zephyr/kernel.h>
26 
27 #include <zephyr/settings/settings.h>
28 
29 #include <zephyr/bluetooth/hci.h>
30 #include <zephyr/bluetooth/bluetooth.h>
31 #include <zephyr/bluetooth/conn.h>
32 #include <zephyr/bluetooth/rfcomm.h>
33 #include <zephyr/bluetooth/sdp.h>
34 #include <zephyr/bluetooth/iso.h>
35 
36 #include <zephyr/shell/shell.h>
37 
38 #include "bt.h"
39 #include "ll.h"
40 #include "hci.h"
41 #include "../audio/shell/audio.h"
42 
43 static bool no_settings_load;
44 
45 uint8_t selected_id = BT_ID_DEFAULT;
46 const struct shell *ctx_shell;
47 
48 #if defined(CONFIG_BT_CONN)
49 struct bt_conn *default_conn;
50 
51 /* Connection context for BR/EDR legacy pairing in sec mode 3 */
52 static struct bt_conn *pairing_conn;
53 
54 static struct bt_le_oob oob_local;
55 #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
56 static struct bt_le_oob oob_remote;
57 #endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR) */
58 #endif /* CONFIG_BT_CONN */
59 
60 #if defined(CONFIG_BT_SMP)
61 static struct bt_conn_auth_info_cb auth_info_cb;
62 #endif /* CONFIG_BT_SMP */
63 
64 #define NAME_LEN 30
65 
66 #define KEY_STR_LEN 33
67 
68 #define ADV_DATA_DELIMITER ", "
69 
70 /*
71  * Based on the maximum number of parameters for HCI_LE_Generate_DHKey
72  * See BT Core Spec V5.2 Vol. 4, Part E, section 7.8.37
73  */
74 #define HCI_CMD_MAX_PARAM 65
75 
76 #if defined(CONFIG_BT_BROADCASTER)
77 enum {
78 	SHELL_ADV_OPT_CONNECTABLE,
79 	SHELL_ADV_OPT_DISCOVERABLE,
80 	SHELL_ADV_OPT_EXT_ADV,
81 	SHELL_ADV_OPT_APPEARANCE,
82 	SHELL_ADV_OPT_KEEP_RPA,
83 
84 	SHELL_ADV_OPT_NUM,
85 };
86 
87 static ATOMIC_DEFINE(adv_opt, SHELL_ADV_OPT_NUM);
88 #if defined(CONFIG_BT_EXT_ADV)
89 uint8_t selected_adv;
90 struct bt_le_ext_adv *adv_sets[CONFIG_BT_EXT_ADV_MAX_ADV_SET];
91 static ATOMIC_DEFINE(adv_set_opt, SHELL_ADV_OPT_NUM)[CONFIG_BT_EXT_ADV_MAX_ADV_SET];
92 #endif /* CONFIG_BT_EXT_ADV */
93 #endif /* CONFIG_BT_BROADCASTER */
94 
95 #if defined(CONFIG_BT_OBSERVER) || defined(CONFIG_BT_USER_PHY_UPDATE)
phy2str(uint8_t phy)96 static const char *phy2str(uint8_t phy)
97 {
98 	switch (phy) {
99 	case 0: return "No packets";
100 	case BT_GAP_LE_PHY_1M: return "LE 1M";
101 	case BT_GAP_LE_PHY_2M: return "LE 2M";
102 	case BT_GAP_LE_PHY_CODED: return "LE Coded";
103 	default: return "Unknown";
104 	}
105 }
106 #endif
107 
108 #if defined(CONFIG_BT_CONN) || (defined(CONFIG_BT_BROADCASTER) && defined(CONFIG_BT_EXT_ADV))
print_le_addr(const char * desc,const bt_addr_le_t * addr)109 static void print_le_addr(const char *desc, const bt_addr_le_t *addr)
110 {
111 	char addr_str[BT_ADDR_LE_STR_LEN];
112 
113 	const char *addr_desc = bt_addr_le_is_identity(addr) ? "identity" :
114 				bt_addr_le_is_rpa(addr) ? "resolvable" :
115 				"non-resolvable";
116 
117 	bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
118 
119 	shell_print(ctx_shell, "%s address: %s (%s)", desc, addr_str,
120 		    addr_desc);
121 }
122 #endif /* CONFIG_BT_CONN || (CONFIG_BT_BROADCASTER && CONFIG_BT_EXT_ADV) */
123 
124 #if defined(CONFIG_BT_CENTRAL)
125 static int cmd_scan_off(const struct shell *sh);
126 static int cmd_connect_le(const struct shell *sh, size_t argc, char *argv[]);
127 static int cmd_scan_filter_clear_name(const struct shell *sh, size_t argc,
128 				      char *argv[]);
129 
130 static struct bt_auto_connect {
131 	bt_addr_le_t addr;
132 	bool addr_set;
133 	bool connect_name;
134 } auto_connect;
135 #endif
136 
137 #if defined(CONFIG_BT_OBSERVER)
138 static struct bt_scan_filter {
139 	char name[NAME_LEN];
140 	bool name_set;
141 	char addr[BT_ADDR_STR_LEN];
142 	bool addr_set;
143 	int8_t rssi;
144 	bool rssi_set;
145 	uint16_t pa_interval;
146 	bool pa_interval_set;
147 } scan_filter;
148 
149 static const char scan_response_label[] = "[DEVICE]: ";
150 static bool scan_verbose_output;
151 
152 /**
153  * @brief Compares two strings without case sensitivy
154  *
155  * @param substr The substring
156  * @param str The string to find the substring in
157  *
158  * @return true if @substr is a substring of @p, else false
159  */
is_substring(const char * substr,const char * str)160 static bool is_substring(const char *substr, const char *str)
161 {
162 	const size_t str_len = strlen(str);
163 	const size_t sub_str_len = strlen(substr);
164 
165 	if (sub_str_len > str_len) {
166 		return false;
167 	}
168 
169 	for (size_t pos = 0; pos < str_len; pos++) {
170 		if (tolower(substr[0]) == tolower(str[pos])) {
171 			if (pos + sub_str_len > str_len) {
172 				return false;
173 			}
174 
175 			if (strncasecmp(substr, &str[pos], sub_str_len) == 0) {
176 				return true;
177 			}
178 		}
179 	}
180 
181 	return false;
182 }
183 
data_cb(struct bt_data * data,void * user_data)184 static bool data_cb(struct bt_data *data, void *user_data)
185 {
186 	char *name = user_data;
187 
188 	switch (data->type) {
189 	case BT_DATA_NAME_SHORTENED:
190 	case BT_DATA_NAME_COMPLETE:
191 		memcpy(name, data->data, MIN(data->data_len, NAME_LEN - 1));
192 		return false;
193 	default:
194 		return true;
195 	}
196 }
197 
print_data_hex(const uint8_t * data,uint8_t len,enum shell_vt100_color color)198 static void print_data_hex(const uint8_t *data, uint8_t len, enum shell_vt100_color color)
199 {
200 	if (len == 0)
201 		return;
202 
203 	shell_fprintf(ctx_shell, color, "0x");
204 	/* Reverse the byte order when printing as advertising data is LE
205 	 * and the MSB should be first in the printed output.
206 	 */
207 	for (int16_t i = len - 1; i >= 0; i--) {
208 		shell_fprintf(ctx_shell, color, "%02x", data[i]);
209 	}
210 }
211 
print_data_set(uint8_t set_value_len,const uint8_t * scan_data,uint8_t scan_data_len)212 static void print_data_set(uint8_t set_value_len,
213 			   const uint8_t *scan_data, uint8_t scan_data_len)
214 {
215 	uint8_t idx = 0;
216 
217 	if (scan_data_len == 0 || set_value_len > scan_data_len) {
218 		return;
219 	}
220 
221 	do {
222 		if (idx > 0) {
223 			shell_fprintf(ctx_shell, SHELL_INFO, ADV_DATA_DELIMITER);
224 		}
225 
226 		print_data_hex(&scan_data[idx], set_value_len, SHELL_INFO);
227 		idx += set_value_len;
228 	} while (idx + set_value_len <= scan_data_len);
229 
230 	if (idx < scan_data_len) {
231 		shell_fprintf(ctx_shell, SHELL_WARNING, " Excess data: ");
232 		print_data_hex(&scan_data[idx], scan_data_len - idx, SHELL_WARNING);
233 	}
234 }
235 
data_verbose_cb(struct bt_data * data,void * user_data)236 static bool data_verbose_cb(struct bt_data *data, void *user_data)
237 {
238 	shell_fprintf(ctx_shell, SHELL_INFO, "%*sType 0x%02x: ",
239 		      strlen(scan_response_label), "", data->type);
240 
241 	switch (data->type) {
242 	case BT_DATA_UUID16_SOME:
243 	case BT_DATA_UUID16_ALL:
244 	case BT_DATA_SOLICIT16:
245 		print_data_set(BT_UUID_SIZE_16, data->data, data->data_len);
246 		break;
247 	case BT_DATA_SVC_DATA16:
248 		/* Data starts with a UUID16 (2 bytes),
249 		 * the rest is unknown and printed as single bytes
250 		 */
251 		if (data->data_len < BT_UUID_SIZE_16) {
252 			shell_fprintf(ctx_shell, SHELL_WARNING,
253 				      "BT_DATA_SVC_DATA16 data length too short (%u)",
254 				      data->data_len);
255 			break;
256 		}
257 		print_data_set(BT_UUID_SIZE_16, data->data, BT_UUID_SIZE_16);
258 		if (data->data_len > BT_UUID_SIZE_16) {
259 			shell_fprintf(ctx_shell, SHELL_INFO, ADV_DATA_DELIMITER);
260 			print_data_set(1, data->data + BT_UUID_SIZE_16,
261 				       data->data_len - BT_UUID_SIZE_16);
262 		}
263 		break;
264 	case BT_DATA_UUID32_SOME:
265 	case BT_DATA_UUID32_ALL:
266 		print_data_set(BT_UUID_SIZE_32, data->data, data->data_len);
267 		break;
268 	case BT_DATA_SVC_DATA32:
269 		/* Data starts with a UUID32 (4 bytes),
270 		 * the rest is unknown and printed as single bytes
271 		 */
272 		if (data->data_len < BT_UUID_SIZE_32) {
273 			shell_fprintf(ctx_shell, SHELL_WARNING,
274 				      "BT_DATA_SVC_DATA32 data length too short (%u)",
275 				      data->data_len);
276 			break;
277 		}
278 		print_data_set(BT_UUID_SIZE_32, data->data, BT_UUID_SIZE_32);
279 		if (data->data_len > BT_UUID_SIZE_32) {
280 			shell_fprintf(ctx_shell, SHELL_INFO, ADV_DATA_DELIMITER);
281 			print_data_set(1, data->data + BT_UUID_SIZE_32,
282 				       data->data_len - BT_UUID_SIZE_32);
283 		}
284 		break;
285 	case BT_DATA_UUID128_SOME:
286 	case BT_DATA_UUID128_ALL:
287 	case BT_DATA_SOLICIT128:
288 		print_data_set(BT_UUID_SIZE_128, data->data, data->data_len);
289 		break;
290 	case BT_DATA_SVC_DATA128:
291 		/* Data starts with a UUID128 (16 bytes),
292 		 * the rest is unknown and printed as single bytes
293 		 */
294 		if (data->data_len < BT_UUID_SIZE_128) {
295 			shell_fprintf(ctx_shell, SHELL_WARNING,
296 				      "BT_DATA_SVC_DATA128 data length too short (%u)",
297 				      data->data_len);
298 			break;
299 		}
300 		print_data_set(BT_UUID_SIZE_128, data->data, BT_UUID_SIZE_128);
301 		if (data->data_len > BT_UUID_SIZE_128) {
302 			shell_fprintf(ctx_shell, SHELL_INFO, ADV_DATA_DELIMITER);
303 			print_data_set(1, data->data + BT_UUID_SIZE_128,
304 				       data->data_len - BT_UUID_SIZE_128);
305 		}
306 		break;
307 	case BT_DATA_NAME_SHORTENED:
308 	case BT_DATA_NAME_COMPLETE:
309 	case BT_DATA_BROADCAST_NAME:
310 		shell_fprintf(ctx_shell, SHELL_INFO, "%.*s", data->data_len, data->data);
311 		break;
312 	case BT_DATA_PUB_TARGET_ADDR:
313 	case BT_DATA_RAND_TARGET_ADDR:
314 	case BT_DATA_LE_BT_DEVICE_ADDRESS:
315 		print_data_set(BT_ADDR_SIZE, data->data, data->data_len);
316 		break;
317 	case BT_DATA_CSIS_RSI:
318 		print_data_set(3, data->data, data->data_len);
319 		break;
320 	default:
321 		print_data_set(1, data->data, data->data_len);
322 	}
323 
324 	shell_fprintf(ctx_shell, SHELL_INFO, "\n");
325 
326 	return true;
327 }
328 
scan_response_type_txt(uint8_t type)329 static const char *scan_response_type_txt(uint8_t type)
330 {
331 	switch (type) {
332 	case BT_GAP_ADV_TYPE_ADV_IND:
333 		return "ADV_IND";
334 	case BT_GAP_ADV_TYPE_ADV_DIRECT_IND:
335 		return "ADV_DIRECT_IND";
336 	case BT_GAP_ADV_TYPE_ADV_SCAN_IND:
337 		return "ADV_SCAN_IND";
338 	case BT_GAP_ADV_TYPE_ADV_NONCONN_IND:
339 		return "ADV_NONCONN_IND";
340 	case BT_GAP_ADV_TYPE_SCAN_RSP:
341 		return "SCAN_RSP";
342 	case BT_GAP_ADV_TYPE_EXT_ADV:
343 		return "EXT_ADV";
344 	default:
345 		return "UNKNOWN";
346 	}
347 }
348 
scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * buf)349 static void scan_recv(const struct bt_le_scan_recv_info *info,
350 		      struct net_buf_simple *buf)
351 {
352 	char le_addr[BT_ADDR_LE_STR_LEN];
353 	char name[NAME_LEN];
354 	struct net_buf_simple buf_copy;
355 
356 	if (scan_filter.rssi_set && (scan_filter.rssi > info->rssi)) {
357 		return;
358 	}
359 
360 	bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
361 
362 	if (scan_filter.addr_set && !is_substring(scan_filter.addr, le_addr)) {
363 		return;
364 	}
365 
366 	if (scan_verbose_output) {
367 		/* call to bt_data_parse consumes netbufs so shallow clone for verbose output */
368 		net_buf_simple_clone(buf, &buf_copy);
369 	}
370 
371 	(void)memset(name, 0, sizeof(name));
372 
373 	bt_data_parse(buf, data_cb, name);
374 
375 	if (scan_filter.name_set && !is_substring(scan_filter.name, name)) {
376 		return;
377 	}
378 
379 	if (scan_filter.pa_interval_set &&
380 	    (scan_filter.pa_interval > BT_CONN_INTERVAL_TO_MS(info->interval))) {
381 		return;
382 	}
383 
384 	shell_print(ctx_shell, "%s%s, AD evt type %u, RSSI %i %s "
385 		    "C:%u S:%u D:%d SR:%u E:%u Prim: %s, Secn: %s, "
386 		    "Interval: 0x%04x (%u us), SID: 0x%x",
387 		    scan_response_label,
388 		    le_addr, info->adv_type, info->rssi, name,
389 		    (info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) != 0,
390 		    (info->adv_props & BT_GAP_ADV_PROP_SCANNABLE) != 0,
391 		    (info->adv_props & BT_GAP_ADV_PROP_DIRECTED) != 0,
392 		    (info->adv_props & BT_GAP_ADV_PROP_SCAN_RESPONSE) != 0,
393 		    (info->adv_props & BT_GAP_ADV_PROP_EXT_ADV) != 0,
394 		    phy2str(info->primary_phy), phy2str(info->secondary_phy),
395 		    info->interval, BT_CONN_INTERVAL_TO_US(info->interval),
396 		    info->sid);
397 
398 	if (scan_verbose_output) {
399 		shell_info(ctx_shell,
400 			   "%*s[SCAN DATA START - %s]",
401 			   strlen(scan_response_label), "",
402 			   scan_response_type_txt(info->adv_type));
403 		bt_data_parse(&buf_copy, data_verbose_cb, NULL);
404 		shell_info(ctx_shell, "%*s[SCAN DATA END]", strlen(scan_response_label), "");
405 	}
406 
407 	/* Store address for later use */
408 #if defined(CONFIG_BT_CENTRAL)
409 	auto_connect.addr_set = true;
410 	bt_addr_le_copy(&auto_connect.addr, info->addr);
411 
412 	/* Use the above auto_connect.addr address to automatically connect */
413 	if (auto_connect.connect_name) {
414 		auto_connect.connect_name = false;
415 
416 		cmd_scan_off(ctx_shell);
417 
418 		/* "name" is what would be in argv[0] normally */
419 		cmd_scan_filter_clear_name(ctx_shell, 1, (char *[]){ "name" });
420 
421 		/* "connect" is what would be in argv[0] normally */
422 		cmd_connect_le(ctx_shell, 1, (char *[]){ "connect" });
423 	}
424 #endif /* CONFIG_BT_CENTRAL */
425 }
426 
scan_timeout(void)427 static void scan_timeout(void)
428 {
429 	shell_print(ctx_shell, "Scan timeout");
430 
431 #if defined(CONFIG_BT_CENTRAL)
432 	if (auto_connect.connect_name) {
433 		auto_connect.connect_name = false;
434 		/* "name" is what would be in argv[0] normally */
435 		cmd_scan_filter_clear_name(ctx_shell, 1, (char *[]){ "name" });
436 	}
437 #endif /* CONFIG_BT_CENTRAL */
438 }
439 #endif /* CONFIG_BT_OBSERVER */
440 
441 #if defined(CONFIG_BT_EXT_ADV)
442 #if defined(CONFIG_BT_BROADCASTER)
adv_sent(struct bt_le_ext_adv * adv,struct bt_le_ext_adv_sent_info * info)443 static void adv_sent(struct bt_le_ext_adv *adv,
444 		     struct bt_le_ext_adv_sent_info *info)
445 {
446 	shell_print(ctx_shell, "Advertiser[%d] %p sent %d",
447 		    bt_le_ext_adv_get_index(adv), adv, info->num_sent);
448 }
449 
adv_scanned(struct bt_le_ext_adv * adv,struct bt_le_ext_adv_scanned_info * info)450 static void adv_scanned(struct bt_le_ext_adv *adv,
451 			struct bt_le_ext_adv_scanned_info *info)
452 {
453 	char str[BT_ADDR_LE_STR_LEN];
454 
455 	bt_addr_le_to_str(info->addr, str, sizeof(str));
456 
457 	shell_print(ctx_shell, "Advertiser[%d] %p scanned by %s",
458 		    bt_le_ext_adv_get_index(adv), adv, str);
459 }
460 #endif /* CONFIG_BT_BROADCASTER */
461 
462 #if defined(CONFIG_BT_PERIPHERAL)
adv_connected(struct bt_le_ext_adv * adv,struct bt_le_ext_adv_connected_info * info)463 static void adv_connected(struct bt_le_ext_adv *adv,
464 			  struct bt_le_ext_adv_connected_info *info)
465 {
466 	char str[BT_ADDR_LE_STR_LEN];
467 
468 	bt_addr_le_to_str(bt_conn_get_dst(info->conn), str, sizeof(str));
469 
470 	shell_print(ctx_shell, "Advertiser[%d] %p connected by %s",
471 		    bt_le_ext_adv_get_index(adv), adv, str);
472 }
473 #endif /* CONFIG_BT_PERIPHERAL */
474 
475 #if defined(CONFIG_BT_PRIVACY)
adv_rpa_expired(struct bt_le_ext_adv * adv)476 static bool adv_rpa_expired(struct bt_le_ext_adv *adv)
477 {
478 	uint8_t adv_index = bt_le_ext_adv_get_index(adv);
479 
480 	bool keep_rpa = atomic_test_bit(adv_set_opt[adv_index],
481 					  SHELL_ADV_OPT_KEEP_RPA);
482 	shell_print(ctx_shell, "Advertiser[%d] %p RPA %s",
483 		    adv_index, adv,
484 		    keep_rpa ? "not expired" : "expired");
485 
486 	return keep_rpa;
487 }
488 #endif /* defined(CONFIG_BT_PRIVACY) */
489 
490 #endif /* CONFIG_BT_EXT_ADV */
491 
492 #if !defined(CONFIG_BT_CONN)
493 #if 0 /* FIXME: Add support for changing prompt */
494 static const char *current_prompt(void)
495 {
496 	return NULL;
497 }
498 #endif
499 #endif /* !CONFIG_BT_CONN */
500 
501 #if defined(CONFIG_BT_CONN)
502 #if 0 /* FIXME: Add support for changing prompt */
503 static const char *current_prompt(void)
504 {
505 	static char str[BT_ADDR_LE_STR_LEN + 2];
506 	static struct bt_conn_info info;
507 
508 	if (!default_conn) {
509 		return NULL;
510 	}
511 
512 	if (bt_conn_get_info(default_conn, &info) < 0) {
513 		return NULL;
514 	}
515 
516 	if (info.type != BT_CONN_TYPE_LE) {
517 		return NULL;
518 	}
519 
520 	bt_addr_le_to_str(info.le.dst, str, sizeof(str) - 2);
521 	strcat(str, "> ");
522 	return str;
523 }
524 #endif
525 
conn_addr_str(struct bt_conn * conn,char * addr,size_t len)526 void conn_addr_str(struct bt_conn *conn, char *addr, size_t len)
527 {
528 	struct bt_conn_info info;
529 
530 	if (bt_conn_get_info(conn, &info) < 0) {
531 		addr[0] = '\0';
532 		return;
533 	}
534 
535 	switch (info.type) {
536 #if defined(CONFIG_BT_BREDR)
537 	case BT_CONN_TYPE_BR:
538 		bt_addr_to_str(info.br.dst, addr, len);
539 		break;
540 #endif
541 	case BT_CONN_TYPE_LE:
542 		bt_addr_le_to_str(info.le.dst, addr, len);
543 		break;
544 	}
545 }
546 
print_le_oob(const struct shell * sh,struct bt_le_oob * oob)547 static void print_le_oob(const struct shell *sh, struct bt_le_oob *oob)
548 {
549 	char addr[BT_ADDR_LE_STR_LEN];
550 	char c[KEY_STR_LEN];
551 	char r[KEY_STR_LEN];
552 
553 	bt_addr_le_to_str(&oob->addr, addr, sizeof(addr));
554 
555 	bin2hex(oob->le_sc_data.c, sizeof(oob->le_sc_data.c), c, sizeof(c));
556 	bin2hex(oob->le_sc_data.r, sizeof(oob->le_sc_data.r), r, sizeof(r));
557 
558 	shell_print(sh, "OOB data:");
559 	shell_print(sh, "%-29s %-32s %-32s", "addr", "random", "confirm");
560 	shell_print(sh, "%29s %32s %32s", addr, r, c);
561 }
562 
connected(struct bt_conn * conn,uint8_t err)563 static void connected(struct bt_conn *conn, uint8_t err)
564 {
565 	char addr[BT_ADDR_LE_STR_LEN];
566 
567 	conn_addr_str(conn, addr, sizeof(addr));
568 
569 	if (err) {
570 		shell_error(ctx_shell, "Failed to connect to %s (0x%02x)", addr,
571 			     err);
572 		goto done;
573 	}
574 
575 	shell_print(ctx_shell, "Connected: %s", addr);
576 
577 	if (!default_conn) {
578 		default_conn = bt_conn_ref(conn);
579 	}
580 
581 done:
582 	/* clear connection reference for sec mode 3 pairing */
583 	if (pairing_conn) {
584 		bt_conn_unref(pairing_conn);
585 		pairing_conn = NULL;
586 	}
587 }
588 
disconencted_set_new_default_conn_cb(struct bt_conn * conn,void * user_data)589 static void disconencted_set_new_default_conn_cb(struct bt_conn *conn, void *user_data)
590 {
591 	struct bt_conn_info info;
592 
593 	if (default_conn != NULL) {
594 		/* nop */
595 		return;
596 	}
597 
598 	if (bt_conn_get_info(conn, &info) != 0) {
599 		shell_error(ctx_shell, "Unable to get info: conn %p", conn);
600 		return;
601 	}
602 
603 	if (info.state == BT_CONN_STATE_CONNECTED) {
604 		char addr_str[BT_ADDR_LE_STR_LEN];
605 
606 		default_conn = bt_conn_ref(conn);
607 
608 		bt_addr_le_to_str(info.le.dst, addr_str, sizeof(addr_str));
609 		shell_print(ctx_shell, "Selected conn is now: %s", addr_str);
610 	}
611 }
612 
disconnected(struct bt_conn * conn,uint8_t reason)613 static void disconnected(struct bt_conn *conn, uint8_t reason)
614 {
615 	char addr[BT_ADDR_LE_STR_LEN];
616 
617 	conn_addr_str(conn, addr, sizeof(addr));
618 	shell_print(ctx_shell, "Disconnected: %s (reason 0x%02x)", addr, reason);
619 
620 	if (default_conn == conn) {
621 		bt_conn_unref(default_conn);
622 		default_conn = NULL;
623 
624 		/* If we are connected to other devices, set one of them as default */
625 		bt_conn_foreach(BT_CONN_TYPE_LE, disconencted_set_new_default_conn_cb, NULL);
626 	}
627 }
628 
le_param_req(struct bt_conn * conn,struct bt_le_conn_param * param)629 static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param)
630 {
631 	shell_print(ctx_shell, "LE conn  param req: int (0x%04x, 0x%04x) lat %d"
632 		    " to %d", param->interval_min, param->interval_max,
633 		    param->latency, param->timeout);
634 
635 	return true;
636 }
637 
le_param_updated(struct bt_conn * conn,uint16_t interval,uint16_t latency,uint16_t timeout)638 static void le_param_updated(struct bt_conn *conn, uint16_t interval,
639 			     uint16_t latency, uint16_t timeout)
640 {
641 	shell_print(ctx_shell, "LE conn param updated: int 0x%04x lat %d "
642 		     "to %d", interval, latency, timeout);
643 }
644 
645 #if defined(CONFIG_BT_SMP)
identity_resolved(struct bt_conn * conn,const bt_addr_le_t * rpa,const bt_addr_le_t * identity)646 static void identity_resolved(struct bt_conn *conn, const bt_addr_le_t *rpa,
647 			      const bt_addr_le_t *identity)
648 {
649 	char addr_identity[BT_ADDR_LE_STR_LEN];
650 	char addr_rpa[BT_ADDR_LE_STR_LEN];
651 
652 	bt_addr_le_to_str(identity, addr_identity, sizeof(addr_identity));
653 	bt_addr_le_to_str(rpa, addr_rpa, sizeof(addr_rpa));
654 
655 	shell_print(ctx_shell, "Identity resolved %s -> %s", addr_rpa,
656 	      addr_identity);
657 }
658 #endif
659 
660 #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
security_err_str(enum bt_security_err err)661 static const char *security_err_str(enum bt_security_err err)
662 {
663 	switch (err) {
664 	case BT_SECURITY_ERR_SUCCESS:
665 		return "Success";
666 	case BT_SECURITY_ERR_AUTH_FAIL:
667 		return "Authentication failure";
668 	case BT_SECURITY_ERR_PIN_OR_KEY_MISSING:
669 		return "PIN or key missing";
670 	case BT_SECURITY_ERR_OOB_NOT_AVAILABLE:
671 		return "OOB not available";
672 	case BT_SECURITY_ERR_AUTH_REQUIREMENT:
673 		return "Authentication requirements";
674 	case BT_SECURITY_ERR_PAIR_NOT_SUPPORTED:
675 		return "Pairing not supported";
676 	case BT_SECURITY_ERR_PAIR_NOT_ALLOWED:
677 		return "Pairing not allowed";
678 	case BT_SECURITY_ERR_INVALID_PARAM:
679 		return "Invalid parameters";
680 	case BT_SECURITY_ERR_UNSPECIFIED:
681 		return "Unspecified";
682 	default:
683 		return "Unknown";
684 	}
685 }
686 
security_changed(struct bt_conn * conn,bt_security_t level,enum bt_security_err err)687 static void security_changed(struct bt_conn *conn, bt_security_t level,
688 			     enum bt_security_err err)
689 {
690 	char addr[BT_ADDR_LE_STR_LEN];
691 
692 	conn_addr_str(conn, addr, sizeof(addr));
693 
694 	if (!err) {
695 		shell_print(ctx_shell, "Security changed: %s level %u", addr,
696 			    level);
697 	} else {
698 		shell_print(ctx_shell, "Security failed: %s level %u "
699 			    "reason: %s (%d)",
700 			    addr, level, security_err_str(err), err);
701 	}
702 }
703 #endif
704 
705 #if defined(CONFIG_BT_REMOTE_INFO)
ver_str(uint8_t ver)706 static const char *ver_str(uint8_t ver)
707 {
708 	const char * const str[] = {
709 		"1.0b", "1.1", "1.2", "2.0", "2.1", "3.0", "4.0", "4.1", "4.2",
710 		"5.0", "5.1", "5.2", "5.3", "5.4"
711 	};
712 
713 	if (ver < ARRAY_SIZE(str)) {
714 		return str[ver];
715 	}
716 
717 	return "unknown";
718 }
719 
remote_info_available(struct bt_conn * conn,struct bt_conn_remote_info * remote_info)720 static void remote_info_available(struct bt_conn *conn,
721 				  struct bt_conn_remote_info *remote_info)
722 {
723 	struct bt_conn_info info;
724 
725 	bt_conn_get_info(conn, &info);
726 
727 	if (IS_ENABLED(CONFIG_BT_REMOTE_VERSION)) {
728 		shell_print(ctx_shell,
729 			    "Remote LMP version %s (0x%02x) subversion 0x%04x "
730 			    "manufacturer 0x%04x", ver_str(remote_info->version),
731 			    remote_info->version, remote_info->subversion,
732 			    remote_info->manufacturer);
733 	}
734 
735 	if (info.type == BT_CONN_TYPE_LE) {
736 		uint8_t features[8];
737 		char features_str[2 * sizeof(features) +  1];
738 
739 		sys_memcpy_swap(features, remote_info->le.features,
740 				sizeof(features));
741 		bin2hex(features, sizeof(features),
742 			features_str, sizeof(features_str));
743 		shell_print(ctx_shell, "LE Features: 0x%s ", features_str);
744 	}
745 }
746 #endif /* defined(CONFIG_BT_REMOTE_INFO) */
747 
748 #if defined(CONFIG_BT_USER_DATA_LEN_UPDATE)
le_data_len_updated(struct bt_conn * conn,struct bt_conn_le_data_len_info * info)749 void le_data_len_updated(struct bt_conn *conn,
750 			 struct bt_conn_le_data_len_info *info)
751 {
752 	shell_print(ctx_shell,
753 		    "LE data len updated: TX (len: %d time: %d)"
754 		    " RX (len: %d time: %d)", info->tx_max_len,
755 		    info->tx_max_time, info->rx_max_len, info->rx_max_time);
756 }
757 #endif
758 
759 #if defined(CONFIG_BT_USER_PHY_UPDATE)
le_phy_updated(struct bt_conn * conn,struct bt_conn_le_phy_info * info)760 void le_phy_updated(struct bt_conn *conn,
761 		    struct bt_conn_le_phy_info *info)
762 {
763 	shell_print(ctx_shell, "LE PHY updated: TX PHY %s, RX PHY %s",
764 		    phy2str(info->tx_phy), phy2str(info->rx_phy));
765 }
766 #endif
767 
768 static struct bt_conn_cb conn_callbacks = {
769 	.connected = connected,
770 	.disconnected = disconnected,
771 	.le_param_req = le_param_req,
772 	.le_param_updated = le_param_updated,
773 #if defined(CONFIG_BT_SMP)
774 	.identity_resolved = identity_resolved,
775 #endif
776 #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
777 	.security_changed = security_changed,
778 #endif
779 #if defined(CONFIG_BT_REMOTE_INFO)
780 	.remote_info_available = remote_info_available,
781 #endif
782 #if defined(CONFIG_BT_USER_DATA_LEN_UPDATE)
783 	.le_data_len_updated = le_data_len_updated,
784 #endif
785 #if defined(CONFIG_BT_USER_PHY_UPDATE)
786 	.le_phy_updated = le_phy_updated,
787 #endif
788 };
789 #endif /* CONFIG_BT_CONN */
790 
791 #if defined(CONFIG_BT_OBSERVER)
792 static struct bt_le_scan_cb scan_callbacks = {
793 	.recv = scan_recv,
794 	.timeout = scan_timeout,
795 };
796 #endif /* defined(CONFIG_BT_OBSERVER) */
797 
798 #if defined(CONFIG_BT_EXT_ADV)
799 #if defined(CONFIG_BT_BROADCASTER)
800 static struct bt_le_ext_adv_cb adv_callbacks = {
801 	.sent = adv_sent,
802 	.scanned = adv_scanned,
803 #if defined(CONFIG_BT_PERIPHERAL)
804 	.connected = adv_connected,
805 #endif /* CONFIG_BT_PERIPHERAL */
806 #if defined(CONFIG_BT_PRIVACY)
807 	.rpa_expired = adv_rpa_expired,
808 #endif /* defined(CONFIG_BT_PRIVACY) */
809 
810 };
811 #endif /* CONFIG_BT_BROADCASTER */
812 #endif /* CONFIG_BT_EXT_ADV */
813 
814 
815 #if defined(CONFIG_BT_PER_ADV_SYNC)
816 struct bt_le_per_adv_sync *per_adv_syncs[CONFIG_BT_PER_ADV_SYNC_MAX];
817 
per_adv_sync_sync_cb(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)818 static void per_adv_sync_sync_cb(struct bt_le_per_adv_sync *sync,
819 				 struct bt_le_per_adv_sync_synced_info *info)
820 {
821 	char le_addr[BT_ADDR_LE_STR_LEN];
822 	char past_peer[BT_ADDR_LE_STR_LEN];
823 
824 	bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
825 
826 	if (info->conn) {
827 		conn_addr_str(info->conn, past_peer, sizeof(past_peer));
828 	} else {
829 		memset(past_peer, 0, sizeof(past_peer));
830 	}
831 
832 	shell_print(ctx_shell, "PER_ADV_SYNC[%u]: [DEVICE]: %s synced, "
833 		    "Interval 0x%04x (%u us), PHY %s, SD 0x%04X, PAST peer %s",
834 		    bt_le_per_adv_sync_get_index(sync), le_addr,
835 		    info->interval, BT_CONN_INTERVAL_TO_US(info->interval),
836 		    phy2str(info->phy), info->service_data, past_peer);
837 
838 	if (info->conn) { /* if from PAST */
839 		for (int i = 0; i < ARRAY_SIZE(per_adv_syncs); i++) {
840 			if (!per_adv_syncs[i]) {
841 				per_adv_syncs[i] = sync;
842 				break;
843 			}
844 		}
845 	}
846 }
847 
per_adv_sync_terminated_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)848 static void per_adv_sync_terminated_cb(
849 	struct bt_le_per_adv_sync *sync,
850 	const struct bt_le_per_adv_sync_term_info *info)
851 {
852 	char le_addr[BT_ADDR_LE_STR_LEN];
853 
854 	for (int i = 0; i < ARRAY_SIZE(per_adv_syncs); i++) {
855 		if (per_adv_syncs[i] == sync) {
856 			per_adv_syncs[i] = NULL;
857 			break;
858 		}
859 	}
860 
861 	bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
862 	shell_print(ctx_shell, "PER_ADV_SYNC[%u]: [DEVICE]: %s sync terminated",
863 		    bt_le_per_adv_sync_get_index(sync), le_addr);
864 }
865 
per_adv_sync_recv_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_recv_info * info,struct net_buf_simple * buf)866 static void per_adv_sync_recv_cb(
867 	struct bt_le_per_adv_sync *sync,
868 	const struct bt_le_per_adv_sync_recv_info *info,
869 	struct net_buf_simple *buf)
870 {
871 	char le_addr[BT_ADDR_LE_STR_LEN];
872 
873 	bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
874 	shell_print(ctx_shell, "PER_ADV_SYNC[%u]: [DEVICE]: %s, tx_power %i, "
875 		    "RSSI %i, CTE %u, data length %u",
876 		    bt_le_per_adv_sync_get_index(sync), le_addr, info->tx_power,
877 		    info->rssi, info->cte_type, buf->len);
878 }
879 
per_adv_sync_biginfo_cb(struct bt_le_per_adv_sync * sync,const struct bt_iso_biginfo * biginfo)880 static void per_adv_sync_biginfo_cb(struct bt_le_per_adv_sync *sync,
881 				    const struct bt_iso_biginfo *biginfo)
882 {
883 	char le_addr[BT_ADDR_LE_STR_LEN];
884 
885 	bt_addr_le_to_str(biginfo->addr, le_addr, sizeof(le_addr));
886 	shell_print(ctx_shell, "BIG_INFO PER_ADV_SYNC[%u]: [DEVICE]: %s, sid 0x%02x, num_bis %u, "
887 		    "nse 0x%02x, interval 0x%04x (%u us), bn 0x%02x, pto 0x%02x, irc 0x%02x, "
888 		    "max_pdu 0x%04x, sdu_interval 0x%04x, max_sdu 0x%04x, phy %s, framing 0x%02x, "
889 		    "%sencrypted",
890 		    bt_le_per_adv_sync_get_index(sync), le_addr, biginfo->sid, biginfo->num_bis,
891 		    biginfo->sub_evt_count, biginfo->iso_interval,
892 		    BT_CONN_INTERVAL_TO_US(biginfo->iso_interval), biginfo->burst_number,
893 		    biginfo->offset, biginfo->rep_count, biginfo->max_pdu, biginfo->sdu_interval,
894 		    biginfo->max_sdu, phy2str(biginfo->phy), biginfo->framing,
895 		    biginfo->encryption ? "" : "not ");
896 }
897 
898 static struct bt_le_per_adv_sync_cb per_adv_sync_cb = {
899 	.synced = per_adv_sync_sync_cb,
900 	.term = per_adv_sync_terminated_cb,
901 	.recv = per_adv_sync_recv_cb,
902 	.biginfo = per_adv_sync_biginfo_cb,
903 };
904 #endif /* CONFIG_BT_PER_ADV_SYNC */
905 
bt_ready(int err)906 static void bt_ready(int err)
907 {
908 	if (err) {
909 		shell_error(ctx_shell, "Bluetooth init failed (err %d)", err);
910 		return;
911 	}
912 
913 	shell_print(ctx_shell, "Bluetooth initialized");
914 
915 	if (IS_ENABLED(CONFIG_SETTINGS) && !no_settings_load) {
916 		settings_load();
917 		shell_print(ctx_shell, "Settings Loaded");
918 	}
919 
920 	if (IS_ENABLED(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)) {
921 		bt_le_oob_set_legacy_flag(true);
922 	}
923 
924 #if defined(CONFIG_BT_OBSERVER)
925 	bt_le_scan_cb_register(&scan_callbacks);
926 #endif
927 
928 #if defined(CONFIG_BT_CONN)
929 	default_conn = NULL;
930 
931 	bt_conn_cb_register(&conn_callbacks);
932 #endif /* CONFIG_BT_CONN */
933 
934 #if defined(CONFIG_BT_PER_ADV_SYNC)
935 	bt_le_per_adv_sync_cb_register(&per_adv_sync_cb);
936 #endif /* CONFIG_BT_PER_ADV_SYNC */
937 
938 #if defined(CONFIG_BT_SMP)
939 	bt_conn_auth_info_cb_register(&auth_info_cb);
940 #endif /* CONFIG_BT_SMP */
941 }
942 
cmd_init(const struct shell * sh,size_t argc,char * argv[])943 static int cmd_init(const struct shell *sh, size_t argc, char *argv[])
944 {
945 	int err;
946 	bool sync = false;
947 
948 	ctx_shell = sh;
949 
950 	for (size_t argn = 1; argn < argc; argn++) {
951 		const char *arg = argv[argn];
952 
953 		if (!strcmp(arg, "no-settings-load")) {
954 			no_settings_load = true;
955 		} else if (!strcmp(arg, "sync")) {
956 			sync = true;
957 		} else {
958 			shell_help(sh);
959 			return SHELL_CMD_HELP_PRINTED;
960 		}
961 	}
962 
963 	if (sync) {
964 		err = bt_enable(NULL);
965 		bt_ready(err);
966 	} else {
967 		err = bt_enable(bt_ready);
968 		if (err) {
969 			shell_error(sh, "Bluetooth init failed (err %d)",
970 				    err);
971 		}
972 	}
973 
974 	return err;
975 }
976 
cmd_disable(const struct shell * sh,size_t argc,char * argv[])977 static int cmd_disable(const struct shell *sh, size_t argc, char *argv[])
978 {
979 	return bt_disable();
980 }
981 
982 #ifdef CONFIG_SETTINGS
cmd_settings_load(const struct shell * sh,size_t argc,char * argv[])983 static int cmd_settings_load(const struct shell *sh, size_t argc,
984 			     char *argv[])
985 {
986 	int err;
987 
988 	err = settings_load();
989 	if (err) {
990 		shell_error(sh, "Settings load failed (err %d)", err);
991 		return err;
992 	}
993 
994 	shell_print(sh, "Settings loaded");
995 	return 0;
996 }
997 #endif
998 
999 #if defined(CONFIG_BT_HCI)
cmd_hci_cmd(const struct shell * sh,size_t argc,char * argv[])1000 static int cmd_hci_cmd(const struct shell *sh, size_t argc, char *argv[])
1001 {
1002 	uint8_t ogf;
1003 	uint16_t ocf;
1004 	struct net_buf *buf = NULL, *rsp;
1005 	int err;
1006 	static uint8_t hex_data[HCI_CMD_MAX_PARAM];
1007 	int hex_data_len;
1008 
1009 	hex_data_len = 0;
1010 	ogf = strtoul(argv[1], NULL, 16);
1011 	ocf = strtoul(argv[2], NULL, 16);
1012 
1013 	if (argc > 3) {
1014 		size_t len;
1015 
1016 		if (strlen(argv[3]) > 2 * HCI_CMD_MAX_PARAM) {
1017 			shell_error(sh, "Data field too large\n");
1018 			return -ENOEXEC;
1019 		}
1020 
1021 		len = hex2bin(argv[3], strlen(argv[3]), &hex_data[hex_data_len],
1022 			      sizeof(hex_data) - hex_data_len);
1023 		if (!len) {
1024 			shell_error(sh, "HCI command illegal data field\n");
1025 			return -ENOEXEC;
1026 		}
1027 
1028 		buf = bt_hci_cmd_create(BT_OP(ogf, ocf), len);
1029 		net_buf_add_mem(buf, hex_data, len);
1030 	}
1031 
1032 	err = bt_hci_cmd_send_sync(BT_OP(ogf, ocf), buf, &rsp);
1033 	if (err) {
1034 		shell_error(sh, "HCI command failed (err %d)", err);
1035 		return err;
1036 	} else {
1037 		shell_hexdump(sh, rsp->data, rsp->len);
1038 		net_buf_unref(rsp);
1039 	}
1040 
1041 	return 0;
1042 }
1043 #endif /* CONFIG_BT_HCI */
1044 
cmd_name(const struct shell * sh,size_t argc,char * argv[])1045 static int cmd_name(const struct shell *sh, size_t argc, char *argv[])
1046 {
1047 	int err;
1048 
1049 	if (argc < 2) {
1050 		shell_print(sh, "Bluetooth Local Name: %s", bt_get_name());
1051 		return 0;
1052 	}
1053 
1054 	err = bt_set_name(argv[1]);
1055 	if (err) {
1056 		shell_error(sh, "Unable to set name %s (err %d)", argv[1],
1057 			    err);
1058 		return err;
1059 	}
1060 
1061 	return 0;
1062 }
1063 
cmd_appearance(const struct shell * sh,size_t argc,char * argv[])1064 static int cmd_appearance(const struct shell *sh, size_t argc, char *argv[])
1065 {
1066 	if (argc == 1) {
1067 		shell_print(sh, "Bluetooth Appearance: 0x%04x", bt_get_appearance());
1068 		return 0;
1069 	}
1070 
1071 #if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC)
1072 	uint16_t app;
1073 	int err;
1074 	const char *val;
1075 
1076 	val = argv[1];
1077 	if (strlen(val) != 6 || strncmp(val, "0x", 2) ||
1078 	    !hex2bin(&val[2], strlen(&val[2]), ((uint8_t *)&app), sizeof(app))) {
1079 		shell_error(sh, "Argument must be 0x followed by exactly 4 hex digits.");
1080 		return -EINVAL;
1081 	}
1082 
1083 	app = sys_be16_to_cpu(app);
1084 
1085 	err = bt_set_appearance(app);
1086 	if (err) {
1087 		shell_error(sh, "bt_set_appearance(0x%04x) failed with err %d", app, err);
1088 		return err;
1089 	}
1090 #endif /* defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC) */
1091 
1092 	return 0;
1093 }
1094 
cmd_id_create(const struct shell * sh,size_t argc,char * argv[])1095 static int cmd_id_create(const struct shell *sh, size_t argc, char *argv[])
1096 {
1097 	char addr_str[BT_ADDR_LE_STR_LEN];
1098 	bt_addr_le_t addr;
1099 	int err;
1100 
1101 	if (argc > 1) {
1102 		err = bt_addr_le_from_str(argv[1], "random", &addr);
1103 		if (err) {
1104 			shell_error(sh, "Invalid address");
1105 		}
1106 	} else {
1107 		bt_addr_le_copy(&addr, BT_ADDR_LE_ANY);
1108 	}
1109 
1110 	err = bt_id_create(&addr, NULL);
1111 	if (err < 0) {
1112 		shell_error(sh, "Creating new ID failed (err %d)", err);
1113 		return err;
1114 	}
1115 
1116 	bt_addr_le_to_str(&addr, addr_str, sizeof(addr_str));
1117 	shell_print(sh, "New identity (%d) created: %s", err, addr_str);
1118 
1119 	return 0;
1120 }
1121 
cmd_id_reset(const struct shell * sh,size_t argc,char * argv[])1122 static int cmd_id_reset(const struct shell *sh, size_t argc, char *argv[])
1123 {
1124 	char addr_str[BT_ADDR_LE_STR_LEN];
1125 	bt_addr_le_t addr;
1126 	uint8_t id;
1127 	int err;
1128 
1129 	if (argc < 2) {
1130 		shell_error(sh, "Identity identifier not specified");
1131 		return -ENOEXEC;
1132 	}
1133 
1134 	id = strtol(argv[1], NULL, 10);
1135 
1136 	if (argc > 2) {
1137 		err = bt_addr_le_from_str(argv[2], "random", &addr);
1138 		if (err) {
1139 			shell_print(sh, "Invalid address");
1140 			return err;
1141 		}
1142 	} else {
1143 		bt_addr_le_copy(&addr, BT_ADDR_LE_ANY);
1144 	}
1145 
1146 	err = bt_id_reset(id, &addr, NULL);
1147 	if (err < 0) {
1148 		shell_print(sh, "Resetting ID %u failed (err %d)", id, err);
1149 		return err;
1150 	}
1151 
1152 	bt_addr_le_to_str(&addr, addr_str, sizeof(addr_str));
1153 	shell_print(sh, "Identity %u reset: %s", id, addr_str);
1154 
1155 	return 0;
1156 }
1157 
cmd_id_delete(const struct shell * sh,size_t argc,char * argv[])1158 static int cmd_id_delete(const struct shell *sh, size_t argc, char *argv[])
1159 {
1160 	uint8_t id;
1161 	int err;
1162 
1163 	if (argc < 2) {
1164 		shell_error(sh, "Identity identifier not specified");
1165 		return -ENOEXEC;
1166 	}
1167 
1168 	id = strtol(argv[1], NULL, 10);
1169 
1170 	err = bt_id_delete(id);
1171 	if (err < 0) {
1172 		shell_error(sh, "Deleting ID %u failed (err %d)", id, err);
1173 		return err;
1174 	}
1175 
1176 	shell_print(sh, "Identity %u deleted", id);
1177 
1178 	return 0;
1179 }
1180 
cmd_id_show(const struct shell * sh,size_t argc,char * argv[])1181 static int cmd_id_show(const struct shell *sh, size_t argc, char *argv[])
1182 {
1183 	bt_addr_le_t addrs[CONFIG_BT_ID_MAX];
1184 	size_t i, count = CONFIG_BT_ID_MAX;
1185 
1186 	bt_id_get(addrs, &count);
1187 
1188 	for (i = 0; i < count; i++) {
1189 		char addr_str[BT_ADDR_LE_STR_LEN];
1190 
1191 		bt_addr_le_to_str(&addrs[i], addr_str, sizeof(addr_str));
1192 		shell_print(sh, "%s%zu: %s", i == selected_id ? "*" : " ", i,
1193 		      addr_str);
1194 	}
1195 
1196 	return 0;
1197 }
1198 
cmd_id_select(const struct shell * sh,size_t argc,char * argv[])1199 static int cmd_id_select(const struct shell *sh, size_t argc, char *argv[])
1200 {
1201 	char addr_str[BT_ADDR_LE_STR_LEN];
1202 	bt_addr_le_t addrs[CONFIG_BT_ID_MAX];
1203 	size_t count = CONFIG_BT_ID_MAX;
1204 	uint8_t id;
1205 
1206 	id = strtol(argv[1], NULL, 10);
1207 
1208 	bt_id_get(addrs, &count);
1209 	if (count <= id) {
1210 		shell_error(sh, "Invalid identity");
1211 		return -ENOEXEC;
1212 	}
1213 
1214 	bt_addr_le_to_str(&addrs[id], addr_str, sizeof(addr_str));
1215 	shell_print(sh, "Selected identity: %s", addr_str);
1216 	selected_id = id;
1217 
1218 	return 0;
1219 }
1220 
1221 #if defined(CONFIG_BT_OBSERVER)
cmd_active_scan_on(const struct shell * sh,uint32_t options,uint16_t timeout)1222 static int cmd_active_scan_on(const struct shell *sh, uint32_t options,
1223 			      uint16_t timeout)
1224 {
1225 	int err;
1226 	struct bt_le_scan_param param = {
1227 			.type       = BT_LE_SCAN_TYPE_ACTIVE,
1228 			.options    = BT_LE_SCAN_OPT_NONE,
1229 			.interval   = BT_GAP_SCAN_FAST_INTERVAL,
1230 			.window     = BT_GAP_SCAN_FAST_WINDOW,
1231 			.timeout    = timeout, };
1232 
1233 	param.options |= options;
1234 
1235 	err = bt_le_scan_start(&param, NULL);
1236 	if (err) {
1237 		shell_error(sh, "Bluetooth set active scan failed "
1238 		      "(err %d)", err);
1239 		return err;
1240 	} else {
1241 		shell_print(sh, "Bluetooth active scan enabled");
1242 	}
1243 
1244 	return 0;
1245 }
1246 
cmd_passive_scan_on(const struct shell * sh,uint32_t options,uint16_t timeout)1247 static int cmd_passive_scan_on(const struct shell *sh, uint32_t options,
1248 			       uint16_t timeout)
1249 {
1250 	struct bt_le_scan_param param = {
1251 			.type       = BT_LE_SCAN_TYPE_PASSIVE,
1252 			.options    = BT_LE_SCAN_OPT_NONE,
1253 			.interval   = 0x10,
1254 			.window     = 0x10,
1255 			.timeout    = timeout, };
1256 	int err;
1257 
1258 	param.options |= options;
1259 
1260 	err = bt_le_scan_start(&param, NULL);
1261 	if (err) {
1262 		shell_error(sh, "Bluetooth set passive scan failed "
1263 			    "(err %d)", err);
1264 		return err;
1265 	} else {
1266 		shell_print(sh, "Bluetooth passive scan enabled");
1267 	}
1268 
1269 	return 0;
1270 }
1271 
cmd_scan_off(const struct shell * sh)1272 static int cmd_scan_off(const struct shell *sh)
1273 {
1274 	int err;
1275 
1276 	err = bt_le_scan_stop();
1277 	if (err) {
1278 		shell_error(sh, "Stopping scanning failed (err %d)", err);
1279 		return err;
1280 	} else {
1281 		shell_print(sh, "Scan successfully stopped");
1282 	}
1283 
1284 	return 0;
1285 }
1286 
cmd_scan(const struct shell * sh,size_t argc,char * argv[])1287 static int cmd_scan(const struct shell *sh, size_t argc, char *argv[])
1288 {
1289 	const char *action;
1290 	uint32_t options = 0;
1291 	uint16_t timeout = 0;
1292 
1293 	/* Parse duplicate filtering data */
1294 	for (size_t argn = 2; argn < argc; argn++) {
1295 		const char *arg = argv[argn];
1296 
1297 		if (!strcmp(arg, "dups")) {
1298 			options |= BT_LE_SCAN_OPT_FILTER_DUPLICATE;
1299 		} else if (!strcmp(arg, "nodups")) {
1300 			options &= ~BT_LE_SCAN_OPT_FILTER_DUPLICATE;
1301 		} else if (!strcmp(arg, "fal")) {
1302 			options |= BT_LE_SCAN_OPT_FILTER_ACCEPT_LIST;
1303 		} else if (!strcmp(arg, "coded")) {
1304 			options |= BT_LE_SCAN_OPT_CODED;
1305 		} else if (!strcmp(arg, "no-1m")) {
1306 			options |= BT_LE_SCAN_OPT_NO_1M;
1307 		} else if (!strcmp(arg, "timeout")) {
1308 			if (++argn == argc) {
1309 				shell_help(sh);
1310 				return SHELL_CMD_HELP_PRINTED;
1311 			}
1312 
1313 			timeout = strtoul(argv[argn], NULL, 16);
1314 		} else {
1315 			shell_help(sh);
1316 			return SHELL_CMD_HELP_PRINTED;
1317 		}
1318 	}
1319 
1320 	action = argv[1];
1321 	if (!strcmp(action, "on")) {
1322 		return cmd_active_scan_on(sh, options, timeout);
1323 	} else if (!strcmp(action, "off")) {
1324 		return cmd_scan_off(sh);
1325 	} else if (!strcmp(action, "passive")) {
1326 		return cmd_passive_scan_on(sh, options, timeout);
1327 	} else {
1328 		shell_help(sh);
1329 		return SHELL_CMD_HELP_PRINTED;
1330 	}
1331 
1332 	return 0;
1333 }
1334 
cmd_scan_verbose_output(const struct shell * sh,size_t argc,char * argv[])1335 static int cmd_scan_verbose_output(const struct shell *sh, size_t argc, char *argv[])
1336 {
1337 	const char *verbose_state;
1338 
1339 	verbose_state = argv[1];
1340 	if (!strcmp(verbose_state, "on")) {
1341 		scan_verbose_output = true;
1342 	} else if (!strcmp(verbose_state, "off")) {
1343 		scan_verbose_output = false;
1344 	} else {
1345 		shell_help(sh);
1346 		return SHELL_CMD_HELP_PRINTED;
1347 	}
1348 
1349 	return 0;
1350 }
1351 
cmd_scan_filter_set_name(const struct shell * sh,size_t argc,char * argv[])1352 static int cmd_scan_filter_set_name(const struct shell *sh, size_t argc,
1353 				    char *argv[])
1354 {
1355 	const char *name_arg = argv[1];
1356 
1357 	if (strlen(name_arg) >= sizeof(scan_filter.name)) {
1358 		shell_error(ctx_shell, "Name is too long (max %zu): %s\n",
1359 			    sizeof(scan_filter.name), name_arg);
1360 		return -ENOEXEC;
1361 	}
1362 
1363 	strcpy(scan_filter.name, name_arg);
1364 	scan_filter.name_set = true;
1365 
1366 	return 0;
1367 }
1368 
cmd_scan_filter_set_addr(const struct shell * sh,size_t argc,char * argv[])1369 static int cmd_scan_filter_set_addr(const struct shell *sh, size_t argc,
1370 				    char *argv[])
1371 {
1372 	const size_t max_cpy_len = sizeof(scan_filter.addr) - 1;
1373 	const char *addr_arg = argv[1];
1374 
1375 	/* Validate length including null terminator. */
1376 	if (strlen(addr_arg) > max_cpy_len) {
1377 		shell_error(ctx_shell, "Invalid address string: %s\n",
1378 			    addr_arg);
1379 		return -ENOEXEC;
1380 	}
1381 
1382 	/* Validate input to check if valid (subset of) BT address */
1383 	for (size_t i = 0; i < strlen(addr_arg); i++) {
1384 		const char c = addr_arg[i];
1385 		uint8_t tmp;
1386 
1387 		if (c != ':' && char2hex(c, &tmp) < 0) {
1388 			shell_error(ctx_shell,
1389 					"Invalid address string: %s\n",
1390 					addr_arg);
1391 			return -ENOEXEC;
1392 		}
1393 	}
1394 
1395 	strncpy(scan_filter.addr, addr_arg, max_cpy_len);
1396 	scan_filter.addr[max_cpy_len] = '\0'; /* ensure NULL termination */
1397 	scan_filter.addr_set = true;
1398 
1399 	return 0;
1400 }
1401 
cmd_scan_filter_set_rssi(const struct shell * sh,size_t argc,char * argv[])1402 static int cmd_scan_filter_set_rssi(const struct shell *sh, size_t argc, char *argv[])
1403 {
1404 	int err = 0;
1405 	long rssi;
1406 
1407 	rssi = shell_strtol(argv[1], 10, &err);
1408 
1409 	if (!err) {
1410 		if (IN_RANGE(rssi, INT8_MIN, INT8_MAX)) {
1411 			scan_filter.rssi = (int8_t)rssi;
1412 			scan_filter.rssi_set = true;
1413 			shell_print(sh, "RSSI cutoff set at %d dB", scan_filter.rssi);
1414 
1415 			return 0;
1416 		}
1417 
1418 		shell_print(sh, "value out of bounds (%d to %d)", INT8_MIN, INT8_MAX);
1419 		err = -ERANGE;
1420 	}
1421 
1422 	shell_print(sh, "error %d", err);
1423 	shell_help(sh);
1424 
1425 	return SHELL_CMD_HELP_PRINTED;
1426 }
1427 
cmd_scan_filter_set_pa_interval(const struct shell * sh,size_t argc,char * argv[])1428 static int cmd_scan_filter_set_pa_interval(const struct shell *sh, size_t argc,
1429 					   char *argv[])
1430 {
1431 	unsigned long pa_interval;
1432 	int err = 0;
1433 
1434 	pa_interval = shell_strtoul(argv[1], 10, &err);
1435 
1436 	if (!err) {
1437 		if (IN_RANGE(pa_interval,
1438 			     BT_GAP_PER_ADV_MIN_INTERVAL,
1439 			     BT_GAP_PER_ADV_MAX_INTERVAL)) {
1440 			scan_filter.pa_interval = (uint16_t)pa_interval;
1441 			scan_filter.pa_interval_set = true;
1442 			shell_print(sh, "PA interval cutoff set at %u",
1443 				    scan_filter.pa_interval);
1444 
1445 			return 0;
1446 		}
1447 
1448 		shell_print(sh, "value out of bounds (%d to %d)",
1449 			    BT_GAP_PER_ADV_MIN_INTERVAL,
1450 			    BT_GAP_PER_ADV_MAX_INTERVAL);
1451 
1452 		err = -ERANGE;
1453 	}
1454 
1455 	shell_print(sh, "error %d", err);
1456 	shell_help(sh);
1457 
1458 	return SHELL_CMD_HELP_PRINTED;
1459 }
1460 
cmd_scan_filter_clear_all(const struct shell * sh,size_t argc,char * argv[])1461 static int cmd_scan_filter_clear_all(const struct shell *sh, size_t argc,
1462 				     char *argv[])
1463 {
1464 	(void)memset(&scan_filter, 0, sizeof(scan_filter));
1465 
1466 	return 0;
1467 }
1468 
cmd_scan_filter_clear_name(const struct shell * sh,size_t argc,char * argv[])1469 static int cmd_scan_filter_clear_name(const struct shell *sh, size_t argc,
1470 				      char *argv[])
1471 {
1472 	(void)memset(scan_filter.name, 0, sizeof(scan_filter.name));
1473 	scan_filter.name_set = false;
1474 
1475 	return 0;
1476 }
1477 
cmd_scan_filter_clear_addr(const struct shell * sh,size_t argc,char * argv[])1478 static int cmd_scan_filter_clear_addr(const struct shell *sh, size_t argc,
1479 				      char *argv[])
1480 {
1481 	(void)memset(scan_filter.addr, 0, sizeof(scan_filter.addr));
1482 	scan_filter.addr_set = false;
1483 
1484 	return 0;
1485 }
1486 
1487 #endif /* CONFIG_BT_OBSERVER */
1488 
1489 #if defined(CONFIG_BT_BROADCASTER)
ad_init(struct bt_data * data_array,const size_t data_array_size,const atomic_t * adv_opt)1490 static ssize_t ad_init(struct bt_data *data_array, const size_t data_array_size,
1491 		       const atomic_t *adv_opt)
1492 {
1493 	const bool discoverable = atomic_test_bit(adv_opt, SHELL_ADV_OPT_DISCOVERABLE);
1494 	const bool appearance = atomic_test_bit(adv_opt, SHELL_ADV_OPT_APPEARANCE);
1495 	const bool adv_ext = atomic_test_bit(adv_opt, SHELL_ADV_OPT_EXT_ADV);
1496 	static uint8_t ad_flags;
1497 	size_t ad_len = 0;
1498 
1499 	/* Set BR/EDR Not Supported if LE-only device */
1500 	ad_flags = IS_ENABLED(CONFIG_BT_BREDR) ? 0 : BT_LE_AD_NO_BREDR;
1501 
1502 	if (discoverable) {
1503 		/* A privacy-enabled Set Member should advertise RSI values only when in
1504 		 * the GAP Limited Discoverable mode.
1505 		 */
1506 		if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
1507 		    IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER) &&
1508 		    svc_inst != NULL) {
1509 			ad_flags |= BT_LE_AD_LIMITED;
1510 		} else {
1511 			ad_flags |= BT_LE_AD_GENERAL;
1512 		}
1513 	}
1514 
1515 	if (ad_flags != 0) {
1516 		__ASSERT(data_array_size > ad_len, "No space for AD_FLAGS");
1517 		data_array[ad_len].type = BT_DATA_FLAGS;
1518 		data_array[ad_len].data_len = sizeof(ad_flags);
1519 		data_array[ad_len].data = &ad_flags;
1520 		ad_len++;
1521 	}
1522 
1523 	if (appearance) {
1524 		const uint16_t appearance = bt_get_appearance();
1525 		static uint8_t appearance_data[sizeof(appearance)];
1526 
1527 		__ASSERT(data_array_size > ad_len, "No space for appearance");
1528 		sys_put_le16(appearance, appearance_data);
1529 		data_array[ad_len].type = BT_DATA_GAP_APPEARANCE;
1530 		data_array[ad_len].data_len = sizeof(appearance_data);
1531 		data_array[ad_len].data = appearance_data;
1532 		ad_len++;
1533 	}
1534 
1535 	if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER)) {
1536 		ssize_t csis_ad_len;
1537 
1538 		csis_ad_len = csis_ad_data_add(&data_array[ad_len],
1539 					       data_array_size - ad_len, discoverable);
1540 		if (csis_ad_len < 0) {
1541 			shell_error(ctx_shell, "Failed to add CSIS data (err %d)", csis_ad_len);
1542 			return ad_len;
1543 		}
1544 
1545 		ad_len += csis_ad_len;
1546 	}
1547 
1548 	if (IS_ENABLED(CONFIG_BT_AUDIO) && IS_ENABLED(CONFIG_BT_EXT_ADV) && adv_ext) {
1549 		const bool connectable = atomic_test_bit(adv_opt, SHELL_ADV_OPT_CONNECTABLE);
1550 		ssize_t audio_ad_len;
1551 
1552 		audio_ad_len = audio_ad_data_add(&data_array[ad_len], data_array_size - ad_len,
1553 						 discoverable, connectable);
1554 		if (audio_ad_len < 0) {
1555 			return audio_ad_len;
1556 		}
1557 
1558 		ad_len += audio_ad_len;
1559 	}
1560 
1561 	return ad_len;
1562 }
1563 
cmd_advertise(const struct shell * sh,size_t argc,char * argv[])1564 static int cmd_advertise(const struct shell *sh, size_t argc, char *argv[])
1565 {
1566 	struct bt_le_adv_param param = {};
1567 	struct bt_data ad[3];
1568 	bool discoverable = true;
1569 	bool appearance = false;
1570 	ssize_t ad_len;
1571 	int err;
1572 
1573 	if (!strcmp(argv[1], "off")) {
1574 		if (bt_le_adv_stop() < 0) {
1575 			shell_error(sh, "Failed to stop advertising");
1576 			return -ENOEXEC;
1577 		} else {
1578 			shell_print(sh, "Advertising stopped");
1579 		}
1580 
1581 		return 0;
1582 	}
1583 
1584 	param.id = selected_id;
1585 	param.interval_min = BT_GAP_ADV_FAST_INT_MIN_2;
1586 	param.interval_max = BT_GAP_ADV_FAST_INT_MAX_2;
1587 
1588 	if (!strcmp(argv[1], "on")) {
1589 		param.options = (BT_LE_ADV_OPT_CONNECTABLE |
1590 				 BT_LE_ADV_OPT_USE_NAME);
1591 	} else if (!strcmp(argv[1], "scan")) {
1592 		param.options = BT_LE_ADV_OPT_USE_NAME;
1593 	} else if (!strcmp(argv[1], "nconn")) {
1594 		param.options = 0U;
1595 	} else {
1596 		goto fail;
1597 	}
1598 
1599 	for (size_t argn = 2; argn < argc; argn++) {
1600 		const char *arg = argv[argn];
1601 
1602 		if (!strcmp(arg, "discov")) {
1603 			discoverable = true;
1604 		} else if (!strcmp(arg, "non_discov")) {
1605 			discoverable = false;
1606 		} else if (!strcmp(arg, "appearance")) {
1607 			appearance = true;
1608 		} else if (!strcmp(arg, "fal")) {
1609 			param.options |= BT_LE_ADV_OPT_FILTER_SCAN_REQ;
1610 			param.options |= BT_LE_ADV_OPT_FILTER_CONN;
1611 		} else if (!strcmp(arg, "fal-scan")) {
1612 			param.options |= BT_LE_ADV_OPT_FILTER_SCAN_REQ;
1613 		} else if (!strcmp(arg, "fal-conn")) {
1614 			param.options |= BT_LE_ADV_OPT_FILTER_CONN;
1615 		} else if (!strcmp(arg, "identity")) {
1616 			param.options |= BT_LE_ADV_OPT_USE_IDENTITY;
1617 		} else if (!strcmp(arg, "no-name")) {
1618 			param.options &= ~BT_LE_ADV_OPT_USE_NAME;
1619 		} else if (!strcmp(arg, "name-ad")) {
1620 			param.options |= BT_LE_ADV_OPT_USE_NAME;
1621 			param.options |= BT_LE_ADV_OPT_FORCE_NAME_IN_AD;
1622 		} else if (!strcmp(arg, "one-time")) {
1623 			param.options |= BT_LE_ADV_OPT_ONE_TIME;
1624 		} else if (!strcmp(arg, "disable-37")) {
1625 			param.options |= BT_LE_ADV_OPT_DISABLE_CHAN_37;
1626 		} else if (!strcmp(arg, "disable-38")) {
1627 			param.options |= BT_LE_ADV_OPT_DISABLE_CHAN_38;
1628 		} else if (!strcmp(arg, "disable-39")) {
1629 			param.options |= BT_LE_ADV_OPT_DISABLE_CHAN_39;
1630 		} else {
1631 			goto fail;
1632 		}
1633 	}
1634 
1635 	atomic_clear(adv_opt);
1636 	atomic_set_bit_to(adv_opt, SHELL_ADV_OPT_CONNECTABLE,
1637 			  (param.options & BT_LE_ADV_OPT_CONNECTABLE) > 0);
1638 	atomic_set_bit_to(adv_opt, SHELL_ADV_OPT_DISCOVERABLE, discoverable);
1639 	atomic_set_bit_to(adv_opt, SHELL_ADV_OPT_APPEARANCE, appearance);
1640 
1641 	ad_len = ad_init(ad, ARRAY_SIZE(ad), adv_opt);
1642 	if (ad_len < 0) {
1643 		return -ENOEXEC;
1644 	}
1645 
1646 	err = bt_le_adv_start(&param, ad_len > 0 ? ad : NULL, ad_len, NULL, 0);
1647 	if (err < 0) {
1648 		shell_error(sh, "Failed to start advertising (err %d)",
1649 			    err);
1650 		return err;
1651 	} else {
1652 		shell_print(sh, "Advertising started");
1653 	}
1654 
1655 	return 0;
1656 
1657 fail:
1658 	shell_help(sh);
1659 	return -ENOEXEC;
1660 }
1661 
1662 #if defined(CONFIG_BT_PERIPHERAL)
cmd_directed_adv(const struct shell * sh,size_t argc,char * argv[])1663 static int cmd_directed_adv(const struct shell *sh,
1664 			     size_t argc, char *argv[])
1665 {
1666 	int err;
1667 	bt_addr_le_t addr;
1668 	struct bt_le_adv_param param;
1669 
1670 	err = bt_addr_le_from_str(argv[1], argv[2], &addr);
1671 	param = *BT_LE_ADV_CONN_DIR(&addr);
1672 	if (err) {
1673 		shell_error(sh, "Invalid peer address (err %d)", err);
1674 		return err;
1675 	}
1676 
1677 	for (size_t argn = 3; argn < argc; argn++) {
1678 		const char *arg = argv[argn];
1679 
1680 		if (!strcmp(arg, "low")) {
1681 			param.options |= BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY;
1682 			param.interval_max = BT_GAP_ADV_FAST_INT_MAX_2;
1683 			param.interval_min = BT_GAP_ADV_FAST_INT_MIN_2;
1684 		} else if (!strcmp(arg, "identity")) {
1685 			param.options |= BT_LE_ADV_OPT_USE_IDENTITY;
1686 		} else if (!strcmp(arg, "dir-rpa")) {
1687 			param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA;
1688 		} else if (!strcmp(arg, "disable-37")) {
1689 			param.options |= BT_LE_ADV_OPT_DISABLE_CHAN_37;
1690 		} else if (!strcmp(arg, "disable-38")) {
1691 			param.options |= BT_LE_ADV_OPT_DISABLE_CHAN_38;
1692 		} else if (!strcmp(arg, "disable-39")) {
1693 			param.options |= BT_LE_ADV_OPT_DISABLE_CHAN_39;
1694 		} else {
1695 			shell_help(sh);
1696 			return -ENOEXEC;
1697 		}
1698 	}
1699 
1700 	err = bt_le_adv_start(&param, NULL, 0, NULL, 0);
1701 	if (err) {
1702 		shell_error(sh, "Failed to start directed advertising (%d)",
1703 			    err);
1704 		return -ENOEXEC;
1705 	} else {
1706 		shell_print(sh, "Started directed advertising");
1707 	}
1708 
1709 	return 0;
1710 }
1711 #endif /* CONFIG_BT_PERIPHERAL */
1712 
1713 #if defined(CONFIG_BT_EXT_ADV)
adv_param_parse(size_t argc,char * argv[],struct bt_le_adv_param * param)1714 static bool adv_param_parse(size_t argc, char *argv[],
1715 			   struct bt_le_adv_param *param)
1716 {
1717 	memset(param, 0, sizeof(struct bt_le_adv_param));
1718 
1719 	if (!strcmp(argv[1], "conn-scan")) {
1720 		param->options |= BT_LE_ADV_OPT_CONNECTABLE;
1721 		param->options |= BT_LE_ADV_OPT_SCANNABLE;
1722 	} else if (!strcmp(argv[1], "conn-nscan")) {
1723 		param->options |= BT_LE_ADV_OPT_CONNECTABLE;
1724 	} else if (!strcmp(argv[1], "nconn-scan")) {
1725 		param->options |= BT_LE_ADV_OPT_SCANNABLE;
1726 	} else if (!strcmp(argv[1], "nconn-nscan")) {
1727 		/* Acceptable option, nothing to do */
1728 	} else {
1729 		return false;
1730 	}
1731 
1732 	for (size_t argn = 2; argn < argc; argn++) {
1733 		const char *arg = argv[argn];
1734 
1735 		if (!strcmp(arg, "ext-adv")) {
1736 			param->options |= BT_LE_ADV_OPT_EXT_ADV;
1737 		} else if (!strcmp(arg, "coded")) {
1738 			param->options |= BT_LE_ADV_OPT_CODED;
1739 		} else if (!strcmp(arg, "no-2m")) {
1740 			param->options |= BT_LE_ADV_OPT_NO_2M;
1741 		} else if (!strcmp(arg, "anon")) {
1742 			param->options |= BT_LE_ADV_OPT_ANONYMOUS;
1743 		} else if (!strcmp(arg, "tx-power")) {
1744 			param->options |= BT_LE_ADV_OPT_USE_TX_POWER;
1745 		} else if (!strcmp(arg, "scan-reports")) {
1746 			param->options |= BT_LE_ADV_OPT_NOTIFY_SCAN_REQ;
1747 		} else if (!strcmp(arg, "fal")) {
1748 			param->options |= BT_LE_ADV_OPT_FILTER_SCAN_REQ;
1749 			param->options |= BT_LE_ADV_OPT_FILTER_CONN;
1750 		} else if (!strcmp(arg, "fal-scan")) {
1751 			param->options |= BT_LE_ADV_OPT_FILTER_SCAN_REQ;
1752 		} else if (!strcmp(arg, "fal-conn")) {
1753 			param->options |= BT_LE_ADV_OPT_FILTER_CONN;
1754 		} else if (!strcmp(arg, "identity")) {
1755 			param->options |= BT_LE_ADV_OPT_USE_IDENTITY;
1756 		} else if (!strcmp(arg, "name")) {
1757 			param->options |= BT_LE_ADV_OPT_USE_NAME;
1758 		} else if (!strcmp(arg, "name-ad")) {
1759 			param->options |= BT_LE_ADV_OPT_USE_NAME;
1760 			param->options |= BT_LE_ADV_OPT_FORCE_NAME_IN_AD;
1761 		} else if (!strcmp(arg, "low")) {
1762 			param->options |= BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY;
1763 		} else if (!strcmp(arg, "dir-rpa")) {
1764 			param->options |= BT_LE_ADV_OPT_DIR_ADDR_RPA;
1765 		} else if (!strcmp(arg, "disable-37")) {
1766 			param->options |= BT_LE_ADV_OPT_DISABLE_CHAN_37;
1767 		} else if (!strcmp(arg, "disable-38")) {
1768 			param->options |= BT_LE_ADV_OPT_DISABLE_CHAN_38;
1769 		} else if (!strcmp(arg, "disable-39")) {
1770 			param->options |= BT_LE_ADV_OPT_DISABLE_CHAN_39;
1771 		} else if (!strcmp(arg, "directed")) {
1772 			static bt_addr_le_t addr;
1773 
1774 			if ((argn + 2) >= argc) {
1775 				return false;
1776 			}
1777 
1778 			if (bt_addr_le_from_str(argv[argn + 1], argv[argn + 2],
1779 						&addr)) {
1780 				return false;
1781 			}
1782 
1783 			param->peer = &addr;
1784 			argn += 2;
1785 		} else {
1786 			return false;
1787 		}
1788 	}
1789 
1790 	param->id = selected_id;
1791 	param->sid = 0;
1792 	if (param->peer &&
1793 	    !(param->options & BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY)) {
1794 		param->interval_min = 0;
1795 		param->interval_max = 0;
1796 	} else {
1797 		param->interval_min = BT_GAP_ADV_FAST_INT_MIN_2;
1798 		param->interval_max = BT_GAP_ADV_FAST_INT_MAX_2;
1799 	}
1800 
1801 	return true;
1802 }
1803 
cmd_adv_create(const struct shell * sh,size_t argc,char * argv[])1804 static int cmd_adv_create(const struct shell *sh, size_t argc, char *argv[])
1805 {
1806 	struct bt_le_adv_param param;
1807 	struct bt_le_ext_adv *adv;
1808 	uint8_t adv_index;
1809 	int err;
1810 
1811 	if (!adv_param_parse(argc, argv, &param)) {
1812 		shell_help(sh);
1813 		return -ENOEXEC;
1814 	}
1815 
1816 	err = bt_le_ext_adv_create(&param, &adv_callbacks, &adv);
1817 	if (err) {
1818 		shell_error(sh, "Failed to create advertiser set (%d)", err);
1819 		return -ENOEXEC;
1820 	}
1821 
1822 	adv_index = bt_le_ext_adv_get_index(adv);
1823 	adv_sets[adv_index] = adv;
1824 
1825 	atomic_clear(adv_set_opt[adv_index]);
1826 	atomic_set_bit_to(adv_set_opt[adv_index], SHELL_ADV_OPT_CONNECTABLE,
1827 			  (param.options & BT_LE_ADV_OPT_CONNECTABLE) > 0);
1828 	atomic_set_bit_to(adv_set_opt[adv_index], SHELL_ADV_OPT_EXT_ADV,
1829 			  (param.options & BT_LE_ADV_OPT_EXT_ADV) > 0);
1830 
1831 	shell_print(sh, "Created adv id: %d, adv: %p", adv_index, adv);
1832 
1833 	return 0;
1834 }
1835 
cmd_adv_param(const struct shell * sh,size_t argc,char * argv[])1836 static int cmd_adv_param(const struct shell *sh, size_t argc, char *argv[])
1837 {
1838 	struct bt_le_ext_adv *adv = adv_sets[selected_adv];
1839 	struct bt_le_adv_param param;
1840 	int err;
1841 
1842 	if (!adv_param_parse(argc, argv, &param)) {
1843 		shell_help(sh);
1844 		return -ENOEXEC;
1845 	}
1846 
1847 	err = bt_le_ext_adv_update_param(adv, &param);
1848 	if (err) {
1849 		shell_error(sh, "Failed to update advertiser set (%d)", err);
1850 		return -ENOEXEC;
1851 	}
1852 
1853 	return 0;
1854 }
1855 
cmd_adv_data(const struct shell * sh,size_t argc,char * argv[])1856 static int cmd_adv_data(const struct shell *sh, size_t argc, char *argv[])
1857 {
1858 	struct bt_le_ext_adv *adv = adv_sets[selected_adv];
1859 	static uint8_t hex_data[1650];
1860 	bool appearance = false;
1861 	struct bt_data *data;
1862 	struct bt_data ad[9];
1863 	struct bt_data sd[9];
1864 	size_t hex_data_len;
1865 	size_t ad_len = 0;
1866 	size_t sd_len = 0;
1867 	bool discoverable = false;
1868 	size_t *data_len;
1869 	int err;
1870 
1871 	if (!adv) {
1872 		return -EINVAL;
1873 	}
1874 
1875 	hex_data_len = 0;
1876 	data = ad;
1877 	data_len = &ad_len;
1878 
1879 	for (size_t argn = 1; argn < argc; argn++) {
1880 		const char *arg = argv[argn];
1881 
1882 		if (strcmp(arg, "scan-response") &&
1883 		    *data_len == ARRAY_SIZE(ad)) {
1884 			/* Maximum entries limit reached. */
1885 			shell_print(sh, "Failed to set advertising data: "
1886 					   "Maximum entries limit reached");
1887 
1888 			return -ENOEXEC;
1889 		}
1890 
1891 		if (!strcmp(arg, "discov")) {
1892 			discoverable = true;
1893 		} else if (!strcmp(arg, "non_discov")) {
1894 			discoverable = false;
1895 		} else if (!strcmp(arg, "appearance")) {
1896 			appearance = true;
1897 		} else if (!strcmp(arg, "scan-response")) {
1898 			if (data == sd) {
1899 				shell_print(sh, "Failed to set advertising data: "
1900 						   "duplicate scan-response option");
1901 				return -ENOEXEC;
1902 			}
1903 
1904 			data = sd;
1905 			data_len = &sd_len;
1906 		} else {
1907 			size_t len;
1908 
1909 			len = hex2bin(arg, strlen(arg), &hex_data[hex_data_len],
1910 				      sizeof(hex_data) - hex_data_len);
1911 
1912 			if (!len || (len - 1) != (hex_data[hex_data_len])) {
1913 				shell_print(sh, "Failed to set advertising data: "
1914 						   "malformed hex data");
1915 				return -ENOEXEC;
1916 			}
1917 
1918 			data[*data_len].type = hex_data[hex_data_len + 1];
1919 			data[*data_len].data_len = len - 2;
1920 			data[*data_len].data = &hex_data[hex_data_len + 2];
1921 			(*data_len)++;
1922 			hex_data_len += len;
1923 		}
1924 	}
1925 
1926 	atomic_set_bit_to(adv_set_opt[selected_adv], SHELL_ADV_OPT_DISCOVERABLE, discoverable);
1927 	atomic_set_bit_to(adv_set_opt[selected_adv], SHELL_ADV_OPT_APPEARANCE,
1928 			  appearance);
1929 
1930 	ad_len = ad_init(&ad[*data_len], ARRAY_SIZE(ad) - *data_len,
1931 			 adv_set_opt[selected_adv]);
1932 	if (ad_len < 0) {
1933 		shell_error(sh, "Failed to initialize stack advertising data");
1934 
1935 		return -ENOEXEC;
1936 	}
1937 
1938 	err = bt_le_ext_adv_set_data(adv, ad_len > 0 ? ad : NULL, ad_len,
1939 					  sd_len > 0 ? sd : NULL, sd_len);
1940 	if (err) {
1941 		shell_print(sh, "Failed to set advertising set data (%d)",
1942 			    err);
1943 		return -ENOEXEC;
1944 	}
1945 
1946 	return 0;
1947 }
1948 
cmd_adv_start(const struct shell * sh,size_t argc,char * argv[])1949 static int cmd_adv_start(const struct shell *sh, size_t argc, char *argv[])
1950 {
1951 	struct bt_le_ext_adv *adv = adv_sets[selected_adv];
1952 	struct bt_le_ext_adv_start_param param;
1953 	uint8_t num_events = 0;
1954 	int32_t timeout = 0;
1955 	int err;
1956 
1957 	if (!adv) {
1958 		shell_print(sh, "Advertiser[%d] not created", selected_adv);
1959 		return -EINVAL;
1960 	}
1961 
1962 	for (size_t argn = 1; argn < argc; argn++) {
1963 		const char *arg = argv[argn];
1964 
1965 		if (!strcmp(arg, "timeout")) {
1966 			if (++argn == argc) {
1967 				goto fail_show_help;
1968 			}
1969 
1970 			timeout = strtoul(argv[argn], NULL, 16);
1971 		}
1972 
1973 		if (!strcmp(arg, "num-events")) {
1974 			if (++argn == argc) {
1975 				goto fail_show_help;
1976 			}
1977 
1978 			num_events = strtoul(argv[argn], NULL, 16);
1979 		}
1980 	}
1981 
1982 	param.timeout = timeout;
1983 	param.num_events = num_events;
1984 
1985 	err = bt_le_ext_adv_start(adv, &param);
1986 	if (err) {
1987 		shell_print(sh, "Failed to start advertising set (%d)", err);
1988 		return -ENOEXEC;
1989 	}
1990 
1991 	shell_print(sh, "Advertiser[%d] %p set started", selected_adv, adv);
1992 	return 0;
1993 
1994 fail_show_help:
1995 	shell_help(sh);
1996 	return -ENOEXEC;
1997 }
1998 
cmd_adv_stop(const struct shell * sh,size_t argc,char * argv[])1999 static int cmd_adv_stop(const struct shell *sh, size_t argc, char *argv[])
2000 {
2001 	struct bt_le_ext_adv *adv = adv_sets[selected_adv];
2002 	int err;
2003 
2004 	if (!adv) {
2005 		shell_print(sh, "Advertiser[%d] not created", selected_adv);
2006 		return -EINVAL;
2007 	}
2008 
2009 	err = bt_le_ext_adv_stop(adv);
2010 	if (err) {
2011 		shell_print(sh, "Failed to stop advertising set (%d)", err);
2012 		return -ENOEXEC;
2013 	}
2014 
2015 	shell_print(sh, "Advertiser set stopped");
2016 	return 0;
2017 }
2018 
cmd_adv_delete(const struct shell * sh,size_t argc,char * argv[])2019 static int cmd_adv_delete(const struct shell *sh, size_t argc, char *argv[])
2020 {
2021 	struct bt_le_ext_adv *adv = adv_sets[selected_adv];
2022 	int err;
2023 
2024 	if (!adv) {
2025 		shell_print(sh, "Advertiser[%d] not created", selected_adv);
2026 		return -EINVAL;
2027 	}
2028 
2029 	err = bt_le_ext_adv_delete(adv);
2030 	if (err) {
2031 		shell_error(ctx_shell, "Failed to delete advertiser set");
2032 		return err;
2033 	}
2034 
2035 	adv_sets[selected_adv] = NULL;
2036 	return 0;
2037 }
2038 
cmd_adv_select(const struct shell * sh,size_t argc,char * argv[])2039 static int cmd_adv_select(const struct shell *sh, size_t argc, char *argv[])
2040 {
2041 	if (argc == 2) {
2042 		uint8_t id = strtol(argv[1], NULL, 10);
2043 
2044 		if (!(id < ARRAY_SIZE(adv_sets))) {
2045 			return -EINVAL;
2046 		}
2047 
2048 		selected_adv = id;
2049 		return 0;
2050 	}
2051 
2052 	for (int i = 0; i < ARRAY_SIZE(adv_sets); i++) {
2053 		if (adv_sets[i]) {
2054 			shell_print(sh, "Advertiser[%d] %p", i, adv_sets[i]);
2055 		}
2056 	}
2057 
2058 	return -ENOEXEC;
2059 }
2060 
cmd_adv_info(const struct shell * sh,size_t argc,char * argv[])2061 static int cmd_adv_info(const struct shell *sh, size_t argc, char *argv[])
2062 {
2063 	struct bt_le_ext_adv *adv = adv_sets[selected_adv];
2064 	struct bt_le_ext_adv_info info;
2065 	int err;
2066 
2067 	if (!adv) {
2068 		return -EINVAL;
2069 	}
2070 
2071 	err = bt_le_ext_adv_get_info(adv, &info);
2072 	if (err) {
2073 		shell_error(sh, "OOB data failed");
2074 		return err;
2075 	}
2076 
2077 	shell_print(sh, "Advertiser[%d] %p", selected_adv, adv);
2078 	shell_print(sh, "Id: %d, TX power: %d dBm", info.id, info.tx_power);
2079 	print_le_addr("Address", info.addr);
2080 
2081 	return 0;
2082 }
2083 
2084 #if defined(CONFIG_BT_PERIPHERAL)
cmd_adv_oob(const struct shell * sh,size_t argc,char * argv[])2085 static int cmd_adv_oob(const struct shell *sh, size_t argc, char *argv[])
2086 {
2087 	struct bt_le_ext_adv *adv = adv_sets[selected_adv];
2088 	int err;
2089 
2090 	if (!adv) {
2091 		return -EINVAL;
2092 	}
2093 
2094 	err = bt_le_ext_adv_oob_get_local(adv, &oob_local);
2095 	if (err) {
2096 		shell_error(sh, "OOB data failed");
2097 		return err;
2098 	}
2099 
2100 	print_le_oob(sh, &oob_local);
2101 
2102 	return 0;
2103 }
2104 #endif /* CONFIG_BT_PERIPHERAL */
2105 
2106 #if defined(CONFIG_BT_PRIVACY)
cmd_adv_rpa_expire(const struct shell * sh,size_t argc,char * argv[])2107 static int cmd_adv_rpa_expire(const struct shell *sh, size_t argc, char *argv[])
2108 {
2109 	if (!strcmp(argv[1], "on")) {
2110 		atomic_clear_bit(adv_set_opt[selected_adv], SHELL_ADV_OPT_KEEP_RPA);
2111 		shell_print(sh, "RPA will expire on next timeout");
2112 	} else if (!strcmp(argv[1], "off")) {
2113 		atomic_set_bit(adv_set_opt[selected_adv], SHELL_ADV_OPT_KEEP_RPA);
2114 		shell_print(sh, "RPA will not expire on RPA timeout");
2115 	} else {
2116 		shell_error(sh, "Invalid argument: %s", argv[1]);
2117 		return -EINVAL;
2118 	}
2119 
2120 	return 0;
2121 }
2122 #endif
2123 
2124 #if defined(CONFIG_BT_PER_ADV)
cmd_per_adv(const struct shell * sh,size_t argc,char * argv[])2125 static int cmd_per_adv(const struct shell *sh, size_t argc, char *argv[])
2126 {
2127 	struct bt_le_ext_adv *adv = adv_sets[selected_adv];
2128 
2129 	if (!adv) {
2130 		shell_error(sh, "No extended advertisement set selected");
2131 		return -EINVAL;
2132 	}
2133 
2134 	if (!strcmp(argv[1], "off")) {
2135 		if (bt_le_per_adv_stop(adv) < 0) {
2136 			shell_error(sh,
2137 				    "Failed to stop periodic advertising");
2138 		} else {
2139 			shell_print(sh, "Periodic advertising stopped");
2140 		}
2141 	} else if (!strcmp(argv[1], "on")) {
2142 		if (bt_le_per_adv_start(adv) < 0) {
2143 			shell_error(sh,
2144 				    "Failed to start periodic advertising");
2145 		} else {
2146 			shell_print(sh, "Periodic advertising started");
2147 		}
2148 	} else {
2149 		shell_error(sh, "Invalid argument: %s", argv[1]);
2150 		return -EINVAL;
2151 	}
2152 
2153 	return 0;
2154 }
2155 
cmd_per_adv_param(const struct shell * sh,size_t argc,char * argv[])2156 static int cmd_per_adv_param(const struct shell *sh, size_t argc,
2157 			     char *argv[])
2158 {
2159 	struct bt_le_ext_adv *adv = adv_sets[selected_adv];
2160 	struct bt_le_per_adv_param param;
2161 	int err;
2162 
2163 	if (!adv) {
2164 		shell_error(sh, "No extended advertisement set selected");
2165 		return -EINVAL;
2166 	}
2167 
2168 	if (argc > 1) {
2169 		param.interval_min = strtol(argv[1], NULL, 16);
2170 	} else {
2171 		param.interval_min = BT_GAP_ADV_SLOW_INT_MIN;
2172 	}
2173 
2174 	if (argc > 2) {
2175 		param.interval_max = strtol(argv[2], NULL, 16);
2176 	} else {
2177 		param.interval_max = param.interval_min * 1.2;
2178 
2179 	}
2180 
2181 	if (param.interval_min > param.interval_max) {
2182 		shell_error(sh,
2183 			    "Min interval shall be less than max interval");
2184 		return -EINVAL;
2185 	}
2186 
2187 	if (argc > 3 && !strcmp(argv[3], "tx-power")) {
2188 		param.options = BT_LE_ADV_OPT_USE_TX_POWER;
2189 	} else {
2190 		param.options = 0;
2191 	}
2192 
2193 	err = bt_le_per_adv_set_param(adv, &param);
2194 	if (err) {
2195 		shell_error(sh, "Failed to set periodic advertising "
2196 			    "parameters (%d)", err);
2197 		return -ENOEXEC;
2198 	}
2199 
2200 	return 0;
2201 }
2202 
pa_ad_init(struct bt_data * data_array,const size_t data_array_size)2203 static ssize_t pa_ad_init(struct bt_data *data_array,
2204 			  const size_t data_array_size)
2205 {
2206 	size_t ad_len = 0;
2207 
2208 	if (IS_ENABLED(CONFIG_BT_AUDIO)) {
2209 		ssize_t audio_pa_ad_len;
2210 
2211 		audio_pa_ad_len = audio_pa_data_add(&data_array[ad_len],
2212 						    data_array_size - ad_len);
2213 		if (audio_pa_ad_len < 0U) {
2214 			return audio_pa_ad_len;
2215 		}
2216 
2217 		ad_len += audio_pa_ad_len;
2218 	}
2219 
2220 	return ad_len;
2221 }
2222 
cmd_per_adv_data(const struct shell * sh,size_t argc,char * argv[])2223 static int cmd_per_adv_data(const struct shell *sh, size_t argc,
2224 			    char *argv[])
2225 {
2226 	struct bt_le_ext_adv *adv = adv_sets[selected_adv];
2227 	static uint8_t hex_data[256];
2228 	static struct bt_data ad[2U];
2229 	ssize_t stack_ad_len;
2230 	uint8_t ad_len = 0;
2231 	int err;
2232 
2233 	if (!adv) {
2234 		shell_error(sh, "No extended advertisement set selected");
2235 		return -EINVAL;
2236 	}
2237 
2238 	if (argc > 1) {
2239 		size_t hex_len = 0U;
2240 
2241 		(void)memset(hex_data, 0, sizeof(hex_data));
2242 		hex_len = hex2bin(argv[1U], strlen(argv[1U]), hex_data,
2243 				  sizeof(hex_data));
2244 
2245 		if (hex_len == 0U) {
2246 			shell_error(sh, "Could not parse adv data");
2247 
2248 			return -ENOEXEC;
2249 		}
2250 
2251 		ad[ad_len].data_len = hex_data[0U];
2252 		ad[ad_len].type = hex_data[1U];
2253 		ad[ad_len].data = &hex_data[2U];
2254 		ad_len++;
2255 	}
2256 
2257 	stack_ad_len = pa_ad_init(&ad[ad_len], ARRAY_SIZE(ad) - ad_len);
2258 	if (stack_ad_len < 0) {
2259 		shell_error(sh, "Failed to get stack PA data");
2260 
2261 		return -ENOEXEC;
2262 	}
2263 	ad_len += stack_ad_len;
2264 
2265 	err = bt_le_per_adv_set_data(adv, ad, ad_len);
2266 	if (err) {
2267 		shell_error(sh,
2268 			    "Failed to set periodic advertising data (%d)",
2269 			    err);
2270 		return -ENOEXEC;
2271 	}
2272 
2273 	return 0;
2274 }
2275 #endif /* CONFIG_BT_PER_ADV */
2276 #endif /* CONFIG_BT_EXT_ADV */
2277 #endif /* CONFIG_BT_BROADCASTER */
2278 
2279 #if defined(CONFIG_BT_PER_ADV_SYNC)
2280 
cmd_per_adv_sync_create(const struct shell * sh,size_t argc,char * argv[])2281 static int cmd_per_adv_sync_create(const struct shell *sh, size_t argc,
2282 				   char *argv[])
2283 {
2284 	int err;
2285 	struct bt_le_per_adv_sync_param create_params = { 0 };
2286 	uint32_t options = 0;
2287 	struct bt_le_per_adv_sync **free_per_adv_sync = NULL;
2288 	int i = 0;
2289 
2290 	for (i = 0; i < ARRAY_SIZE(per_adv_syncs); i++) {
2291 		if (per_adv_syncs[i] == NULL) {
2292 			free_per_adv_sync = &per_adv_syncs[i];
2293 			break;
2294 		}
2295 	}
2296 
2297 	if (i == ARRAY_SIZE(per_adv_syncs)) {
2298 		shell_error(sh, "Cannot create more per adv syncs");
2299 		return -ENOEXEC;
2300 	}
2301 
2302 	err = bt_addr_le_from_str(argv[1], argv[2], &create_params.addr);
2303 	if (err) {
2304 		shell_error(sh, "Invalid peer address (err %d)", err);
2305 		return -ENOEXEC;
2306 	}
2307 
2308 	/* Default values */
2309 	create_params.timeout = 1000; /* 10 seconds */
2310 	create_params.skip = 10;
2311 
2312 	create_params.sid = strtol(argv[3], NULL, 16);
2313 
2314 	for (int i = 4; i < argc; i++) {
2315 		if (!strcmp(argv[i], "aoa")) {
2316 			options |= BT_LE_PER_ADV_SYNC_OPT_DONT_SYNC_AOA;
2317 		} else if (!strcmp(argv[i], "aod_1us")) {
2318 			options |= BT_LE_PER_ADV_SYNC_OPT_DONT_SYNC_AOD_1US;
2319 		} else if (!strcmp(argv[i], "aod_2us")) {
2320 			options |= BT_LE_PER_ADV_SYNC_OPT_DONT_SYNC_AOD_2US;
2321 		} else if (!strcmp(argv[i], "only_cte")) {
2322 			options |=
2323 				BT_LE_PER_ADV_SYNC_OPT_SYNC_ONLY_CONST_TONE_EXT;
2324 		} else if (!strcmp(argv[i], "timeout")) {
2325 			if (++i == argc) {
2326 				shell_help(sh);
2327 				return SHELL_CMD_HELP_PRINTED;
2328 			}
2329 
2330 			create_params.timeout = strtoul(argv[i], NULL, 16);
2331 		} else if (!strcmp(argv[i], "skip")) {
2332 			if (++i == argc) {
2333 				shell_help(sh);
2334 				return SHELL_CMD_HELP_PRINTED;
2335 			}
2336 
2337 			create_params.skip = strtoul(argv[i], NULL, 16);
2338 		} else {
2339 			shell_help(sh);
2340 			return SHELL_CMD_HELP_PRINTED;
2341 		}
2342 
2343 		/* TODO: add support to parse using the per adv list */
2344 	}
2345 
2346 	create_params.options = options;
2347 
2348 	err = bt_le_per_adv_sync_create(&create_params, free_per_adv_sync);
2349 	if (err) {
2350 		shell_error(sh, "Per adv sync failed (%d)", err);
2351 	} else {
2352 		shell_print(sh, "Per adv sync pending");
2353 	}
2354 
2355 	return 0;
2356 }
2357 
cmd_per_adv_sync_delete(const struct shell * sh,size_t argc,char * argv[])2358 static int cmd_per_adv_sync_delete(const struct shell *sh, size_t argc,
2359 				   char *argv[])
2360 {
2361 	struct bt_le_per_adv_sync *per_adv_sync = NULL;
2362 	int index;
2363 	int err;
2364 
2365 	if (argc > 1) {
2366 		index = strtol(argv[1], NULL, 10);
2367 	} else {
2368 		index = 0;
2369 	}
2370 
2371 	if (index >= ARRAY_SIZE(per_adv_syncs)) {
2372 		shell_error(sh, "Maximum index is %zu but %d was requested",
2373 			    ARRAY_SIZE(per_adv_syncs) - 1, index);
2374 	}
2375 
2376 	per_adv_sync = per_adv_syncs[index];
2377 
2378 	if (!per_adv_sync) {
2379 		return -EINVAL;
2380 	}
2381 
2382 	err = bt_le_per_adv_sync_delete(per_adv_sync);
2383 
2384 	if (err) {
2385 		shell_error(sh, "Per adv sync delete failed (%d)", err);
2386 	} else {
2387 		shell_print(sh, "Per adv sync deleted");
2388 		per_adv_syncs[index] = NULL;
2389 	}
2390 
2391 	return 0;
2392 }
2393 
2394 #if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER)
cmd_past_subscribe(const struct shell * sh,size_t argc,char * argv[])2395 static int cmd_past_subscribe(const struct shell *sh, size_t argc,
2396 			      char *argv[])
2397 {
2398 	struct bt_le_per_adv_sync_transfer_param param;
2399 	int err;
2400 	int i = 0;
2401 	bool global = true;
2402 
2403 	if (i == ARRAY_SIZE(per_adv_syncs)) {
2404 		shell_error(sh, "Cannot create more per adv syncs");
2405 		return -ENOEXEC;
2406 	}
2407 
2408 	/* Default values */
2409 	param.options = 0;
2410 	param.timeout = 1000; /* 10 seconds */
2411 	param.skip = 10;
2412 
2413 	for (int i = 1; i < argc; i++) {
2414 		if (!strcmp(argv[i], "aoa")) {
2415 			param.options |=
2416 				BT_LE_PER_ADV_SYNC_TRANSFER_OPT_SYNC_NO_AOA;
2417 		} else if (!strcmp(argv[i], "aod_1us")) {
2418 			param.options |=
2419 				BT_LE_PER_ADV_SYNC_TRANSFER_OPT_SYNC_NO_AOD_1US;
2420 		} else if (!strcmp(argv[i], "aod_2us")) {
2421 			param.options |=
2422 				BT_LE_PER_ADV_SYNC_TRANSFER_OPT_SYNC_NO_AOD_2US;
2423 		} else if (!strcmp(argv[i], "only_cte")) {
2424 			param.options |=
2425 				BT_LE_PER_ADV_SYNC_TRANSFER_OPT_SYNC_ONLY_CTE;
2426 		} else if (!strcmp(argv[i], "timeout")) {
2427 			if (++i == argc) {
2428 				shell_help(sh);
2429 				return SHELL_CMD_HELP_PRINTED;
2430 			}
2431 
2432 			param.timeout = strtoul(argv[i], NULL, 16);
2433 		} else if (!strcmp(argv[i], "skip")) {
2434 			if (++i == argc) {
2435 				shell_help(sh);
2436 				return SHELL_CMD_HELP_PRINTED;
2437 			}
2438 
2439 			param.skip = strtoul(argv[i], NULL, 16);
2440 		} else if (!strcmp(argv[i], "conn")) {
2441 			if (!default_conn) {
2442 				shell_print(sh, "Not connected");
2443 				return -EINVAL;
2444 			}
2445 			global = false;
2446 		} else {
2447 			shell_help(sh);
2448 			return SHELL_CMD_HELP_PRINTED;
2449 		}
2450 	}
2451 
2452 	bt_le_per_adv_sync_cb_register(&per_adv_sync_cb);
2453 
2454 	err = bt_le_per_adv_sync_transfer_subscribe(
2455 		global ? NULL : default_conn, &param);
2456 
2457 	if (err) {
2458 		shell_error(sh, "PAST subscribe failed (%d)", err);
2459 	} else {
2460 		shell_print(sh, "Subscribed to PAST");
2461 	}
2462 
2463 	return 0;
2464 }
2465 
cmd_past_unsubscribe(const struct shell * sh,size_t argc,char * argv[])2466 static int cmd_past_unsubscribe(const struct shell *sh, size_t argc,
2467 				char *argv[])
2468 {
2469 	int err;
2470 
2471 	if (argc > 1) {
2472 		if (!strcmp(argv[1], "conn")) {
2473 			if (default_conn) {
2474 				err =
2475 					bt_le_per_adv_sync_transfer_unsubscribe(
2476 						default_conn);
2477 			} else {
2478 				shell_print(sh, "Not connected");
2479 				return -EINVAL;
2480 			}
2481 		} else {
2482 			shell_help(sh);
2483 			return SHELL_CMD_HELP_PRINTED;
2484 		}
2485 	} else {
2486 		err = bt_le_per_adv_sync_transfer_unsubscribe(NULL);
2487 	}
2488 
2489 	if (err) {
2490 		shell_error(sh, "PAST unsubscribe failed (%d)", err);
2491 	}
2492 
2493 	return err;
2494 }
2495 #endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER */
2496 
2497 #if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)
cmd_per_adv_sync_transfer(const struct shell * sh,size_t argc,char * argv[])2498 static int cmd_per_adv_sync_transfer(const struct shell *sh, size_t argc,
2499 				     char *argv[])
2500 {
2501 	int err;
2502 	int index;
2503 	struct bt_le_per_adv_sync *per_adv_sync;
2504 
2505 	if (argc > 1) {
2506 		index = strtol(argv[1], NULL, 10);
2507 	} else {
2508 		index = 0;
2509 	}
2510 
2511 	if (index >= ARRAY_SIZE(per_adv_syncs)) {
2512 		shell_error(sh, "Maximum index is %zu but %d was requested",
2513 			    ARRAY_SIZE(per_adv_syncs) - 1, index);
2514 	}
2515 
2516 	per_adv_sync = per_adv_syncs[index];
2517 	if (!per_adv_sync) {
2518 		return -EINVAL;
2519 	}
2520 
2521 	err = bt_le_per_adv_sync_transfer(per_adv_sync, default_conn, 0);
2522 	if (err) {
2523 		shell_error(sh, "Periodic advertising sync transfer failed (%d)", err);
2524 	}
2525 
2526 	return err;
2527 }
2528 #endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER */
2529 #endif /* CONFIG_BT_PER_ADV_SYNC */
2530 
2531 #if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER) && defined(CONFIG_BT_PER_ADV)
cmd_per_adv_set_info_transfer(const struct shell * sh,size_t argc,char * argv[])2532 static int cmd_per_adv_set_info_transfer(const struct shell *sh, size_t argc,
2533 					 char *argv[])
2534 {
2535 	const struct bt_le_ext_adv *adv = adv_sets[selected_adv];
2536 	int err;
2537 
2538 	if (default_conn == NULL) {
2539 		shell_error(sh, "%s: at least, one connection is required",
2540 			    sh->ctx->active_cmd.syntax);
2541 		return -ENOEXEC;
2542 	}
2543 
2544 	err = bt_le_per_adv_set_info_transfer(adv, default_conn, 0U);
2545 	if (err) {
2546 		shell_error(sh, "Periodic advertising sync transfer failed (%d)", err);
2547 	}
2548 
2549 	return err;
2550 }
2551 #endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER && CONFIG_BT_PER_ADV */
2552 
2553 #if defined(CONFIG_BT_CONN)
2554 #if defined(CONFIG_BT_CENTRAL)
cmd_connect_le(const struct shell * sh,size_t argc,char * argv[])2555 static int cmd_connect_le(const struct shell *sh, size_t argc, char *argv[])
2556 {
2557 	int err;
2558 	bt_addr_le_t addr;
2559 	struct bt_conn *conn;
2560 	uint32_t options = 0;
2561 
2562 	/* When no arguments are specified, connect to the last scanned device. */
2563 	if (argc == 1) {
2564 		if (auto_connect.addr_set) {
2565 			bt_addr_le_copy(&addr, &auto_connect.addr);
2566 		} else {
2567 			shell_error(sh, "No connectable adv stored, please trigger a scan first.");
2568 			shell_help(sh);
2569 
2570 			return SHELL_CMD_HELP_PRINTED;
2571 		}
2572 	} else {
2573 		err = bt_addr_le_from_str(argv[1], argv[2], &addr);
2574 		if (err) {
2575 			shell_error(sh, "Invalid peer address (err %d)", err);
2576 			return err;
2577 		}
2578 	}
2579 
2580 #if defined(CONFIG_BT_EXT_ADV)
2581 	for (size_t argn = 3; argn < argc; argn++) {
2582 		const char *arg = argv[argn];
2583 
2584 		if (!strcmp(arg, "coded")) {
2585 			options |= BT_CONN_LE_OPT_CODED;
2586 		} else if (!strcmp(arg, "no-1m")) {
2587 			options |= BT_CONN_LE_OPT_NO_1M;
2588 		} else {
2589 			shell_help(sh);
2590 			return SHELL_CMD_HELP_PRINTED;
2591 		}
2592 	}
2593 #endif /* defined(CONFIG_BT_EXT_ADV) */
2594 
2595 	struct bt_conn_le_create_param *create_params =
2596 		BT_CONN_LE_CREATE_PARAM(options,
2597 					BT_GAP_SCAN_FAST_INTERVAL,
2598 					BT_GAP_SCAN_FAST_INTERVAL);
2599 
2600 	err = bt_conn_le_create(&addr, create_params, BT_LE_CONN_PARAM_DEFAULT,
2601 				&conn);
2602 	if (err) {
2603 		shell_error(sh, "Connection failed (%d)", err);
2604 		return -ENOEXEC;
2605 	} else {
2606 
2607 		shell_print(sh, "Connection pending");
2608 
2609 		/* unref connection obj in advance as app user */
2610 		bt_conn_unref(conn);
2611 	}
2612 
2613 	return 0;
2614 }
2615 
2616 #if !defined(CONFIG_BT_FILTER_ACCEPT_LIST)
cmd_auto_conn(const struct shell * sh,size_t argc,char * argv[])2617 static int cmd_auto_conn(const struct shell *sh, size_t argc, char *argv[])
2618 {
2619 	bt_addr_le_t addr;
2620 	int err;
2621 
2622 	err = bt_addr_le_from_str(argv[1], argv[2], &addr);
2623 	if (err) {
2624 		shell_error(sh, "Invalid peer address (err %d)", err);
2625 		return err;
2626 	}
2627 
2628 	if (argc < 4) {
2629 		return bt_le_set_auto_conn(&addr, BT_LE_CONN_PARAM_DEFAULT);
2630 	} else if (!strcmp(argv[3], "on")) {
2631 		return bt_le_set_auto_conn(&addr, BT_LE_CONN_PARAM_DEFAULT);
2632 	} else if (!strcmp(argv[3], "off")) {
2633 		return bt_le_set_auto_conn(&addr, NULL);
2634 	} else {
2635 		shell_help(sh);
2636 		return SHELL_CMD_HELP_PRINTED;
2637 	}
2638 
2639 	return 0;
2640 }
2641 #endif /* !defined(CONFIG_BT_FILTER_ACCEPT_LIST) */
2642 
cmd_connect_le_name(const struct shell * sh,size_t argc,char * argv[])2643 static int cmd_connect_le_name(const struct shell *sh, size_t argc, char *argv[])
2644 {
2645 	const uint16_t timeout_seconds = 10;
2646 	const struct bt_le_scan_param param = {
2647 		.type       = BT_LE_SCAN_TYPE_ACTIVE,
2648 		.options    = BT_LE_SCAN_OPT_NONE,
2649 		.interval   = BT_GAP_SCAN_FAST_INTERVAL,
2650 		.window     = BT_GAP_SCAN_FAST_WINDOW,
2651 		.timeout    = timeout_seconds * 100, /* 10ms units */
2652 	};
2653 	int err;
2654 
2655 	/* Set the name filter which we will use in the scan callback to
2656 	 * automatically connect to the first device that passes the filter
2657 	 */
2658 	err = cmd_scan_filter_set_name(sh, argc, argv);
2659 	if (err) {
2660 		shell_error(sh,
2661 			    "Bluetooth set scan filter name to %s failed (err %d)",
2662 			    argv[1], err);
2663 		return err;
2664 	}
2665 
2666 	err = bt_le_scan_start(&param, NULL);
2667 	if (err) {
2668 		shell_error(sh, "Bluetooth scan failed (err %d)", err);
2669 		return err;
2670 	}
2671 
2672 	shell_print(sh, "Bluetooth active scan enabled");
2673 
2674 	/* Set boolean to tell the scan callback to connect to this name */
2675 	auto_connect.connect_name = true;
2676 
2677 	return 0;
2678 }
2679 #endif /* CONFIG_BT_CENTRAL */
2680 
cmd_disconnect(const struct shell * sh,size_t argc,char * argv[])2681 static int cmd_disconnect(const struct shell *sh, size_t argc, char *argv[])
2682 {
2683 	struct bt_conn *conn;
2684 	int err;
2685 
2686 	if (default_conn && argc < 3) {
2687 		conn = bt_conn_ref(default_conn);
2688 	} else {
2689 		bt_addr_le_t addr;
2690 
2691 		if (argc < 3) {
2692 			shell_help(sh);
2693 			return SHELL_CMD_HELP_PRINTED;
2694 		}
2695 
2696 		err = bt_addr_le_from_str(argv[1], argv[2], &addr);
2697 		if (err) {
2698 			shell_error(sh, "Invalid peer address (err %d)",
2699 				    err);
2700 			return err;
2701 		}
2702 
2703 		conn = bt_conn_lookup_addr_le(selected_id, &addr);
2704 	}
2705 
2706 	if (!conn) {
2707 		shell_error(sh, "Not connected");
2708 		return -ENOEXEC;
2709 	}
2710 
2711 	err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
2712 	if (err) {
2713 		shell_error(sh, "Disconnection failed (err %d)", err);
2714 		return err;
2715 	}
2716 
2717 	bt_conn_unref(conn);
2718 
2719 	return 0;
2720 }
2721 
cmd_select(const struct shell * sh,size_t argc,char * argv[])2722 static int cmd_select(const struct shell *sh, size_t argc, char *argv[])
2723 {
2724 	char addr_str[BT_ADDR_LE_STR_LEN];
2725 	struct bt_conn *conn;
2726 	bt_addr_le_t addr;
2727 	int err;
2728 
2729 	err = bt_addr_le_from_str(argv[1], argv[2], &addr);
2730 	if (err) {
2731 		shell_error(sh, "Invalid peer address (err %d)", err);
2732 		return err;
2733 	}
2734 
2735 	conn = bt_conn_lookup_addr_le(selected_id, &addr);
2736 	if (!conn) {
2737 		shell_error(sh, "No matching connection found");
2738 		return -ENOEXEC;
2739 	}
2740 
2741 	if (default_conn) {
2742 		bt_conn_unref(default_conn);
2743 	}
2744 
2745 	default_conn = conn;
2746 
2747 	bt_addr_le_to_str(&addr, addr_str, sizeof(addr_str));
2748 	shell_print(sh, "Selected conn is now: %s", addr_str);
2749 
2750 	return 0;
2751 }
2752 
get_conn_type_str(uint8_t type)2753 static const char *get_conn_type_str(uint8_t type)
2754 {
2755 	switch (type) {
2756 	case BT_CONN_TYPE_LE: return "LE";
2757 	case BT_CONN_TYPE_BR: return "BR/EDR";
2758 	case BT_CONN_TYPE_SCO: return "SCO";
2759 	default: return "Invalid";
2760 	}
2761 }
2762 
get_conn_role_str(uint8_t role)2763 static const char *get_conn_role_str(uint8_t role)
2764 {
2765 	switch (role) {
2766 	case BT_CONN_ROLE_CENTRAL: return "central";
2767 	case BT_CONN_ROLE_PERIPHERAL: return "peripheral";
2768 	default: return "Invalid";
2769 	}
2770 }
2771 
cmd_info(const struct shell * sh,size_t argc,char * argv[])2772 static int cmd_info(const struct shell *sh, size_t argc, char *argv[])
2773 {
2774 	struct bt_conn *conn = NULL;
2775 	struct bt_conn_info info;
2776 	bt_addr_le_t addr;
2777 	int err;
2778 
2779 	switch (argc) {
2780 	case 1:
2781 		if (default_conn) {
2782 			conn = bt_conn_ref(default_conn);
2783 		}
2784 		break;
2785 	case 2:
2786 		addr.type = BT_ADDR_LE_PUBLIC;
2787 		err = bt_addr_from_str(argv[1], &addr.a);
2788 		if (err) {
2789 			shell_error(sh, "Invalid peer address (err %d)",
2790 				    err);
2791 			return err;
2792 		}
2793 		conn = bt_conn_lookup_addr_le(selected_id, &addr);
2794 		break;
2795 	case 3:
2796 		err = bt_addr_le_from_str(argv[1], argv[2], &addr);
2797 
2798 		if (err) {
2799 			shell_error(sh, "Invalid peer address (err %d)",
2800 				    err);
2801 			return err;
2802 		}
2803 		conn = bt_conn_lookup_addr_le(selected_id, &addr);
2804 		break;
2805 	}
2806 
2807 	if (!conn) {
2808 		shell_error(sh, "Not connected");
2809 		return -ENOEXEC;
2810 	}
2811 
2812 	err = bt_conn_get_info(conn, &info);
2813 	if (err) {
2814 		shell_print(ctx_shell, "Failed to get info");
2815 		goto done;
2816 	}
2817 
2818 	shell_print(ctx_shell, "Type: %s, Role: %s, Id: %u",
2819 		    get_conn_type_str(info.type),
2820 		    get_conn_role_str(info.role),
2821 		    info.id);
2822 
2823 	if (info.type == BT_CONN_TYPE_LE) {
2824 		print_le_addr("Remote", info.le.dst);
2825 		print_le_addr("Local", info.le.src);
2826 		print_le_addr("Remote on-air", info.le.remote);
2827 		print_le_addr("Local on-air", info.le.local);
2828 
2829 		shell_print(ctx_shell, "Interval: 0x%04x (%u us)",
2830 			    info.le.interval,
2831 			    BT_CONN_INTERVAL_TO_US(info.le.interval));
2832 		shell_print(ctx_shell, "Latency: 0x%04x",
2833 			    info.le.latency);
2834 		shell_print(ctx_shell, "Supervision timeout: 0x%04x (%d ms)",
2835 			    info.le.timeout, info.le.timeout * 10);
2836 #if defined(CONFIG_BT_USER_PHY_UPDATE)
2837 		shell_print(ctx_shell, "LE PHY: TX PHY %s, RX PHY %s",
2838 			    phy2str(info.le.phy->tx_phy),
2839 			    phy2str(info.le.phy->rx_phy));
2840 #endif
2841 #if defined(CONFIG_BT_USER_DATA_LEN_UPDATE)
2842 		shell_print(ctx_shell, "LE data len: TX (len: %d time: %d)"
2843 			    " RX (len: %d time: %d)",
2844 			    info.le.data_len->tx_max_len,
2845 			    info.le.data_len->tx_max_time,
2846 			    info.le.data_len->rx_max_len,
2847 			    info.le.data_len->rx_max_time);
2848 #endif
2849 	}
2850 
2851 #if defined(CONFIG_BT_BREDR)
2852 	if (info.type == BT_CONN_TYPE_BR) {
2853 		char addr_str[BT_ADDR_STR_LEN];
2854 
2855 		bt_addr_to_str(info.br.dst, addr_str, sizeof(addr_str));
2856 		shell_print(ctx_shell, "Peer address %s", addr_str);
2857 	}
2858 #endif /* defined(CONFIG_BT_BREDR) */
2859 
2860 done:
2861 	bt_conn_unref(conn);
2862 
2863 	return err;
2864 }
2865 
cmd_conn_update(const struct shell * sh,size_t argc,char * argv[])2866 static int cmd_conn_update(const struct shell *sh, size_t argc, char *argv[])
2867 {
2868 	struct bt_le_conn_param param;
2869 	int err;
2870 
2871 	if (default_conn == NULL) {
2872 		shell_error(sh,
2873 				"%s: at least, one connection is required",
2874 				sh->ctx->active_cmd.syntax);
2875 		return -ENOEXEC;
2876 	}
2877 
2878 	param.interval_min = strtoul(argv[1], NULL, 16);
2879 	param.interval_max = strtoul(argv[2], NULL, 16);
2880 	param.latency = strtoul(argv[3], NULL, 16);
2881 	param.timeout = strtoul(argv[4], NULL, 16);
2882 
2883 	err = bt_conn_le_param_update(default_conn, &param);
2884 	if (err) {
2885 		shell_error(sh, "conn update failed (err %d).", err);
2886 	} else {
2887 		shell_print(sh, "conn update initiated.");
2888 	}
2889 
2890 	return err;
2891 }
2892 
2893 #if defined(CONFIG_BT_USER_DATA_LEN_UPDATE)
tx_time_calc(uint8_t phy,uint16_t max_len)2894 static uint16_t tx_time_calc(uint8_t phy, uint16_t max_len)
2895 {
2896 	/* Access address + header + payload + MIC + CRC */
2897 	uint16_t total_len = 4 + 2 + max_len + 4 + 3;
2898 
2899 	switch (phy) {
2900 	case BT_GAP_LE_PHY_1M:
2901 		/* 1 byte preamble, 8 us per byte */
2902 		return 8 * (1 + total_len);
2903 	case BT_GAP_LE_PHY_2M:
2904 		/* 2 byte preamble, 4 us per byte */
2905 		return 4 * (2 + total_len);
2906 	case BT_GAP_LE_PHY_CODED:
2907 		/* S8: Preamble + CI + TERM1 + 64 us per byte + TERM2 */
2908 		return 80 + 16 + 24 + 64 * (total_len) + 24;
2909 	default:
2910 		return 0;
2911 	}
2912 }
2913 
cmd_conn_data_len_update(const struct shell * sh,size_t argc,char * argv[])2914 static int cmd_conn_data_len_update(const struct shell *sh, size_t argc,
2915 				    char *argv[])
2916 {
2917 	struct bt_conn_le_data_len_param param;
2918 	int err;
2919 
2920 	if (default_conn == NULL) {
2921 		shell_error(sh,
2922 				"%s: at least, one connection is required",
2923 				sh->ctx->active_cmd.syntax);
2924 		return -ENOEXEC;
2925 	}
2926 
2927 	param.tx_max_len = strtoul(argv[1], NULL, 10);
2928 
2929 	if (argc > 2) {
2930 		param.tx_max_time = strtoul(argv[2], NULL, 10);
2931 	} else {
2932 		/* Assume 1M if not able to retrieve PHY */
2933 		uint8_t phy = BT_GAP_LE_PHY_1M;
2934 
2935 #if defined(CONFIG_BT_USER_PHY_UPDATE)
2936 		struct bt_conn_info info;
2937 
2938 		err = bt_conn_get_info(default_conn, &info);
2939 		if (!err) {
2940 			phy = info.le.phy->tx_phy;
2941 		}
2942 #endif
2943 		param.tx_max_time = tx_time_calc(phy, param.tx_max_len);
2944 		shell_print(sh, "Calculated tx time: %d", param.tx_max_time);
2945 	}
2946 
2947 
2948 
2949 	err = bt_conn_le_data_len_update(default_conn, &param);
2950 	if (err) {
2951 		shell_error(sh, "data len update failed (err %d).", err);
2952 	} else {
2953 		shell_print(sh, "data len update initiated.");
2954 	}
2955 
2956 	return err;
2957 }
2958 #endif
2959 
2960 #if defined(CONFIG_BT_USER_PHY_UPDATE)
cmd_conn_phy_update(const struct shell * sh,size_t argc,char * argv[])2961 static int cmd_conn_phy_update(const struct shell *sh, size_t argc,
2962 			       char *argv[])
2963 {
2964 	struct bt_conn_le_phy_param param;
2965 	int err;
2966 
2967 	if (default_conn == NULL) {
2968 		shell_error(sh,
2969 				"%s: at least, one connection is required",
2970 				sh->ctx->active_cmd.syntax);
2971 		return -ENOEXEC;
2972 	}
2973 
2974 	param.pref_tx_phy = strtoul(argv[1], NULL, 16);
2975 	param.pref_rx_phy = param.pref_tx_phy;
2976 	param.options = BT_CONN_LE_PHY_OPT_NONE;
2977 
2978 	for (size_t argn = 2; argn < argc; argn++) {
2979 		const char *arg = argv[argn];
2980 
2981 		if (!strcmp(arg, "s2")) {
2982 			param.options |= BT_CONN_LE_PHY_OPT_CODED_S2;
2983 		} else if (!strcmp(arg, "s8")) {
2984 			param.options |= BT_CONN_LE_PHY_OPT_CODED_S8;
2985 		} else {
2986 			param.pref_rx_phy = strtoul(arg, NULL, 16);
2987 		}
2988 	}
2989 
2990 	err = bt_conn_le_phy_update(default_conn, &param);
2991 	if (err) {
2992 		shell_error(sh, "PHY update failed (err %d).", err);
2993 	} else {
2994 		shell_print(sh, "PHY update initiated.");
2995 	}
2996 
2997 	return err;
2998 }
2999 #endif
3000 
3001 #if defined(CONFIG_BT_CENTRAL)
cmd_chan_map(const struct shell * sh,size_t argc,char * argv[])3002 static int cmd_chan_map(const struct shell *sh, size_t argc, char *argv[])
3003 {
3004 	uint8_t chan_map[5] = {};
3005 	int err;
3006 
3007 	if (hex2bin(argv[1], strlen(argv[1]), chan_map, 5) == 0) {
3008 		shell_error(sh, "Invalid channel map");
3009 		return -ENOEXEC;
3010 	}
3011 	sys_mem_swap(chan_map, 5);
3012 
3013 	err = bt_le_set_chan_map(chan_map);
3014 	if (err) {
3015 		shell_error(sh, "Failed to set channel map (err %d)", err);
3016 	} else {
3017 		shell_print(sh, "Channel map set");
3018 	}
3019 
3020 	return err;
3021 }
3022 #endif /* CONFIG_BT_CENTRAL */
3023 
cmd_oob(const struct shell * sh,size_t argc,char * argv[])3024 static int cmd_oob(const struct shell *sh, size_t argc, char *argv[])
3025 {
3026 	int err;
3027 
3028 	err = bt_le_oob_get_local(selected_id, &oob_local);
3029 	if (err) {
3030 		shell_error(sh, "OOB data failed");
3031 		return err;
3032 	}
3033 
3034 	print_le_oob(sh, &oob_local);
3035 
3036 	return 0;
3037 }
3038 
3039 #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
cmd_oob_remote(const struct shell * sh,size_t argc,char * argv[])3040 static int cmd_oob_remote(const struct shell *sh, size_t argc,
3041 			     char *argv[])
3042 {
3043 	int err;
3044 	bt_addr_le_t addr;
3045 
3046 	err = bt_addr_le_from_str(argv[1], argv[2], &addr);
3047 	if (err) {
3048 		shell_error(sh, "Invalid peer address (err %d)", err);
3049 		return err;
3050 	}
3051 
3052 	bt_addr_le_copy(&oob_remote.addr, &addr);
3053 
3054 	if (argc == 5) {
3055 		hex2bin(argv[3], strlen(argv[3]), oob_remote.le_sc_data.r,
3056 			sizeof(oob_remote.le_sc_data.r));
3057 		hex2bin(argv[4], strlen(argv[4]), oob_remote.le_sc_data.c,
3058 			sizeof(oob_remote.le_sc_data.c));
3059 		bt_le_oob_set_sc_flag(true);
3060 	} else {
3061 		shell_help(sh);
3062 		return -ENOEXEC;
3063 	}
3064 
3065 	return 0;
3066 }
3067 
cmd_oob_clear(const struct shell * sh,size_t argc,char * argv[])3068 static int cmd_oob_clear(const struct shell *sh, size_t argc, char *argv[])
3069 {
3070 	memset(&oob_remote, 0, sizeof(oob_remote));
3071 	bt_le_oob_set_sc_flag(false);
3072 
3073 	return 0;
3074 }
3075 #endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR) */
3076 
cmd_clear(const struct shell * sh,size_t argc,char * argv[])3077 static int cmd_clear(const struct shell *sh, size_t argc, char *argv[])
3078 {
3079 	bt_addr_le_t addr;
3080 	int err;
3081 
3082 	if (strcmp(argv[1], "all") == 0) {
3083 		err = bt_unpair(selected_id, NULL);
3084 		if (err) {
3085 			shell_error(sh, "Failed to clear pairings (err %d)",
3086 			      err);
3087 			return err;
3088 		} else {
3089 			shell_print(sh, "Pairings successfully cleared");
3090 		}
3091 
3092 		return 0;
3093 	}
3094 
3095 	if (argc < 3) {
3096 #if defined(CONFIG_BT_BREDR)
3097 		addr.type = BT_ADDR_LE_PUBLIC;
3098 		err = bt_addr_from_str(argv[1], &addr.a);
3099 #else
3100 		shell_print(sh, "Both address and address type needed");
3101 		return -ENOEXEC;
3102 #endif
3103 	} else {
3104 		err = bt_addr_le_from_str(argv[1], argv[2], &addr);
3105 	}
3106 
3107 	if (err) {
3108 		shell_print(sh, "Invalid address");
3109 		return err;
3110 	}
3111 
3112 	err = bt_unpair(selected_id, &addr);
3113 	if (err) {
3114 		shell_error(sh, "Failed to clear pairing (err %d)", err);
3115 	} else {
3116 		shell_print(sh, "Pairing successfully cleared");
3117 	}
3118 
3119 	return err;
3120 }
3121 #endif /* CONFIG_BT_CONN */
3122 
3123 #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
cmd_security(const struct shell * sh,size_t argc,char * argv[])3124 static int cmd_security(const struct shell *sh, size_t argc, char *argv[])
3125 {
3126 	int err, sec;
3127 	struct bt_conn_info info;
3128 
3129 	if (!default_conn || (bt_conn_get_info(default_conn, &info) < 0)) {
3130 		shell_error(sh, "Not connected");
3131 		return -ENOEXEC;
3132 	}
3133 
3134 	if (argc < 2) {
3135 		shell_print(sh, "BT_SECURITY_L%d", bt_conn_get_security(default_conn));
3136 
3137 		return 0;
3138 	}
3139 
3140 	sec = *argv[1] - '0';
3141 
3142 	if ((info.type == BT_CONN_TYPE_BR &&
3143 	    (sec < BT_SECURITY_L0 || sec > BT_SECURITY_L3))) {
3144 		shell_error(sh, "Invalid BR/EDR security level (%d)", sec);
3145 		return -ENOEXEC;
3146 	}
3147 
3148 	if ((info.type == BT_CONN_TYPE_LE &&
3149 	    (sec < BT_SECURITY_L1 || sec > BT_SECURITY_L4))) {
3150 		shell_error(sh, "Invalid LE security level (%d)", sec);
3151 		return -ENOEXEC;
3152 	}
3153 
3154 	if (argc > 2) {
3155 		if (!strcmp(argv[2], "force-pair")) {
3156 			sec |= BT_SECURITY_FORCE_PAIR;
3157 		} else {
3158 			shell_help(sh);
3159 			return -ENOEXEC;
3160 		}
3161 	}
3162 
3163 	err = bt_conn_set_security(default_conn, sec);
3164 	if (err) {
3165 		shell_error(sh, "Setting security failed (err %d)", err);
3166 	}
3167 
3168 	return err;
3169 }
3170 
cmd_bondable(const struct shell * sh,size_t argc,char * argv[])3171 static int cmd_bondable(const struct shell *sh, size_t argc, char *argv[])
3172 {
3173 	const char *bondable;
3174 
3175 	bondable = argv[1];
3176 	if (!strcmp(bondable, "on")) {
3177 		bt_set_bondable(true);
3178 	} else if (!strcmp(bondable, "off")) {
3179 		bt_set_bondable(false);
3180 	} else {
3181 		shell_help(sh);
3182 		return SHELL_CMD_HELP_PRINTED;
3183 	}
3184 
3185 	return 0;
3186 }
3187 
bond_info(const struct bt_bond_info * info,void * user_data)3188 static void bond_info(const struct bt_bond_info *info, void *user_data)
3189 {
3190 	char addr[BT_ADDR_LE_STR_LEN];
3191 	int *bond_count = user_data;
3192 
3193 	bt_addr_le_to_str(&info->addr, addr, sizeof(addr));
3194 	shell_print(ctx_shell, "Remote Identity: %s", addr);
3195 	(*bond_count)++;
3196 }
3197 
cmd_bonds(const struct shell * sh,size_t argc,char * argv[])3198 static int cmd_bonds(const struct shell *sh, size_t argc, char *argv[])
3199 {
3200 	int bond_count = 0;
3201 
3202 	shell_print(sh, "Bonded devices:");
3203 	bt_foreach_bond(selected_id, bond_info, &bond_count);
3204 	shell_print(sh, "Total %d", bond_count);
3205 
3206 	return 0;
3207 }
3208 
role_str(uint8_t role)3209 static const char *role_str(uint8_t role)
3210 {
3211 	switch (role) {
3212 	case BT_CONN_ROLE_CENTRAL:
3213 		return "Central";
3214 	case BT_CONN_ROLE_PERIPHERAL:
3215 		return "Peripheral";
3216 	}
3217 
3218 	return "Unknown";
3219 }
3220 
connection_info(struct bt_conn * conn,void * user_data)3221 static void connection_info(struct bt_conn *conn, void *user_data)
3222 {
3223 	char addr[BT_ADDR_LE_STR_LEN];
3224 	int *conn_count = user_data;
3225 	struct bt_conn_info info;
3226 
3227 	if (bt_conn_get_info(conn, &info) < 0) {
3228 		shell_error(ctx_shell, "Unable to get info: conn %p", conn);
3229 		return;
3230 	}
3231 
3232 	switch (info.type) {
3233 #if defined(CONFIG_BT_BREDR)
3234 	case BT_CONN_TYPE_BR:
3235 		bt_addr_to_str(info.br.dst, addr, sizeof(addr));
3236 		shell_print(ctx_shell, " #%u [BR][%s] %s", info.id, role_str(info.role), addr);
3237 		break;
3238 #endif
3239 	case BT_CONN_TYPE_LE:
3240 		bt_addr_le_to_str(info.le.dst, addr, sizeof(addr));
3241 		shell_print(ctx_shell, "%s#%u [LE][%s] %s: Interval %u latency %u timeout %u",
3242 			    conn == default_conn ? "*" : " ", info.id, role_str(info.role), addr,
3243 			    info.le.interval, info.le.latency, info.le.timeout);
3244 		break;
3245 #if defined(CONFIG_BT_ISO)
3246 	case BT_CONN_TYPE_ISO:
3247 		bt_addr_le_to_str(info.le.dst, addr, sizeof(addr));
3248 		shell_print(ctx_shell, " #%u [ISO][%s] %s", info.id, role_str(info.role), addr);
3249 		break;
3250 #endif
3251 	}
3252 
3253 	(*conn_count)++;
3254 }
3255 
cmd_connections(const struct shell * sh,size_t argc,char * argv[])3256 static int cmd_connections(const struct shell *sh, size_t argc, char *argv[])
3257 {
3258 	int conn_count = 0;
3259 
3260 	shell_print(sh, "Connected devices:");
3261 	bt_conn_foreach(BT_CONN_TYPE_ALL, connection_info, &conn_count);
3262 	shell_print(sh, "Total %d", conn_count);
3263 
3264 	return 0;
3265 }
3266 
auth_passkey_display(struct bt_conn * conn,unsigned int passkey)3267 static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey)
3268 {
3269 	char addr[BT_ADDR_LE_STR_LEN];
3270 	char passkey_str[7];
3271 
3272 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
3273 
3274 	snprintk(passkey_str, 7, "%06u", passkey);
3275 
3276 	shell_print(ctx_shell, "Passkey for %s: %s", addr, passkey_str);
3277 }
3278 
3279 #if defined(CONFIG_BT_PASSKEY_KEYPRESS)
auth_passkey_display_keypress(struct bt_conn * conn,enum bt_conn_auth_keypress type)3280 static void auth_passkey_display_keypress(struct bt_conn *conn,
3281 					  enum bt_conn_auth_keypress type)
3282 {
3283 	char addr[BT_ADDR_LE_STR_LEN];
3284 
3285 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
3286 
3287 	shell_print(ctx_shell, "Passkey keypress notification from %s: type %d",
3288 		    addr, type);
3289 }
3290 #endif
3291 
auth_passkey_confirm(struct bt_conn * conn,unsigned int passkey)3292 static void auth_passkey_confirm(struct bt_conn *conn, unsigned int passkey)
3293 {
3294 	char addr[BT_ADDR_LE_STR_LEN];
3295 	char passkey_str[7];
3296 
3297 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
3298 
3299 	snprintk(passkey_str, 7, "%06u", passkey);
3300 
3301 	shell_print(ctx_shell, "Confirm passkey for %s: %s", addr, passkey_str);
3302 }
3303 
auth_passkey_entry(struct bt_conn * conn)3304 static void auth_passkey_entry(struct bt_conn *conn)
3305 {
3306 	char addr[BT_ADDR_LE_STR_LEN];
3307 
3308 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
3309 
3310 	shell_print(ctx_shell, "Enter passkey for %s", addr);
3311 }
3312 
auth_cancel(struct bt_conn * conn)3313 static void auth_cancel(struct bt_conn *conn)
3314 {
3315 	char addr[BT_ADDR_LE_STR_LEN];
3316 
3317 	conn_addr_str(conn, addr, sizeof(addr));
3318 
3319 	shell_print(ctx_shell, "Pairing cancelled: %s", addr);
3320 
3321 	/* clear connection reference for sec mode 3 pairing */
3322 	if (pairing_conn) {
3323 		bt_conn_unref(pairing_conn);
3324 		pairing_conn = NULL;
3325 	}
3326 }
3327 
auth_pairing_confirm(struct bt_conn * conn)3328 static void auth_pairing_confirm(struct bt_conn *conn)
3329 {
3330 	char addr[BT_ADDR_LE_STR_LEN];
3331 
3332 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
3333 
3334 	shell_print(ctx_shell, "Confirm pairing for %s", addr);
3335 }
3336 
3337 #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
oob_config_str(int oob_config)3338 static const char *oob_config_str(int oob_config)
3339 {
3340 	switch (oob_config) {
3341 	case BT_CONN_OOB_LOCAL_ONLY:
3342 		return "Local";
3343 	case BT_CONN_OOB_REMOTE_ONLY:
3344 		return "Remote";
3345 	case BT_CONN_OOB_BOTH_PEERS:
3346 		return "Local and Remote";
3347 	case BT_CONN_OOB_NO_DATA:
3348 	default:
3349 		return "no";
3350 	}
3351 }
3352 #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
3353 
auth_pairing_oob_data_request(struct bt_conn * conn,struct bt_conn_oob_info * oob_info)3354 static void auth_pairing_oob_data_request(struct bt_conn *conn,
3355 					  struct bt_conn_oob_info *oob_info)
3356 {
3357 	char addr[BT_ADDR_LE_STR_LEN];
3358 	struct bt_conn_info info;
3359 	int err;
3360 
3361 	err = bt_conn_get_info(conn, &info);
3362 	if (err) {
3363 		return;
3364 	}
3365 
3366 #if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
3367 	if (oob_info->type == BT_CONN_OOB_LE_SC) {
3368 		struct bt_le_oob_sc_data *oobd_local =
3369 			oob_info->lesc.oob_config != BT_CONN_OOB_REMOTE_ONLY
3370 						  ? &oob_local.le_sc_data
3371 						  : NULL;
3372 		struct bt_le_oob_sc_data *oobd_remote =
3373 			oob_info->lesc.oob_config != BT_CONN_OOB_LOCAL_ONLY
3374 						  ? &oob_remote.le_sc_data
3375 						  : NULL;
3376 
3377 		if (oobd_remote &&
3378 		    !bt_addr_le_eq(info.le.remote, &oob_remote.addr)) {
3379 			bt_addr_le_to_str(info.le.remote, addr, sizeof(addr));
3380 			shell_print(ctx_shell,
3381 				    "No OOB data available for remote %s",
3382 				    addr);
3383 			bt_conn_auth_cancel(conn);
3384 			return;
3385 		}
3386 
3387 		if (oobd_local &&
3388 		    !bt_addr_le_eq(info.le.local, &oob_local.addr)) {
3389 			bt_addr_le_to_str(info.le.local, addr, sizeof(addr));
3390 			shell_print(ctx_shell,
3391 				    "No OOB data available for local %s",
3392 				    addr);
3393 			bt_conn_auth_cancel(conn);
3394 			return;
3395 		}
3396 
3397 		bt_le_oob_set_sc_data(conn, oobd_local, oobd_remote);
3398 
3399 		bt_addr_le_to_str(info.le.dst, addr, sizeof(addr));
3400 		shell_print(ctx_shell, "Set %s OOB SC data for %s, ",
3401 			    oob_config_str(oob_info->lesc.oob_config), addr);
3402 		return;
3403 	}
3404 #endif /* CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY */
3405 
3406 	bt_addr_le_to_str(info.le.dst, addr, sizeof(addr));
3407 	shell_print(ctx_shell, "Legacy OOB TK requested from remote %s", addr);
3408 }
3409 
auth_pairing_complete(struct bt_conn * conn,bool bonded)3410 static void auth_pairing_complete(struct bt_conn *conn, bool bonded)
3411 {
3412 	char addr[BT_ADDR_LE_STR_LEN];
3413 
3414 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
3415 
3416 	shell_print(ctx_shell, "%s with %s", bonded ? "Bonded" : "Paired",
3417 		    addr);
3418 }
3419 
auth_pairing_failed(struct bt_conn * conn,enum bt_security_err err)3420 static void auth_pairing_failed(struct bt_conn *conn, enum bt_security_err err)
3421 {
3422 	char addr[BT_ADDR_LE_STR_LEN];
3423 
3424 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
3425 
3426 	shell_print(ctx_shell, "Pairing failed with %s reason: %s (%d)", addr,
3427 		    security_err_str(err), err);
3428 }
3429 
3430 #if defined(CONFIG_BT_BREDR)
auth_pincode_entry(struct bt_conn * conn,bool highsec)3431 static void auth_pincode_entry(struct bt_conn *conn, bool highsec)
3432 {
3433 	char addr[BT_ADDR_STR_LEN];
3434 	struct bt_conn_info info;
3435 
3436 	if (bt_conn_get_info(conn, &info) < 0) {
3437 		return;
3438 	}
3439 
3440 	if (info.type != BT_CONN_TYPE_BR) {
3441 		return;
3442 	}
3443 
3444 	bt_addr_to_str(info.br.dst, addr, sizeof(addr));
3445 
3446 	if (highsec) {
3447 		shell_print(ctx_shell, "Enter 16 digits wide PIN code for %s",
3448 			    addr);
3449 	} else {
3450 		shell_print(ctx_shell, "Enter PIN code for %s", addr);
3451 	}
3452 
3453 	/*
3454 	 * Save connection info since in security mode 3 (link level enforced
3455 	 * security) PIN request callback is called before connected callback
3456 	 */
3457 	if (!default_conn && !pairing_conn) {
3458 		pairing_conn = bt_conn_ref(conn);
3459 	}
3460 }
3461 #endif
3462 
3463 #if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
pairing_accept(struct bt_conn * conn,const struct bt_conn_pairing_feat * const feat)3464 enum bt_security_err pairing_accept(
3465 	struct bt_conn *conn, const struct bt_conn_pairing_feat *const feat)
3466 {
3467 	shell_print(ctx_shell, "Remote pairing features: "
3468 			       "IO: 0x%02x, OOB: %d, AUTH: 0x%02x, Key: %d, "
3469 			       "Init Kdist: 0x%02x, Resp Kdist: 0x%02x",
3470 			       feat->io_capability, feat->oob_data_flag,
3471 			       feat->auth_req, feat->max_enc_key_size,
3472 			       feat->init_key_dist, feat->resp_key_dist);
3473 
3474 	return BT_SECURITY_ERR_SUCCESS;
3475 }
3476 #endif /* CONFIG_BT_SMP_APP_PAIRING_ACCEPT */
3477 
bond_deleted(uint8_t id,const bt_addr_le_t * peer)3478 void bond_deleted(uint8_t id, const bt_addr_le_t *peer)
3479 {
3480 	char addr[BT_ADDR_LE_STR_LEN];
3481 
3482 	bt_addr_le_to_str(peer, addr, sizeof(addr));
3483 	shell_print(ctx_shell, "Bond deleted for %s, id %u", addr, id);
3484 }
3485 
3486 static struct bt_conn_auth_cb auth_cb_display = {
3487 	.passkey_display = auth_passkey_display,
3488 #if defined(CONFIG_BT_PASSKEY_KEYPRESS)
3489 	.passkey_display_keypress = auth_passkey_display_keypress,
3490 #endif
3491 	.passkey_entry = NULL,
3492 	.passkey_confirm = NULL,
3493 #if defined(CONFIG_BT_BREDR)
3494 	.pincode_entry = auth_pincode_entry,
3495 #endif
3496 	.oob_data_request = NULL,
3497 	.cancel = auth_cancel,
3498 	.pairing_confirm = auth_pairing_confirm,
3499 #if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
3500 	.pairing_accept = pairing_accept,
3501 #endif
3502 };
3503 
3504 static struct bt_conn_auth_cb auth_cb_display_yes_no = {
3505 	.passkey_display = auth_passkey_display,
3506 	.passkey_entry = NULL,
3507 	.passkey_confirm = auth_passkey_confirm,
3508 #if defined(CONFIG_BT_BREDR)
3509 	.pincode_entry = auth_pincode_entry,
3510 #endif
3511 	.oob_data_request = NULL,
3512 	.cancel = auth_cancel,
3513 	.pairing_confirm = auth_pairing_confirm,
3514 #if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
3515 	.pairing_accept = pairing_accept,
3516 #endif
3517 };
3518 
3519 static struct bt_conn_auth_cb auth_cb_input = {
3520 	.passkey_display = NULL,
3521 	.passkey_entry = auth_passkey_entry,
3522 	.passkey_confirm = NULL,
3523 #if defined(CONFIG_BT_BREDR)
3524 	.pincode_entry = auth_pincode_entry,
3525 #endif
3526 	.oob_data_request = NULL,
3527 	.cancel = auth_cancel,
3528 	.pairing_confirm = auth_pairing_confirm,
3529 #if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
3530 	.pairing_accept = pairing_accept,
3531 #endif
3532 };
3533 
3534 static struct bt_conn_auth_cb auth_cb_confirm = {
3535 #if defined(CONFIG_BT_BREDR)
3536 	.pincode_entry = auth_pincode_entry,
3537 #endif
3538 	.oob_data_request = NULL,
3539 	.cancel = auth_cancel,
3540 	.pairing_confirm = auth_pairing_confirm,
3541 #if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
3542 	.pairing_accept = pairing_accept,
3543 #endif
3544 };
3545 
3546 static struct bt_conn_auth_cb auth_cb_all = {
3547 	.passkey_display = auth_passkey_display,
3548 	.passkey_entry = auth_passkey_entry,
3549 	.passkey_confirm = auth_passkey_confirm,
3550 #if defined(CONFIG_BT_BREDR)
3551 	.pincode_entry = auth_pincode_entry,
3552 #endif
3553 	.oob_data_request = auth_pairing_oob_data_request,
3554 	.cancel = auth_cancel,
3555 	.pairing_confirm = auth_pairing_confirm,
3556 #if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
3557 	.pairing_accept = pairing_accept,
3558 #endif
3559 };
3560 
3561 static struct bt_conn_auth_cb auth_cb_oob = {
3562 	.passkey_display = NULL,
3563 	.passkey_entry = NULL,
3564 	.passkey_confirm = NULL,
3565 #if defined(CONFIG_BT_BREDR)
3566 	.pincode_entry = NULL,
3567 #endif
3568 	.oob_data_request = auth_pairing_oob_data_request,
3569 	.cancel = auth_cancel,
3570 	.pairing_confirm = NULL,
3571 #if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
3572 	.pairing_accept = pairing_accept,
3573 #endif
3574 };
3575 
3576 static struct bt_conn_auth_cb auth_cb_status = {
3577 #if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
3578 	.pairing_accept = pairing_accept,
3579 #endif
3580 };
3581 
3582 static struct bt_conn_auth_info_cb auth_info_cb = {
3583 	.pairing_failed = auth_pairing_failed,
3584 	.pairing_complete = auth_pairing_complete,
3585 	.bond_deleted = bond_deleted,
3586 };
3587 
cmd_auth(const struct shell * sh,size_t argc,char * argv[])3588 static int cmd_auth(const struct shell *sh, size_t argc, char *argv[])
3589 {
3590 	int err;
3591 
3592 	if (!strcmp(argv[1], "all")) {
3593 		err = bt_conn_auth_cb_register(&auth_cb_all);
3594 	} else if (!strcmp(argv[1], "input")) {
3595 		err = bt_conn_auth_cb_register(&auth_cb_input);
3596 	} else if (!strcmp(argv[1], "display")) {
3597 		err = bt_conn_auth_cb_register(&auth_cb_display);
3598 	} else if (!strcmp(argv[1], "yesno")) {
3599 		err = bt_conn_auth_cb_register(&auth_cb_display_yes_no);
3600 	} else if (!strcmp(argv[1], "confirm")) {
3601 		err = bt_conn_auth_cb_register(&auth_cb_confirm);
3602 	} else if (!strcmp(argv[1], "oob")) {
3603 		err = bt_conn_auth_cb_register(&auth_cb_oob);
3604 	} else if (!strcmp(argv[1], "status")) {
3605 		err = bt_conn_auth_cb_register(&auth_cb_status);
3606 	} else if (!strcmp(argv[1], "none")) {
3607 		err = bt_conn_auth_cb_register(NULL);
3608 	} else {
3609 		shell_help(sh);
3610 		return SHELL_CMD_HELP_PRINTED;
3611 	}
3612 
3613 	if (err) {
3614 		shell_error(sh, "Failed to set auth handlers (%d)", err);
3615 	}
3616 
3617 	return err;
3618 }
3619 
cmd_auth_cancel(const struct shell * sh,size_t argc,char * argv[])3620 static int cmd_auth_cancel(const struct shell *sh,
3621 			   size_t argc, char *argv[])
3622 {
3623 	struct bt_conn *conn;
3624 
3625 	if (default_conn) {
3626 		conn = default_conn;
3627 	} else if (pairing_conn) {
3628 		conn = pairing_conn;
3629 	} else {
3630 		conn = NULL;
3631 	}
3632 
3633 	if (!conn) {
3634 		shell_print(sh, "Not connected");
3635 		return -ENOEXEC;
3636 	}
3637 
3638 	bt_conn_auth_cancel(conn);
3639 
3640 	return 0;
3641 }
3642 
cmd_auth_passkey_confirm(const struct shell * sh,size_t argc,char * argv[])3643 static int cmd_auth_passkey_confirm(const struct shell *sh,
3644 				    size_t argc, char *argv[])
3645 {
3646 	if (!default_conn) {
3647 		shell_print(sh, "Not connected");
3648 		return -ENOEXEC;
3649 	}
3650 
3651 	bt_conn_auth_passkey_confirm(default_conn);
3652 	return 0;
3653 }
3654 
cmd_auth_pairing_confirm(const struct shell * sh,size_t argc,char * argv[])3655 static int cmd_auth_pairing_confirm(const struct shell *sh,
3656 				    size_t argc, char *argv[])
3657 {
3658 	if (!default_conn) {
3659 		shell_print(sh, "Not connected");
3660 		return -ENOEXEC;
3661 	}
3662 
3663 	bt_conn_auth_pairing_confirm(default_conn);
3664 	return 0;
3665 }
3666 
3667 #if defined(CONFIG_BT_FILTER_ACCEPT_LIST)
cmd_fal_add(const struct shell * sh,size_t argc,char * argv[])3668 static int cmd_fal_add(const struct shell *sh, size_t argc, char *argv[])
3669 {
3670 	bt_addr_le_t addr;
3671 	int err;
3672 
3673 	err = bt_addr_le_from_str(argv[1], argv[2], &addr);
3674 	if (err) {
3675 		shell_error(sh, "Invalid peer address (err %d)", err);
3676 		return err;
3677 	}
3678 
3679 	err = bt_le_filter_accept_list_add(&addr);
3680 	if (err) {
3681 		shell_error(sh, "Add to fa list failed (err %d)", err);
3682 		return err;
3683 	}
3684 
3685 	return 0;
3686 }
3687 
cmd_fal_rem(const struct shell * sh,size_t argc,char * argv[])3688 static int cmd_fal_rem(const struct shell *sh, size_t argc, char *argv[])
3689 {
3690 	bt_addr_le_t addr;
3691 	int err;
3692 
3693 	err = bt_addr_le_from_str(argv[1], argv[2], &addr);
3694 	if (err) {
3695 		shell_error(sh, "Invalid peer address (err %d)", err);
3696 		return err;
3697 	}
3698 
3699 	err = bt_le_filter_accept_list_remove(&addr);
3700 	if (err) {
3701 		shell_error(sh, "Remove from fa list failed (err %d)",
3702 			    err);
3703 		return err;
3704 	}
3705 	return 0;
3706 }
3707 
cmd_fal_clear(const struct shell * sh,size_t argc,char * argv[])3708 static int cmd_fal_clear(const struct shell *sh, size_t argc, char *argv[])
3709 {
3710 	int err;
3711 
3712 	err = bt_le_filter_accept_list_clear();
3713 	if (err) {
3714 		shell_error(sh, "Clearing fa list failed (err %d)", err);
3715 		return err;
3716 	}
3717 
3718 	return 0;
3719 }
3720 
3721 #if defined(CONFIG_BT_CENTRAL)
cmd_fal_connect(const struct shell * sh,size_t argc,char * argv[])3722 static int cmd_fal_connect(const struct shell *sh, size_t argc, char *argv[])
3723 {
3724 	int err;
3725 	const char *action = argv[1];
3726 	uint32_t options = 0;
3727 
3728 #if defined(CONFIG_BT_EXT_ADV)
3729 	for (size_t argn = 2; argn < argc; argn++) {
3730 		const char *arg = argv[argn];
3731 
3732 		if (!strcmp(arg, "coded")) {
3733 			options |= BT_CONN_LE_OPT_CODED;
3734 		} else if (!strcmp(arg, "no-1m")) {
3735 			options |= BT_CONN_LE_OPT_NO_1M;
3736 		} else {
3737 			shell_help(sh);
3738 			return SHELL_CMD_HELP_PRINTED;
3739 		}
3740 	}
3741 #endif /* defined(CONFIG_BT_EXT_ADV) */
3742 	struct bt_conn_le_create_param *create_params =
3743 		BT_CONN_LE_CREATE_PARAM(options,
3744 					BT_GAP_SCAN_FAST_INTERVAL,
3745 					BT_GAP_SCAN_FAST_WINDOW);
3746 
3747 	if (!strcmp(action, "on")) {
3748 		err = bt_conn_le_create_auto(create_params,
3749 					     BT_LE_CONN_PARAM_DEFAULT);
3750 		if (err) {
3751 			shell_error(sh, "Auto connect failed (err %d)", err);
3752 			return err;
3753 		}
3754 	} else if (!strcmp(action, "off")) {
3755 		err = bt_conn_create_auto_stop();
3756 		if (err) {
3757 			shell_error(sh, "Auto connect stop failed (err %d)",
3758 				    err);
3759 		}
3760 		return err;
3761 	}
3762 
3763 	return 0;
3764 }
3765 #endif /* CONFIG_BT_CENTRAL */
3766 #endif /* defined(CONFIG_BT_FILTER_ACCEPT_LIST) */
3767 
3768 #if defined(CONFIG_BT_FIXED_PASSKEY)
cmd_fixed_passkey(const struct shell * sh,size_t argc,char * argv[])3769 static int cmd_fixed_passkey(const struct shell *sh,
3770 			     size_t argc, char *argv[])
3771 {
3772 	unsigned int passkey;
3773 	int err;
3774 
3775 	if (argc < 2) {
3776 		bt_passkey_set(BT_PASSKEY_INVALID);
3777 		shell_print(sh, "Fixed passkey cleared");
3778 		return 0;
3779 	}
3780 
3781 	passkey = atoi(argv[1]);
3782 	if (passkey > 999999) {
3783 		shell_print(sh, "Passkey should be between 0-999999");
3784 		return -ENOEXEC;
3785 	}
3786 
3787 	err = bt_passkey_set(passkey);
3788 	if (err) {
3789 		shell_print(sh, "Setting fixed passkey failed (err %d)",
3790 			    err);
3791 	}
3792 
3793 	return err;
3794 }
3795 #endif
3796 
cmd_auth_passkey(const struct shell * sh,size_t argc,char * argv[])3797 static int cmd_auth_passkey(const struct shell *sh,
3798 			    size_t argc, char *argv[])
3799 {
3800 	unsigned int passkey;
3801 	int err;
3802 
3803 	if (!default_conn) {
3804 		shell_print(sh, "Not connected");
3805 		return -ENOEXEC;
3806 	}
3807 
3808 	passkey = atoi(argv[1]);
3809 	if (passkey > 999999) {
3810 		shell_print(sh, "Passkey should be between 0-999999");
3811 		return -EINVAL;
3812 	}
3813 
3814 	err = bt_conn_auth_passkey_entry(default_conn, passkey);
3815 	if (err) {
3816 		shell_error(sh, "Failed to set passkey (%d)", err);
3817 		return err;
3818 	}
3819 
3820 	return 0;
3821 }
3822 
3823 #if defined(CONFIG_BT_PASSKEY_KEYPRESS)
cmd_auth_passkey_notify(const struct shell * sh,size_t argc,char * argv[])3824 static int cmd_auth_passkey_notify(const struct shell *sh,
3825 				   size_t argc, char *argv[])
3826 {
3827 	unsigned long type;
3828 	int err;
3829 
3830 	if (!default_conn) {
3831 		shell_print(sh, "Not connected");
3832 		return -ENOEXEC;
3833 	}
3834 
3835 	err = 0;
3836 	type = shell_strtoul(argv[1], 0, &err);
3837 	if (err || !IN_RANGE(type, BT_CONN_AUTH_KEYPRESS_ENTRY_STARTED,
3838 			     BT_CONN_AUTH_KEYPRESS_ENTRY_COMPLETED)) {
3839 		shell_error(sh, "<type> must be a value in range of enum bt_conn_auth_keypress");
3840 		return -EINVAL;
3841 	}
3842 
3843 	err = bt_conn_auth_keypress_notify(default_conn, type);
3844 	if (err) {
3845 		shell_error(sh, "bt_conn_auth_keypress_notify errno %d", err);
3846 		return err;
3847 	}
3848 
3849 	return 0;
3850 }
3851 #endif /* CONFIG_BT_PASSKEY_KEYPRESS */
3852 
3853 #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
cmd_auth_oob_tk(const struct shell * sh,size_t argc,char * argv[])3854 static int cmd_auth_oob_tk(const struct shell *sh, size_t argc, char *argv[])
3855 {
3856 	uint8_t tk[16];
3857 	size_t len;
3858 	int err;
3859 
3860 	len = hex2bin(argv[1], strlen(argv[1]), tk, sizeof(tk));
3861 	if (len != sizeof(tk)) {
3862 		shell_error(sh, "TK should be 16 bytes");
3863 		return -EINVAL;
3864 	}
3865 
3866 	err = bt_le_oob_set_legacy_tk(default_conn, tk);
3867 	if (err) {
3868 		shell_error(sh, "Failed to set TK (%d)", err);
3869 		return err;
3870 	}
3871 
3872 	return 0;
3873 }
3874 #endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */
3875 #endif /* CONFIG_BT_SMP) || CONFIG_BT_BREDR */
3876 
cmd_default_handler(const struct shell * sh,size_t argc,char ** argv)3877 static int cmd_default_handler(const struct shell *sh, size_t argc, char **argv)
3878 {
3879 	if (argc == 1) {
3880 		shell_help(sh);
3881 		return SHELL_CMD_HELP_PRINTED;
3882 	}
3883 
3884 	shell_error(sh, "%s unknown parameter: %s", argv[0], argv[1]);
3885 
3886 	return -EINVAL;
3887 }
3888 
3889 #define HELP_NONE "[none]"
3890 #define HELP_ONOFF "<on, off>"
3891 #define HELP_ADDR "<address: XX:XX:XX:XX:XX:XX>"
3892 #define HELP_ADDR_LE "<address: XX:XX:XX:XX:XX:XX> <type: (public|random)>"
3893 
3894 #if defined(CONFIG_BT_EXT_ADV)
3895 #define EXT_ADV_SCAN_OPT " [coded] [no-1m]"
3896 #define EXT_ADV_PARAM                                                                              \
3897 	"<type: conn-scan conn-nscan, nconn-scan nconn-nscan> "                                    \
3898 	"[ext-adv] [no-2m] [coded] [anon] [tx-power] [scan-reports] "                              \
3899 	"[filter-accept-list: fal, fal-scan, fal-conn] [identity] [name] "                         \
3900 	"[name-ad] [directed " HELP_ADDR_LE "] [mode: low] [dir-rpa] "                             \
3901 	"[disable-37] [disable-38] [disable-39]"
3902 #else
3903 #define EXT_ADV_SCAN_OPT ""
3904 #endif /* defined(CONFIG_BT_EXT_ADV) */
3905 
3906 #if defined(CONFIG_BT_OBSERVER)
3907 SHELL_STATIC_SUBCMD_SET_CREATE(bt_scan_filter_set_cmds,
3908 	SHELL_CMD_ARG(name, NULL, "<name>", cmd_scan_filter_set_name, 2, 0),
3909 	SHELL_CMD_ARG(addr, NULL, HELP_ADDR, cmd_scan_filter_set_addr, 2, 0),
3910 	SHELL_CMD_ARG(rssi, NULL, "<rssi>", cmd_scan_filter_set_rssi, 2, 0),
3911 	SHELL_CMD_ARG(pa_interval, NULL, "<pa_interval>",
3912 		      cmd_scan_filter_set_pa_interval, 2, 0),
3913 	SHELL_SUBCMD_SET_END
3914 );
3915 
3916 SHELL_STATIC_SUBCMD_SET_CREATE(bt_scan_filter_clear_cmds,
3917 	SHELL_CMD_ARG(all, NULL, "", cmd_scan_filter_clear_all, 1, 0),
3918 	SHELL_CMD_ARG(name, NULL, "", cmd_scan_filter_clear_name, 1, 0),
3919 	SHELL_CMD_ARG(addr, NULL, "", cmd_scan_filter_clear_addr, 1, 0),
3920 	SHELL_SUBCMD_SET_END
3921 );
3922 #endif /* CONFIG_BT_OBSERVER */
3923 
3924 SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds,
3925 	SHELL_CMD_ARG(init, NULL, "[no-settings-load], [sync]",
3926 		      cmd_init, 1, 2),
3927 	SHELL_CMD_ARG(disable, NULL, HELP_NONE, cmd_disable, 1, 0),
3928 #if defined(CONFIG_SETTINGS)
3929 	SHELL_CMD_ARG(settings-load, NULL, HELP_NONE, cmd_settings_load, 1, 0),
3930 #endif
3931 #if defined(CONFIG_BT_HCI)
3932 	SHELL_CMD_ARG(hci-cmd, NULL, "<ogf> <ocf> [data]", cmd_hci_cmd, 3, 1),
3933 #endif
3934 	SHELL_CMD_ARG(id-create, NULL, HELP_ADDR, cmd_id_create, 1, 1),
3935 	SHELL_CMD_ARG(id-reset, NULL, "<id> "HELP_ADDR, cmd_id_reset, 2, 1),
3936 	SHELL_CMD_ARG(id-delete, NULL, "<id>", cmd_id_delete, 2, 0),
3937 	SHELL_CMD_ARG(id-show, NULL, HELP_NONE, cmd_id_show, 1, 0),
3938 	SHELL_CMD_ARG(id-select, NULL, "<id>", cmd_id_select, 2, 0),
3939 	SHELL_CMD_ARG(name, NULL, "[name]", cmd_name, 1, 1),
3940 #if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC)
3941 	SHELL_CMD_ARG(appearance, NULL, "[new appearance value]", cmd_appearance, 1, 1),
3942 #else
3943 	SHELL_CMD_ARG(appearance, NULL, HELP_NONE, cmd_appearance, 1, 0),
3944 #endif /* CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC */
3945 #if defined(CONFIG_BT_OBSERVER)
3946 	SHELL_CMD_ARG(scan, NULL,
3947 		      "<value: on, passive, off> [filter: dups, nodups] [fal]"
3948 		      EXT_ADV_SCAN_OPT,
3949 		      cmd_scan, 2, 4),
3950 	SHELL_CMD(scan-filter-set, &bt_scan_filter_set_cmds,
3951 		      "Scan filter set commands",
3952 		      cmd_default_handler),
3953 	SHELL_CMD(scan-filter-clear, &bt_scan_filter_clear_cmds,
3954 		      "Scan filter clear commands",
3955 		      cmd_default_handler),
3956 	SHELL_CMD_ARG(scan-verbose-output, NULL, "<value: on, off>", cmd_scan_verbose_output, 2, 0),
3957 #endif /* CONFIG_BT_OBSERVER */
3958 #if defined(CONFIG_BT_BROADCASTER)
3959 	SHELL_CMD_ARG(advertise, NULL,
3960 		      "<type: off, on, scan, nconn> [mode: discov, non_discov] "
3961 		      "[filter-accept-list: fal, fal-scan, fal-conn] [identity] [no-name] "
3962 		      "[one-time] [name-ad] [appearance] "
3963 		      "[disable-37] [disable-38] [disable-39]",
3964 		      cmd_advertise, 2, 8),
3965 #if defined(CONFIG_BT_PERIPHERAL)
3966 	SHELL_CMD_ARG(directed-adv, NULL, HELP_ADDR_LE " [mode: low] "
3967 		      "[identity] [dir-rpa]",
3968 		      cmd_directed_adv, 3, 6),
3969 #endif /* CONFIG_BT_PERIPHERAL */
3970 #if defined(CONFIG_BT_EXT_ADV)
3971 	SHELL_CMD_ARG(adv-create, NULL, EXT_ADV_PARAM, cmd_adv_create, 2, 11),
3972 	SHELL_CMD_ARG(adv-param, NULL, EXT_ADV_PARAM, cmd_adv_param, 2, 11),
3973 	SHELL_CMD_ARG(adv-data, NULL, "<data> [scan-response <data>] "
3974 				      "<type: discov, hex> [appearance] ",
3975 		      cmd_adv_data, 1, 16),
3976 	SHELL_CMD_ARG(adv-start, NULL,
3977 		"[timeout <timeout>] [num-events <num events>]",
3978 		cmd_adv_start, 1, 4),
3979 	SHELL_CMD_ARG(adv-stop, NULL, HELP_NONE, cmd_adv_stop, 1, 0),
3980 	SHELL_CMD_ARG(adv-delete, NULL, HELP_NONE, cmd_adv_delete, 1, 0),
3981 	SHELL_CMD_ARG(adv-select, NULL, "[adv]", cmd_adv_select, 1, 1),
3982 	SHELL_CMD_ARG(adv-info, NULL, HELP_NONE, cmd_adv_info, 1, 0),
3983 #if defined(CONFIG_BT_PERIPHERAL)
3984 	SHELL_CMD_ARG(adv-oob, NULL, HELP_NONE, cmd_adv_oob, 1, 0),
3985 #endif /* CONFIG_BT_PERIPHERAL */
3986 #if defined(CONFIG_BT_PRIVACY)
3987 	SHELL_CMD_ARG(adv-rpa-expire, NULL, HELP_ONOFF, cmd_adv_rpa_expire, 2, 0),
3988 #endif
3989 #if defined(CONFIG_BT_PER_ADV)
3990 	SHELL_CMD_ARG(per-adv, NULL, HELP_ONOFF, cmd_per_adv, 2, 0),
3991 	SHELL_CMD_ARG(per-adv-param, NULL,
3992 		      "[<interval-min> [<interval-max> [tx_power]]]",
3993 		      cmd_per_adv_param, 1, 3),
3994 	SHELL_CMD_ARG(per-adv-data, NULL, "[data]", cmd_per_adv_data, 1, 1),
3995 #endif /* CONFIG_BT_PER_ADV */
3996 #endif /* CONFIG_BT_EXT_ADV */
3997 #endif /* CONFIG_BT_BROADCASTER */
3998 #if defined(CONFIG_BT_PER_ADV_SYNC)
3999 	SHELL_CMD_ARG(per-adv-sync-create, NULL,
4000 		      HELP_ADDR_LE " <sid> [skip <count>] [timeout <ms>] [aoa] "
4001 		      "[aod_1us] [aod_2us] [cte_only]",
4002 		      cmd_per_adv_sync_create, 4, 6),
4003 	SHELL_CMD_ARG(per-adv-sync-delete, NULL, "[<index>]",
4004 		      cmd_per_adv_sync_delete, 1, 1),
4005 #endif /* defined(CONFIG_BT_PER_ADV_SYNC) */
4006 #if defined(CONFIG_BT_CONN)
4007 #if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER)
4008 	SHELL_CMD_ARG(past-subscribe, NULL, "[conn] [skip <count>] "
4009 		      "[timeout <ms>] [aoa] [aod_1us] [aod_2us] [cte_only]",
4010 		      cmd_past_subscribe, 1, 7),
4011 	SHELL_CMD_ARG(past-unsubscribe, NULL, "[conn]",
4012 		      cmd_past_unsubscribe, 1, 1),
4013 #endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER */
4014 #if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)
4015 #if defined(CONFIG_BT_PER_ADV_SYNC)
4016 	SHELL_CMD_ARG(per-adv-sync-transfer, NULL, "[<index>]",
4017 		      cmd_per_adv_sync_transfer, 1, 1),
4018 #endif /* CONFIG_BT_PER_ADV_SYNC */
4019 #if defined(CONFIG_BT_PER_ADV)
4020 	SHELL_CMD_ARG(per-adv-set-info-transfer, NULL, "",
4021 		      cmd_per_adv_set_info_transfer, 1, 0),
4022 #endif /* CONFIG_BT_PER_ADV */
4023 #endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER */
4024 #if defined(CONFIG_BT_CENTRAL)
4025 	SHELL_CMD_ARG(connect, NULL, HELP_ADDR_LE EXT_ADV_SCAN_OPT,
4026 		      cmd_connect_le, 1, 3),
4027 #if !defined(CONFIG_BT_FILTER_ACCEPT_LIST)
4028 	SHELL_CMD_ARG(auto-conn, NULL, HELP_ADDR_LE, cmd_auto_conn, 3, 0),
4029 #endif /* !defined(CONFIG_BT_FILTER_ACCEPT_LIST) */
4030 	SHELL_CMD_ARG(connect-name, NULL, "<name filter>",
4031 		      cmd_connect_le_name, 2, 0),
4032 #endif /* CONFIG_BT_CENTRAL */
4033 	SHELL_CMD_ARG(disconnect, NULL, HELP_ADDR_LE, cmd_disconnect, 1, 2),
4034 	SHELL_CMD_ARG(select, NULL, HELP_ADDR_LE, cmd_select, 3, 0),
4035 	SHELL_CMD_ARG(info, NULL, HELP_ADDR_LE, cmd_info, 1, 2),
4036 	SHELL_CMD_ARG(conn-update, NULL, "<min> <max> <latency> <timeout>",
4037 		      cmd_conn_update, 5, 0),
4038 #if defined(CONFIG_BT_USER_DATA_LEN_UPDATE)
4039 	SHELL_CMD_ARG(data-len-update, NULL, "<tx_max_len> [tx_max_time]",
4040 		      cmd_conn_data_len_update, 2, 1),
4041 #endif
4042 #if defined(CONFIG_BT_USER_PHY_UPDATE)
4043 	SHELL_CMD_ARG(phy-update, NULL, "<tx_phy> [rx_phy] [s2] [s8]",
4044 		      cmd_conn_phy_update, 2, 3),
4045 #endif
4046 #if defined(CONFIG_BT_CENTRAL)
4047 	SHELL_CMD_ARG(channel-map, NULL, "<channel-map: XXXXXXXXXX> (36-0)",
4048 		      cmd_chan_map, 2, 1),
4049 #endif /* CONFIG_BT_CENTRAL */
4050 	SHELL_CMD_ARG(oob, NULL, HELP_NONE, cmd_oob, 1, 0),
4051 	SHELL_CMD_ARG(clear, NULL, "[all] ["HELP_ADDR_LE"]", cmd_clear, 2, 1),
4052 #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
4053 	SHELL_CMD_ARG(security, NULL, "<security level BR/EDR: 0 - 3, "
4054 				      "LE: 1 - 4> [force-pair]",
4055 		      cmd_security, 1, 2),
4056 	SHELL_CMD_ARG(bondable, NULL, HELP_ONOFF, cmd_bondable,
4057 		      2, 0),
4058 	SHELL_CMD_ARG(bonds, NULL, HELP_NONE, cmd_bonds, 1, 0),
4059 	SHELL_CMD_ARG(connections, NULL, HELP_NONE, cmd_connections, 1, 0),
4060 	SHELL_CMD_ARG(auth, NULL,
4061 		      "<method: all, input, display, yesno, confirm, "
4062 		      "oob, status, none>",
4063 		      cmd_auth, 2, 0),
4064 	SHELL_CMD_ARG(auth-cancel, NULL, HELP_NONE, cmd_auth_cancel, 1, 0),
4065 	SHELL_CMD_ARG(auth-passkey, NULL, "<passkey>", cmd_auth_passkey, 2, 0),
4066 #if defined(CONFIG_BT_PASSKEY_KEYPRESS)
4067 	SHELL_CMD_ARG(auth-passkey-notify, NULL, "<type>",
4068 		      cmd_auth_passkey_notify, 2, 0),
4069 #endif /* CONFIG_BT_PASSKEY_KEYPRESS */
4070 	SHELL_CMD_ARG(auth-passkey-confirm, NULL, HELP_NONE,
4071 		      cmd_auth_passkey_confirm, 1, 0),
4072 	SHELL_CMD_ARG(auth-pairing-confirm, NULL, HELP_NONE,
4073 		      cmd_auth_pairing_confirm, 1, 0),
4074 #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
4075 	SHELL_CMD_ARG(auth-oob-tk, NULL, "<tk>", cmd_auth_oob_tk, 2, 0),
4076 #endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */
4077 	SHELL_CMD_ARG(oob-remote, NULL,
4078 		      HELP_ADDR_LE" <oob rand> <oob confirm>",
4079 		      cmd_oob_remote, 3, 2),
4080 	SHELL_CMD_ARG(oob-clear, NULL, HELP_NONE, cmd_oob_clear, 1, 0),
4081 #if defined(CONFIG_BT_FILTER_ACCEPT_LIST)
4082 	SHELL_CMD_ARG(fal-add, NULL, HELP_ADDR_LE, cmd_fal_add, 3, 0),
4083 	SHELL_CMD_ARG(fal-rem, NULL, HELP_ADDR_LE, cmd_fal_rem, 3, 0),
4084 	SHELL_CMD_ARG(fal-clear, NULL, HELP_NONE, cmd_fal_clear, 1, 0),
4085 
4086 #if defined(CONFIG_BT_CENTRAL)
4087 	SHELL_CMD_ARG(fal-connect, NULL, HELP_ONOFF EXT_ADV_SCAN_OPT,
4088 		      cmd_fal_connect, 2, 3),
4089 #endif /* CONFIG_BT_CENTRAL */
4090 #endif /* defined(CONFIG_BT_FILTER_ACCEPT_LIST) */
4091 #if defined(CONFIG_BT_FIXED_PASSKEY)
4092 	SHELL_CMD_ARG(fixed-passkey, NULL, "[passkey]", cmd_fixed_passkey,
4093 		      1, 1),
4094 #endif
4095 #endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR) */
4096 #endif /* CONFIG_BT_CONN */
4097 #if defined(CONFIG_BT_HCI_MESH_EXT)
4098 	SHELL_CMD(mesh_adv, NULL, HELP_ONOFF, cmd_mesh_adv),
4099 #endif /* CONFIG_BT_HCI_MESH_EXT */
4100 
4101 #if defined(CONFIG_BT_LL_SW_SPLIT)
4102 	SHELL_CMD(ll-addr, NULL, "<random|public>", cmd_ll_addr_read),
4103 #if defined(CONFIG_BT_CTLR_ADV_EXT)
4104 #if defined(CONFIG_BT_BROADCASTER)
4105 	SHELL_CMD_ARG(advx, NULL,
4106 		      "<on hdcd ldcd off> [coded] [anon] [txp] [ad]",
4107 		      cmd_advx, 2, 4),
4108 #endif /* CONFIG_BT_BROADCASTER */
4109 #if defined(CONFIG_BT_OBSERVER)
4110 	SHELL_CMD_ARG(scanx, NULL, "<on passive off> [coded]", cmd_scanx,
4111 		      2, 1),
4112 #endif /* CONFIG_BT_OBSERVER */
4113 #endif /* CONFIG_BT_CTLR_ADV_EXT */
4114 #if defined(CONFIG_BT_CTLR_DTM)
4115 	SHELL_CMD_ARG(test_tx, NULL, "<chan> <len> <type> <phy>", cmd_test_tx,
4116 		      5, 0),
4117 	SHELL_CMD_ARG(test_rx, NULL, "<chan> <phy> <mod_idx>", cmd_test_rx,
4118 		      4, 0),
4119 	SHELL_CMD_ARG(test_end, NULL, HELP_NONE, cmd_test_end, 1, 0),
4120 #endif /* CONFIG_BT_CTLR_DTM */
4121 #endif /* CONFIG_BT_LL_SW_SPLIT */
4122 
4123 	SHELL_SUBCMD_SET_END
4124 );
4125 
4126 SHELL_CMD_REGISTER(bt, &bt_cmds, "Bluetooth shell commands", cmd_default_handler);
4127