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