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