Bluetooth: Shell: Add support for EAD
Add new commands to manage the Encrypted Advertising Data feature. Overview of those new commands: - `bt encrypted-ad set-keys`: set key materials (session key and initialisation vector) used for encrypted and decryption of EAD; - `bt encrypted-ad add-ad`: store a given advertising data structure; - `bt encrypted-ad add-ead`: encrypt the given advertising data structres and store the generated AD structure; - `bt encrypted-ad commit-ad`: set the AD of the selected advertiser with the stored AD; - `bt encrypted-ad clear-ad`: remove all stored AD; - `bt encrypted-ad decrypt-scan`: decrypt data using the previously set key materials when receiving AD with type `0x31`. The documentation of the Bluetooth Shell has been updated to include those new commands. Signed-off-by: Théo Battrel <theo.battrel@nordicsemi.no>
This commit is contained in:
parent
f3f42d363b
commit
4a55bc00f0
3 changed files with 426 additions and 0 deletions
|
@ -228,6 +228,90 @@ Let's now have a look at some extended advertising features. To enable extended
|
|||
|
||||
This will create an extended advertiser, that is connectable and non-scannable.
|
||||
|
||||
Encrypted Advertising Data
|
||||
==========================
|
||||
|
||||
Zephyr has support for the Encrypted Advertising Data feature. The :code:`bt encrypted-ad`
|
||||
sub-commands allow managing the advertising data of a given advertiser.
|
||||
|
||||
To encrypt the advertising data, key materials need to be provided, that can be done with :code:`bt
|
||||
encrypted-ad set-keys <session key> <init vector>`. The session key is 16 bytes long and the
|
||||
initialisation vector is 8 bytes long.
|
||||
|
||||
You can add advertising data by using :code:`bt encrypted-ad add-ad` and :code:`bt encrypted-ad
|
||||
add-ead`. The former will take add one advertising data structure (as defined in the Core
|
||||
Specification), when the later will read the given data, encrypt them and then add the generated
|
||||
encrypted advertising data structure. It's possible to mix encrypted and non-encrypted data, when
|
||||
done adding advertising data, :code:`bt encrypted-ad commit-ad` can be used to apply the change to
|
||||
the data to the selected advertiser. After that the advertiser can be started as described
|
||||
previously. It's possible to clear the advertising data by using :code:`bt encrypted-ad clear-ad`.
|
||||
|
||||
On the Central side, it's possible to decrypt the received encrypted advertising data by setting the
|
||||
correct keys material as described earlier and then enabling the decrypting of the data with
|
||||
:code:`bt encrypted-ad decrypt-scan on`.
|
||||
|
||||
.. note::
|
||||
|
||||
To see the advertising data in the scan report :code:`bt scan-verbose-output` need to be
|
||||
enabled.
|
||||
|
||||
.. note::
|
||||
|
||||
It's possible to increase the length of the advertising data by increasing the value of
|
||||
:kconfig:option:`CONFIG_BT_CTLR_ADV_DATA_LEN_MAX` and
|
||||
:kconfig:option:`CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX`.
|
||||
|
||||
Here is a simple example demonstrating the usage of EAD:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Peripheral
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bt init
|
||||
...
|
||||
uart:~$ bt adv-create conn-nscan ext-adv
|
||||
Created adv id: 0, adv: 0x81769a0
|
||||
uart:~$ bt encrypted-ad set-keys 9ba22d3824efc70feb800c80294cba38 2e83f3d4d47695b6
|
||||
session key set to:
|
||||
00000000: 9b a2 2d 38 24 ef c7 0f eb 80 0c 80 29 4c ba 38 |..-8$... ....)L.8|
|
||||
initialisation vector set to:
|
||||
00000000: 2e 83 f3 d4 d4 76 95 b6 |.....v.. |
|
||||
uart:~$ bt encrypted-ad add-ad 06097368656C6C
|
||||
uart:~$ bt encrypted-ad add-ead 03ffdead03ffbeef
|
||||
uart:~$ bt encrypted-ad commit-ad
|
||||
Advertising data for Advertiser[0] 0x81769a0 updated.
|
||||
uart:~$ bt adv-start
|
||||
Advertiser[0] 0x81769a0 set started
|
||||
|
||||
.. group-tab:: Central
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bt init
|
||||
...
|
||||
uart:~$ bt scan-verbose-output on
|
||||
uart:~$ bt encrypted-ad set-keys 9ba22d3824efc70feb800c80294cba38 2e83f3d4d47695b6
|
||||
session key set to:
|
||||
00000000: 9b a2 2d 38 24 ef c7 0f eb 80 0c 80 29 4c ba 38 |..-8$... ....)L.8|
|
||||
initialisation vector set to:
|
||||
00000000: 2e 83 f3 d4 d4 76 95 b6 |.....v.. |
|
||||
uart:~$ bt encrypted-ad decrypt-scan on
|
||||
Received encrypted advertising data will now be decrypted using provided key materials.
|
||||
uart:~$ bt scan on
|
||||
Bluetooth active scan enabled
|
||||
[DEVICE]: 68:49:30:68:49:30 (random), AD evt type 5, RSSI -59 shell C:1 S:0 D:0 SR:0 E:1 Prim: LE 1M, Secn: LE 2M, Interval: 0x0000 (0 us), SID: 0x0
|
||||
[SCAN DATA START - EXT_ADV]
|
||||
Type 0x09: shell
|
||||
Type 0x31: Encrypted Advertising Data: 0xe2, 0x17, 0xed, 0x04, 0xe7, 0x02, 0x1d, 0xc9, 0x40, 0x07, uart:~0x18, 0x90, 0x6c, 0x4b, 0xfe, 0x34, 0xad
|
||||
[START DECRYPTED DATA]
|
||||
Type 0xff: 0xde, 0xad
|
||||
Type 0xff: 0xbe, 0xef
|
||||
[END DECRYPTED DATA]
|
||||
[SCAN DATA END]
|
||||
...
|
||||
|
||||
Filter Accept List
|
||||
******************
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <zephyr/bluetooth/classic/rfcomm.h>
|
||||
#include <zephyr/bluetooth/classic/sdp.h>
|
||||
#include <zephyr/bluetooth/iso.h>
|
||||
#include <zephyr/bluetooth/ead.h>
|
||||
|
||||
#include <zephyr/shell/shell.h>
|
||||
|
||||
|
@ -216,6 +217,30 @@ static struct bt_scan_filter {
|
|||
static const char scan_response_label[] = "[DEVICE]: ";
|
||||
static bool scan_verbose_output;
|
||||
|
||||
#if defined(CONFIG_BT_EAD)
|
||||
static uint8_t bt_shell_ead_session_key[BT_EAD_KEY_SIZE] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5,
|
||||
0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB,
|
||||
0xCC, 0xCD, 0xCE, 0xCF};
|
||||
static uint8_t bt_shell_ead_iv[BT_EAD_IV_SIZE] = {0xFB, 0x56, 0xE1, 0xDA, 0xDC, 0x7E, 0xAD, 0xF5};
|
||||
|
||||
/* this is the number of ad struct allowed */
|
||||
#define BT_SHELL_EAD_MAX_AD 10
|
||||
static size_t bt_shell_ead_ad_len;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_DATA_LEN_MAX)
|
||||
/* this is the maximum total size of the ad data */
|
||||
#define BT_SHELL_EAD_DATA_MAX_SIZE CONFIG_BT_CTLR_ADV_DATA_LEN_MAX
|
||||
#else
|
||||
#define BT_SHELL_EAD_DATA_MAX_SIZE 31
|
||||
#endif
|
||||
static size_t bt_shell_ead_data_size;
|
||||
static uint8_t bt_shell_ead_data[BT_SHELL_EAD_DATA_MAX_SIZE] = {0};
|
||||
|
||||
int ead_update_ad(void);
|
||||
#endif
|
||||
|
||||
static bool bt_shell_ead_decrypt_scan;
|
||||
|
||||
/**
|
||||
* @brief Compares two strings without case sensitivy
|
||||
*
|
||||
|
@ -383,6 +408,36 @@ static bool data_verbose_cb(struct bt_data *data, void *user_data)
|
|||
case BT_DATA_CSIS_RSI:
|
||||
print_data_set(3, data->data, data->data_len);
|
||||
break;
|
||||
case BT_DATA_ENCRYPTED_AD_DATA:
|
||||
shell_fprintf(ctx_shell, SHELL_INFO, "Encrypted Advertising Data: ");
|
||||
print_data_set(1, data->data, data->data_len);
|
||||
|
||||
if (bt_shell_ead_decrypt_scan) {
|
||||
#if defined(CONFIG_BT_EAD)
|
||||
shell_fprintf(ctx_shell, SHELL_INFO, "\n%*s[START DECRYPTED DATA]\n",
|
||||
strlen(scan_response_label), "");
|
||||
|
||||
int ead_err;
|
||||
struct net_buf_simple decrypted_buf;
|
||||
size_t decrypted_data_size = BT_EAD_DECRYPTED_PAYLOAD_SIZE(data->data_len);
|
||||
uint8_t decrypted_data[decrypted_data_size];
|
||||
|
||||
ead_err = bt_ead_decrypt(bt_shell_ead_session_key, bt_shell_ead_iv,
|
||||
data->data, data->data_len, decrypted_data);
|
||||
if (ead_err) {
|
||||
shell_error(ctx_shell, "Error during decryption (err %d)", ead_err);
|
||||
}
|
||||
|
||||
net_buf_simple_init_with_data(&decrypted_buf, &decrypted_data[0],
|
||||
decrypted_data_size);
|
||||
|
||||
bt_data_parse(&decrypted_buf, &data_verbose_cb, user_data);
|
||||
|
||||
shell_fprintf(ctx_shell, SHELL_INFO, "%*s[END DECRYPTED DATA]",
|
||||
strlen(scan_response_label), "");
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
print_data_set(1, data->data, data->data_len);
|
||||
}
|
||||
|
@ -581,6 +636,13 @@ static bool adv_rpa_expired(struct bt_le_ext_adv *adv)
|
|||
adv_index, adv,
|
||||
keep_rpa ? "not expired" : "expired");
|
||||
|
||||
#if defined(CONFIG_BT_EAD)
|
||||
/* EAD must be updated each time the RPA is updated */
|
||||
if (!keep_rpa) {
|
||||
ead_update_ad();
|
||||
}
|
||||
#endif
|
||||
|
||||
return keep_rpa;
|
||||
}
|
||||
#endif /* defined(CONFIG_BT_PRIVACY) */
|
||||
|
@ -4127,6 +4189,267 @@ static int cmd_auth_oob_tk(const struct shell *sh, size_t argc, char *argv[])
|
|||
#endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */
|
||||
#endif /* CONFIG_BT_SMP) || CONFIG_BT_CLASSIC */
|
||||
|
||||
#if defined(CONFIG_BT_EAD)
|
||||
static int cmd_encrypted_ad_set_keys(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
size_t len;
|
||||
|
||||
const char *session_key = argv[1];
|
||||
const char *iv = argv[2];
|
||||
|
||||
len = hex2bin(session_key, strlen(session_key), bt_shell_ead_session_key, BT_EAD_KEY_SIZE);
|
||||
if (len != BT_EAD_KEY_SIZE) {
|
||||
shell_error(sh, "Failed to set session key");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
len = hex2bin(iv, strlen(iv), bt_shell_ead_iv, BT_EAD_IV_SIZE);
|
||||
if (len != BT_EAD_IV_SIZE) {
|
||||
shell_error(sh, "Failed to set initialisation vector");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
shell_info(sh, "session key set to:");
|
||||
shell_hexdump(sh, bt_shell_ead_session_key, BT_EAD_KEY_SIZE);
|
||||
shell_info(sh, "initialisation vector set to:");
|
||||
shell_hexdump(sh, bt_shell_ead_iv, BT_EAD_IV_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int encrypted_ad_store_ad(const struct shell *sh, uint8_t type, const uint8_t *data,
|
||||
uint8_t data_len)
|
||||
{
|
||||
/* data_len is the size of the data, add two bytes for the size of the type
|
||||
* and the length that will be stored with the data
|
||||
*/
|
||||
uint8_t new_data_size = data_len + 2;
|
||||
|
||||
if (bt_shell_ead_data_size + new_data_size > BT_SHELL_EAD_DATA_MAX_SIZE) {
|
||||
shell_error(sh, "Failed to add data (trying to add %d but %d already used on %d)",
|
||||
new_data_size, bt_shell_ead_data_size, BT_SHELL_EAD_DATA_MAX_SIZE);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* the length is the size of the data + the size of the type */
|
||||
bt_shell_ead_data[bt_shell_ead_data_size] = data_len + 1;
|
||||
bt_shell_ead_data[bt_shell_ead_data_size + 1] = type;
|
||||
memcpy(&bt_shell_ead_data[bt_shell_ead_data_size + 2], data, data_len);
|
||||
|
||||
bt_shell_ead_data_size += new_data_size;
|
||||
bt_shell_ead_ad_len += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_payload_valid_ad(uint8_t *payload, size_t payload_size)
|
||||
{
|
||||
size_t idx = 0;
|
||||
bool is_valid = true;
|
||||
|
||||
uint8_t ad_len;
|
||||
|
||||
while (idx < payload_size) {
|
||||
ad_len = payload[idx];
|
||||
|
||||
if (payload_size <= ad_len) {
|
||||
is_valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
idx += ad_len + 1;
|
||||
}
|
||||
|
||||
if (idx != payload_size) {
|
||||
is_valid = false;
|
||||
}
|
||||
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
static int cmd_encrypted_ad_add_ead(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
size_t len;
|
||||
|
||||
char *hex_payload = argv[1];
|
||||
size_t hex_payload_size = strlen(hex_payload);
|
||||
|
||||
uint8_t payload[BT_SHELL_EAD_DATA_MAX_SIZE] = {0};
|
||||
uint8_t payload_size = hex_payload_size / 2 + hex_payload_size % 2;
|
||||
|
||||
uint8_t ead_size = BT_EAD_ENCRYPTED_PAYLOAD_SIZE(payload_size);
|
||||
|
||||
if (ead_size > BT_SHELL_EAD_DATA_MAX_SIZE) {
|
||||
shell_error(sh,
|
||||
"Failed to add data. Maximum AD size is %d, passed data size after "
|
||||
"encryption is %d",
|
||||
BT_SHELL_EAD_DATA_MAX_SIZE, ead_size);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
len = hex2bin(hex_payload, hex_payload_size, payload, BT_SHELL_EAD_DATA_MAX_SIZE);
|
||||
if (len != payload_size) {
|
||||
shell_error(sh, "Failed to add data");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* check that the given advertising data structures are valid before encrypting them */
|
||||
if (!is_payload_valid_ad(payload, payload_size)) {
|
||||
shell_error(sh, "Failed to add data. Advertising structure are malformed.");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* store not-yet encrypted AD but claim the expected size of encrypted AD */
|
||||
return encrypted_ad_store_ad(sh, BT_DATA_ENCRYPTED_AD_DATA, payload, ead_size);
|
||||
}
|
||||
|
||||
static int cmd_encrypted_ad_add_ad(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
size_t len;
|
||||
uint8_t ad_len;
|
||||
uint8_t ad_type;
|
||||
|
||||
char *hex_payload = argv[1];
|
||||
size_t hex_payload_size = strlen(hex_payload);
|
||||
|
||||
uint8_t payload[BT_SHELL_EAD_DATA_MAX_SIZE] = {0};
|
||||
uint8_t payload_size = hex_payload_size / 2 + hex_payload_size % 2;
|
||||
|
||||
len = hex2bin(hex_payload, hex_payload_size, payload, BT_SHELL_EAD_DATA_MAX_SIZE);
|
||||
if (len != payload_size) {
|
||||
shell_error(sh, "Failed to add data");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* the length received is the length of ad data + the length of the data
|
||||
* type but `bt_data` struct `data_len` field is only the size of the
|
||||
* data
|
||||
*/
|
||||
ad_len = payload[0] - 1;
|
||||
ad_type = payload[1];
|
||||
|
||||
/* if the ad data is malformed or there is more than 1 ad data passed we
|
||||
* fail
|
||||
*/
|
||||
if (len != ad_len + 2) {
|
||||
shell_error(sh,
|
||||
"Failed to add data. Data need to be formated as specified in the "
|
||||
"Core Spec. Only one non-encrypted AD payload can be added at a time.");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
return encrypted_ad_store_ad(sh, ad_type, payload, payload_size);
|
||||
}
|
||||
|
||||
static int cmd_encrypted_ad_clear_ad(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
memset(bt_shell_ead_data, 0, BT_SHELL_EAD_DATA_MAX_SIZE);
|
||||
|
||||
bt_shell_ead_ad_len = 0;
|
||||
bt_shell_ead_data_size = 0;
|
||||
|
||||
shell_info(sh, "Advertising data has been cleared.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ead_encrypt_ad(const uint8_t *payload, uint8_t payload_size, uint8_t *encrypted_payload)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = bt_ead_encrypt(bt_shell_ead_session_key, bt_shell_ead_iv, payload, payload_size,
|
||||
encrypted_payload);
|
||||
if (err != 0) {
|
||||
shell_error(ctx_shell, "Failed to encrypt AD.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ead_update_ad(void)
|
||||
{
|
||||
int err;
|
||||
size_t idx = 0;
|
||||
struct bt_le_ext_adv *adv = adv_sets[selected_adv];
|
||||
|
||||
struct bt_data *ad;
|
||||
size_t ad_structs_idx = 0;
|
||||
struct bt_data ad_structs[BT_SHELL_EAD_MAX_AD] = {0};
|
||||
|
||||
size_t encrypted_data_buf_len = 0;
|
||||
uint8_t encrypted_data_buf[BT_SHELL_EAD_DATA_MAX_SIZE] = {0};
|
||||
|
||||
while (idx < bt_shell_ead_data_size && ad_structs_idx < BT_SHELL_EAD_MAX_AD) {
|
||||
ad = &ad_structs[ad_structs_idx];
|
||||
|
||||
/* the data_len from bt_data struct doesn't include the size of the type */
|
||||
ad->data_len = bt_shell_ead_data[idx] - 1;
|
||||
|
||||
if (ad->data_len < 0) {
|
||||
/* if the len is less than 0 that mean there is not even a type field */
|
||||
shell_error(ctx_shell, "Failed to update AD due to malformed AD.");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
ad->type = bt_shell_ead_data[idx + 1];
|
||||
|
||||
if (ad->data_len > 0) {
|
||||
if (ad->type == BT_DATA_ENCRYPTED_AD_DATA) {
|
||||
/* for EAD the size used to store the non-encrypted data
|
||||
* is the size of those data when encrypted
|
||||
*/
|
||||
ead_encrypt_ad(&bt_shell_ead_data[idx + 2],
|
||||
BT_EAD_DECRYPTED_PAYLOAD_SIZE(ad->data_len),
|
||||
&encrypted_data_buf[encrypted_data_buf_len]);
|
||||
|
||||
ad->data = &encrypted_data_buf[encrypted_data_buf_len];
|
||||
encrypted_data_buf_len += ad->data_len;
|
||||
} else {
|
||||
ad->data = &bt_shell_ead_data[idx + 2];
|
||||
}
|
||||
}
|
||||
|
||||
ad_structs_idx += 1;
|
||||
idx += ad->data_len + 2;
|
||||
}
|
||||
|
||||
err = bt_le_ext_adv_set_data(adv, ad_structs, bt_shell_ead_ad_len, NULL, 0);
|
||||
if (err != 0) {
|
||||
shell_error(ctx_shell, "Failed to set advertising data (err %d)", err);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
shell_info(ctx_shell, "Advertising data for Advertiser[%d] %p updated.", selected_adv, adv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_encrypted_ad_commit_ad(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
return ead_update_ad();
|
||||
}
|
||||
|
||||
static int cmd_encrypted_ad_decrypt_scan(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
const char *action = argv[1];
|
||||
|
||||
if (strcmp(action, "on") == 0) {
|
||||
bt_shell_ead_decrypt_scan = true;
|
||||
shell_info(sh, "Received encrypted advertising data will now be decrypted using "
|
||||
"provided key materials.");
|
||||
} else if (strcmp(action, "off") == 0) {
|
||||
bt_shell_ead_decrypt_scan = false;
|
||||
shell_info(sh, "Received encrypted advertising data will now longer be decrypted.");
|
||||
} else {
|
||||
shell_error(sh, "Invalid option.");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cmd_default_handler(const struct shell *sh, size_t argc, char **argv)
|
||||
{
|
||||
if (argc == 1) {
|
||||
|
@ -4174,6 +4497,19 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_scan_filter_clear_cmds,
|
|||
);
|
||||
#endif /* CONFIG_BT_OBSERVER */
|
||||
|
||||
#if defined(CONFIG_BT_EAD)
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(
|
||||
bt_encrypted_ad_cmds,
|
||||
SHELL_CMD_ARG(set-keys, NULL, "<session key> <init vector>", cmd_encrypted_ad_set_keys, 3,
|
||||
0),
|
||||
SHELL_CMD_ARG(add-ead, NULL, "<advertising data>", cmd_encrypted_ad_add_ead, 2, 0),
|
||||
SHELL_CMD_ARG(add-ad, NULL, "<advertising data>", cmd_encrypted_ad_add_ad, 2, 0),
|
||||
SHELL_CMD(clear-ad, NULL, HELP_NONE, cmd_encrypted_ad_clear_ad),
|
||||
SHELL_CMD(commit-ad, NULL, HELP_NONE, cmd_encrypted_ad_commit_ad),
|
||||
SHELL_CMD_ARG(decrypt-scan, NULL, HELP_ONOFF, cmd_encrypted_ad_decrypt_scan, 2, 0),
|
||||
SHELL_SUBCMD_SET_END);
|
||||
#endif
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds,
|
||||
SHELL_CMD_ARG(init, NULL, "[no-settings-load], [sync]",
|
||||
cmd_init, 1, 2),
|
||||
|
@ -4262,6 +4598,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds,
|
|||
cmd_per_adv_sync_delete, 1, 1),
|
||||
SHELL_CMD_ARG(per-adv-sync-select, NULL, "[adv]", cmd_per_adv_sync_select, 1, 1),
|
||||
#endif /* defined(CONFIG_BT_PER_ADV_SYNC) */
|
||||
#if defined(CONFIG_BT_EAD)
|
||||
SHELL_CMD(encrypted-ad, &bt_encrypted_ad_cmds, "Manage advertiser with encrypted data",
|
||||
cmd_default_handler),
|
||||
#endif /* CONFIG_BT_EAD */
|
||||
#if defined(CONFIG_BT_CONN)
|
||||
#if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER)
|
||||
SHELL_CMD_ARG(past-subscribe, NULL, "[conn] [skip <count>] "
|
||||
|
|
|
@ -46,6 +46,8 @@ CONFIG_BT_PER_ADV_SYNC=y
|
|||
CONFIG_BT_USER_DATA_LEN_UPDATE=y
|
||||
CONFIG_BT_AUTO_DATA_LEN_UPDATE=y
|
||||
|
||||
CONFIG_BT_EAD=y
|
||||
|
||||
CONFIG_BT_USER_PHY_UPDATE=y
|
||||
CONFIG_BT_AUTO_PHY_UPDATE=y
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue