Multiple Advertising Sets in NCS

I am attempting to advertise two sets, one using coded PHY and one using 1M, currently using the master NCS branch (post v1.7.0-rc2 tag). This is on a custom board with an nRF52840.

When attempting to start advertising a 2nd advertising set via a 2nd call to bt_le_ext_adv_start with different args, I'm getting an assert from MPSL from inside its timer0 ISR (unhelpful log: <err> mpsl_init: MPSL ASSERT: 112, 2164 ).

Relevant code:

#define ADV_OPTIONS_COMMON  BT_LE_ADV_OPT_CONNECTABLE \
                          | BT_LE_ADV_OPT_USE_NAME \
                          | BT_LE_ADV_OPT_EXT_ADV \
                          | BT_LE_ADV_OPT_USE_TX_POWER

int ble_adv_init(void) {
    int err;

    struct bt_le_ext_adv *adv_set_coded_PHY = NULL;
    struct bt_le_ext_adv *adv_set_1M_PHY = NULL;

    struct bt_le_adv_param adv_param_coded = {
        .id = BT_ID_DEFAULT,
        .sid = 0,
        .secondary_max_skip = 0,
        .options = ADV_OPTIONS_COMMON | BT_LE_ADV_OPT_CODED,    // Advertise on long-range coded PHY
        .interval_min = 0x20,   // 20 ms (32 * 0.625)
        .interval_max = 0x152,  // 152.5 ms
        .peer = NULL
    };

    struct bt_le_adv_param adv_param_1M = {
        .id = BT_ID_DEFAULT,
        .sid = 1,
        .secondary_max_skip = 0,
        .options = ADV_OPTIONS_COMMON | BT_LE_ADV_OPT_NO_2M,    // Advertise only on legacy 1M PHY
        .interval_min = 0x20,   // 20 ms (32 * 0.625)
        .interval_max = 0x152,  // 152.5 ms
        .peer = NULL
    };

    struct bt_le_ext_adv_cb adv_cb = {.sent = adv_sent};

    err = bt_le_ext_adv_create(&adv_param_coded, &adv_cb, &adv_set_coded_PHY);
    if (err) {
        // TODO
        return err;
    }

    err = bt_le_ext_adv_create(&adv_param_1M, &adv_cb, &adv_set_1M_PHY);
    if (err) {
        // TODO
        return err;
    }

    err = bt_le_ext_adv_set_data(adv_set_coded_PHY, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    if (err) {
        // TODO
        return err;
    }

    err = bt_le_ext_adv_set_data(adv_set_1M_PHY, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    if (err) {
        // TODO
        return err;
    }

    struct bt_le_ext_adv_start_param adv_start_param = {
        .timeout = 30000,   // 5 minutes in 10 ms units
        .num_events = 0
    };

    err = bt_le_ext_adv_start(adv_set_coded_PHY, &adv_start_param);
    if (err) {
        // TODO
        return err;
    }

    err = bt_le_ext_adv_start(adv_set_1M_PHY, &adv_start_param);    // Never returns, logs: <err> mpsl_init: MPSL ASSERT: 112, 2164
    if (err) {
        // TODO
        return err;
    }

    return 0;
}

Relevant prj.conf settings:

## General BLE Properties
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CTLR_PHY_CODED=y
CONFIG_BT_USER_PHY_UPDATE=y
CONFIG_BT_SMP=y
CONFIG_BT_PRIVACY=y
CONFIG_BT_MAX_CONN=2
CONFIG_BT_MAX_PAIRED=3
CONFIG_BT_SIGNING=y

## BLE Advertising options
CONFIG_BT_EXT_ADV=y
CONFIG_BT_EXT_ADV_MAX_ADV_SET=2

Am I missing something?

  • Refactoring my code to call bt_le_ext_adv_start via the system work queue, as is done in the peripheral_hr_coded sample eliminates the assertion error. However, I'm not seeing the 1M PHY advertisements. (Also I discovered nRF Connect Desktop doesn't currently support coded PHY, so I don't have the easy means to test I thought I did.)

  • Hi

    You're correct in that the nRFConnect for Desktop BLE app does not support Coded PHY. You will have to use either a phone supporting Coded PHY and the nRFConnect app or a central scanning over the Coded PHY like the Central Heart Rate monitor with Coded PHY in the NCS for instance.

    Do you have a DK available so you can test if your application's advertisements are caught by any scanners there? This way we can narrow it down to either a HW or SW issue.

    Best regards,

    Simon

  • Calling bt_le_ext_adv_start from the system work queue (even multiple times) prevents the assert. Calling it just once from my main thread triggers the assertion.

    Additionally, when attempting to only advertise adv_param_1M, I still don't see any advertising data.

  • Hi

    Can you provide some details on what you mean by "when attempting to only advertise adv_param_1M, I still don't see any advertising data." What do you need to do to be able to spot the advertising data, or are you not able to at all?

    You can check out this ticket where my colleague Karl explains how to set up multiple advertising sets in detail.

    Do you have a DK available so you can test if your application's advertisements are caught by any scanners there? This way we can narrow it down to either a HW or SW issue.

    Best regards,

    Simon

  • An update. One of our developers ran this project on the v1.7.0-rc2 revision, and was not able to reproduce this assert. They started out with the peripheral_hr_coded example in NCS and added the following patch. Both advertising sets then start as intended, and provides a successful return code. Console output attached here as well.

    79655.patch

    Bluetooth initialized
    ble_adv_init err 0
    [00:00:00.004,516] <inf> sdc_hci_driver: SoftDevice Controller build revision:
                                             3f 47 70 8e 81 95 4e 86  9d d3 a2 95 88 f6 30 0a |?Gp...N. ......0.
                                             7f 53 49 fd                                      |.SI.
    [00:00:00.007,293] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
    [00:00:00.007,293] <inf> bt_hci_core: HW Variant: nRF52x (0x0002)
    [00:00:00.007,324] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 63.28743 Build 1318420878
    [00:00:00.008,392] <inf> bt_hci_core: Identity: FC:10:15:C3:E6:EE (random)
    [00:00:00.008,392] <inf> bt_hci_core: HCI: version 5.2 (0x0b) revision 0x125b, manufacturer 0x0059
    [00:00:00.008,392] <inf> bt_hci_core: LMP: version 5.2 (0x0b) subver 0x125b
    

    Best regards,

    Simon

Related