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