Hello!
I tried to send extended adv on nrf5340, but encountered some problems.The extended adv packet type i want to send is Non-connectable and Non-scannable and directed, my code configuration is as follows:
/* main.c - Application main entry point */ /* * Copyright (c) 2015-2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/types.h> #include <stddef.h> #include <zephyr/sys/printk.h> #include <zephyr/sys/util.h> #include <zephyr/kernel.h> // #include <zephyr/logging/log.h> #include <zephyr/bluetooth/bluetooth.h> #include <zephyr/bluetooth/hci.h> #include <zephyr/bluetooth/addr.h> typedef struct adv_mfg_data { // uint8_t id; /* company id */ // uint8_t integer; /* integer part */ // uint8_t mantissa; /* mantissa part */ float temp; } adv_mfg_data_type; static adv_mfg_data_type adv_temperature_data = {-25.11}; static const struct bt_data ad[] = { BT_DATA(BT_DATA_MANUFACTURER_DATA,(unsigned char *)&adv_temperature_data, sizeof(adv_temperature_data)) }; static const bt_addr_le_t addr = { .type = 1, .a = { .val = {0x0a,0x62,0x24,0x06,0x53,0x3e} } }; static struct bt_le_adv_param * adv_param = BT_LE_ADV_PARAM((BT_LE_ADV_OPT_EXT_ADV|BT_LE_ADV_OPT_USE_IDENTITY| \ BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY|BT_LE_ADV_OPT_NO_2M), 400, 400, &addr); void main(void) { int err; printk("Starting Beacon Demo\n"); /* Initialize the Bluetooth Subsystem */ err = bt_enable(NULL); if (err) { printk("Bluetooth init failed (err %d)\n", err); return; } printk("Bluetooth initialized\n"); err = bt_le_adv_start(adv_param, ad, ARRAY_SIZE(ad), (void*)NULL, 0); if (err) { printk("Advertising failed to start (err %d)\n", err); return; } printk("Advertising successfully started\n"); for (;;) { k_sleep(K_SECONDS(2)); } }
And I also enabled extended adv in prj.conf:
CONFIG_BT=y CONFIG_BT_DEBUG_LOG=y CONFIG_BT_DEVICE_NAME="beacon" CONFIG_BT_EXT_ADV=y
However, when i run the code,it can't start advertising and the output is as follows:
*** Booting Zephyr OS build v3.2.99-ncs2 *** Starting Beacon Demo [00:00:00.289,550] <inf> bt_hci_core: hci_vs_init: HW Platform: Nordic Semiconductor (0x0002) [00:00:00.289,611] <inf> bt_hci_core: hci_vs_init: HW Variant: nRF53x (0x0003) [00:00:00.289,611] <inf> bt_hci_core: hci_vs_init: Firmware: Standard Bluetooth controller (0x00) Version 216.11532 Build 3803067951 [00:00:00.291,320] <inf> bt_hci_core: bt_dev_show_info: Identity: CD:B8:1D:7E:27:B0 (random) [00:00:00.291,351] <inf> bt_hci_core: bt_dev_show_info: HCI: version 5.3 (0x0c) revision 0x224b, manufacturer 0x0059 [00:00:00.291,381] <inf> bt_hci_core: bt_dev_show_info: LMP: version 5.3 (0x0c) subver 0x224b Bluetooth initialized [00:00:00.291,809] <wrn> bt_hci_core: bt_hci_cmd_send_sync: opcode 0x2036 status 0x01 Advertising failed to start (err -5)
the err code is -5,corresponding the EIO.I tried to debug to trace the error, and I found that the error was generated when calling bt_hci_cmd_send_sync in the le_ext_adv_param_set call,but i can't understand.
And i also have questions about the adv.c code:
int bt_le_adv_start_ext(struct bt_le_ext_adv *adv, const struct bt_le_adv_param *param, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len) { struct bt_le_ext_adv_start_param start_param = { .timeout = 0, .num_events = 0, }; bool dir_adv = (param->peer != NULL); struct bt_conn *conn = NULL; int err; if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) { return -EAGAIN; } if (!valid_adv_param(param)) { return -EINVAL; } if (atomic_test_bit(adv->flags, BT_ADV_ENABLED)) { return -EALREADY; } adv->id = param->id; err = le_ext_adv_param_set(adv, param, sd != NULL); if (err) { return err; } if (!dir_adv) { err = bt_le_ext_adv_set_data(adv, ad, ad_len, sd, sd_len); if (err) { return err; } } else { if (!(param->options & BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY)) { start_param.timeout = BT_GAP_ADV_HIGH_DUTY_CYCLE_MAX_TIMEOUT; atomic_set_bit(adv->flags, BT_ADV_LIMITED); } } if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && (param->options & BT_LE_ADV_OPT_CONNECTABLE)) { err = le_adv_start_add_conn(adv, &conn); if (err) { if (err == -ENOMEM && !dir_adv && !(param->options & BT_LE_ADV_OPT_ONE_TIME)) { goto set_adv_state; } return err; } } err = bt_le_adv_set_enable_ext(adv, true, &start_param); if (err) { LOG_ERR("Failed to start advertiser"); if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn) { bt_conn_set_state(conn, BT_CONN_DISCONNECTED); bt_conn_unref(conn); } return err; } if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn) { /* If undirected connectable advertiser we have created a * connection object that we don't yet give to the application. * Since we don't give the application a reference to manage in * this case, we need to release this reference here */ bt_conn_unref(conn); } set_adv_state: /* Flag always set to false by le_ext_adv_param_set */ atomic_set_bit_to(adv->flags, BT_ADV_PERSIST, !dir_adv && !(param->options & BT_LE_ADV_OPT_ONE_TIME)); return 0; } static bool valid_adv_param(const struct bt_le_adv_param *param) { if (param->options & BT_LE_ADV_OPT_EXT_ADV) { return false; } if (param->peer && !(param->options & BT_LE_ADV_OPT_CONNECTABLE)) { return false; } return valid_adv_ext_param(param); }
When I want to send extended adv, I have to add the BT_LE_ADV_OPT_EXT_ADV option, but why does valid_adv_param have these two judgment statements? Does this mean that the system does not support sending extended adv by default (I commented out these two judgment statements when I used them)?
is there an example or demo I can refer to?
looking forward to your reply!