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