bt_le_adv_start() returns -22, with adv_param.id=1

I'm adding this post as I'm not sure MDL's problem (or my problem) on this thread will be noticed otherwise (I'm guessing as there's an accepted answer the other thread might not be noticed).

The problem seems to come down to the internal bt_dev.id_count being equal to 1, which means that bt_le_adv_start() fails if we use adv_param.id of 1.

More is explained in the other thread.

Thanks for the help!

  • Hello,

    Depending on the notification settings, the assigned support engineer may not receive a notification when comments are added to an old thread. Thus, it is always safer to raise a new ticket with a reference to the old thread. But to answer your question, yes, you need to call bt_id_create() to increase the id_count. Please note that this API has some caveats. For instance, it behaves differently depending on when it is called, as discussed in this thread: RE: problems with bt_id_create   

    Best regards,

    Vidar

  • Thanks for the tip!

    I've called bt_id_create twice (I guess that was necessary so the "0"th and "1"th entries exist). I found it now works!

    Here's the whole main.c file:

    /*
    * Copyright (c) 2018 Nordic Semiconductor ASA
    *
    * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    */

    #include <zephyr/types.h>
    #include <stddef.h>
    #include <string.h>
    #include <errno.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/sys/byteorder.h>
    #include <zephyr/kernel.h>
    #include <zephyr/drivers/gpio.h>
    #include <soc.h>

    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/hci.h>
    #include <zephyr/bluetooth/conn.h>
    #include <zephyr/bluetooth/uuid.h>
    #include <zephyr/bluetooth/gatt.h>

    #include <bluetooth/services/lbs.h>

    #include <zephyr/settings/settings.h>

    #include <dk_buttons_and_leds.h>

    #define DEVICE_NAME CONFIG_BT_DEVICE_NAME
    #define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)


    #define RUN_STATUS_LED DK_LED1
    #define CON_STATUS_LED DK_LED2
    #define RUN_LED_BLINK_INTERVAL 1000

    #define USER_LED DK_LED3

    #define USER_BUTTON DK_BTN1_MSK

    static bool app_button_state;

    static const struct bt_data ad[] = {
    BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
    };

    static const struct bt_data sd[] = {
    BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_LBS_VAL),
    };

    static void connected(struct bt_conn *conn, uint8_t err)
    {
    if (err) {
    printk("Connection failed (err %u)\n", err);
    return;
    }

    printk("Connected\n");

    dk_set_led_on(CON_STATUS_LED);
    }

    static void disconnected(struct bt_conn *conn, uint8_t reason)
    {
    printk("Disconnected (reason %u)\n", reason);

    dk_set_led_off(CON_STATUS_LED);
    }

    #ifdef CONFIG_BT_LBS_SECURITY_ENABLED
    static void security_changed(struct bt_conn *conn, bt_security_t level,
    enum bt_security_err err)
    {
    char addr[BT_ADDR_LE_STR_LEN];

    bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

    if (!err) {
    printk("Security changed: %s level %u\n", addr, level);
    } else {
    printk("Security failed: %s level %u err %d\n", addr, level,
    err);
    }
    }
    #endif

    BT_CONN_CB_DEFINE(conn_callbacks) = {
    .connected = connected,
    .disconnected = disconnected,
    #ifdef CONFIG_BT_LBS_SECURITY_ENABLED
    .security_changed = security_changed,
    #endif
    };

    #if defined(CONFIG_BT_LBS_SECURITY_ENABLED)
    static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey)
    {
    char addr[BT_ADDR_LE_STR_LEN];

    bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

    printk("Passkey for %s: %06u\n", addr, passkey);
    }

    static void auth_cancel(struct bt_conn *conn)
    {
    char addr[BT_ADDR_LE_STR_LEN];

    bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

    printk("Pairing cancelled: %s\n", addr);
    }

    static void pairing_complete(struct bt_conn *conn, bool bonded)
    {
    char addr[BT_ADDR_LE_STR_LEN];

    bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

    printk("Pairing completed: %s, bonded: %d\n", addr, bonded);
    }

    static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
    {
    char addr[BT_ADDR_LE_STR_LEN];

    bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

    printk("Pairing failed conn: %s, reason %d\n", addr, reason);
    }

    static struct bt_conn_auth_cb conn_auth_callbacks = {
    .passkey_display = auth_passkey_display,
    .cancel = auth_cancel,
    };

    static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
    .pairing_complete = pairing_complete,
    .pairing_failed = pairing_failed
    };
    #else
    static struct bt_conn_auth_cb conn_auth_callbacks;
    static struct bt_conn_auth_info_cb conn_auth_info_callbacks;
    #endif

    static void app_led_cb(bool led_state)
    {
    dk_set_led(USER_LED, led_state);
    }

    static bool app_button_cb(void)
    {
    return app_button_state;
    }

    static struct bt_lbs_cb lbs_callbacs = {
    .led_cb = app_led_cb,
    .button_cb = app_button_cb,
    };

    static void button_changed(uint32_t button_state, uint32_t has_changed)
    {
    if (has_changed & USER_BUTTON) {
    uint32_t user_button_state = button_state & USER_BUTTON;

    bt_lbs_send_button_state(user_button_state);
    app_button_state = user_button_state ? true : false;
    }
    }

    static int init_button(void)
    {
    int err;

    err = dk_buttons_init(button_changed);
    if (err) {
    printk("Cannot init buttons (err: %d)\n", err);
    }

    return err;
    }

    void main(void)
    {
    int blink_status = 0;
    int err;
    struct bt_le_adv_param adv_param = {
    .id = BT_ID_DEFAULT,
    .sid = 0,
    .secondary_max_skip = 0,
    .options = (BT_LE_ADV_OPT_CONNECTABLE),
    .interval_min = 0x0020, /* 20 ms */
    .interval_max = 0x0020, /* 20 ms */
    .peer = NULL,
    };

    printk("Starting Bluetooth Peripheral LBS example\n");

    err = dk_leds_init();
    if (err) {
    printk("LEDs init failed (err %d)\n", err);
    return;
    }

    err = init_button();
    if (err) {
    printk("Button init failed (err %d)\n", err);
    return;
    }

    if (IS_ENABLED(CONFIG_BT_LBS_SECURITY_ENABLED)) {
    err = bt_conn_auth_cb_register(&conn_auth_callbacks);
    if (err) {
    printk("Failed to register authorization callbacks.\n");
    return;
    }

    err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
    if (err) {
    printk("Failed to register authorization info callbacks.\n");
    return;
    }
    }

    bt_addr_le_t addr;

    err = bt_addr_le_from_str("DE:AD:BE:EF:BA:11", "random", &addr);
    if (err) {
    printk("Invalid BT address (err %d)\n", err);
    }



    err = bt_enable(NULL);
    if (err) {
    printk("Bluetooth init failed (err %d)\n", err);
    return;
    }
    err = bt_id_create(&addr, NULL);
    if (err < 0) {
    printk("Creating new ID failed #1(err %d)\n", err);
    }
    err = bt_addr_le_from_str("DE:AD:BE:FF:FF:11", "random", &addr);
    err = bt_id_create(&addr, NULL);
    if (err < 0) {
    printk("Creating new ID failed #2 (err %d)\n", err);
    }
    printk("Bluetooth initialized\n");

    if (IS_ENABLED(CONFIG_SETTINGS)) {
    printk("Loading settings...\n");
    err = settings_load();
    if (err<0) {
    printk("Failed to load settings (err:%d)\n", err);
    }
    }
    err = bt_lbs_init(&lbs_callbacs);
    if (err) {
    printk("Failed to init LBS (err:%d)\n", err);
    return;
    }
    adv_param.id=1;
    err = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad),
    sd, ARRAY_SIZE(sd));
    if (err) {
    printk("Advertising failed to start (err %d)\n", err);
    return;
    }

    printk("Advertising successfully started\n");
    err = bt_addr_le_from_str("DE:AD:BE:FF:FF:11", "random", &addr);
    for (;;) {
    dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
    k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
    bt_le_adv_stop();
    addr.a.val[0]=addr.a.val[0]+1;
    err = bt_id_reset(1,&addr, NULL);
    if (err < 0) {
    printk("Reset ID failed (err %d)\n", err);
    };
    err = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad),
    sd, ARRAY_SIZE(sd));
    if (err) {
    printk("Advertising failed to start (err %d)\n", err);
    return;
    }
    }
    }

    void oldmain(void)
    {
    int blink_status = 0;
    int err;

    printk("Starting Bluetooth Peripheral LBS example\n");

    err = dk_leds_init();
    if (err) {
    printk("LEDs init failed (err %d)\n", err);
    return;
    }

    err = init_button();
    if (err) {
    printk("Button init failed (err %d)\n", err);
    return;
    }

    if (IS_ENABLED(CONFIG_BT_LBS_SECURITY_ENABLED)) {
    err = bt_conn_auth_cb_register(&conn_auth_callbacks);
    if (err) {
    printk("Failed to register authorization callbacks.\n");
    return;
    }

    err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
    if (err) {
    printk("Failed to register authorization info callbacks.\n");
    return;
    }
    }

    err = bt_enable(NULL);
    if (err) {
    printk("Bluetooth init failed (err %d)\n", err);
    return;
    }

    printk("Bluetooth initialized\n");

    if (IS_ENABLED(CONFIG_SETTINGS)) {
    settings_load();
    }

    err = bt_lbs_init(&lbs_callbacs);
    if (err) {
    printk("Failed to init LBS (err:%d)\n", err);
    return;
    }

    err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad),
    sd, ARRAY_SIZE(sd));
    if (err) {
    printk("Advertising failed to start (err %d)\n", err);
    return;
    }

    printk("Advertising successfully started\n");

    for (;;) {
    dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
    k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
    }
    }
Related