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