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