Updating scan response packet whilst advertising

In my application, I'm using the Scan Response Packet to transmit some device related information, rather than requiring Clients to connect to get this.  I'm using NCS v2.0.0 and testing on an nRF52-DK.

I'm using the following to store the scan response information, and I update the information in there whenever it changes.

static struct bt_data sd[] = {
    BT_DATA(BT_DATA_MANUFACTURER_DATA, NULL, BT_GAP_ADV_MAX_ADV_DATA_LEN-2),
};

On first boot up, when I start BLE, I make a call to:

err = bt_le_adv_start(BT_LE_ADV_CONN_LSR_AD, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));

That successfully updates the scan response packet.  But if I subsequently attempt to update the scan response packet whilst I'm still advertising, via a call to:

err = bt_le_adv_update_data(ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));

Then the scan response packet doesn't change.  I'm checking the result of err after this function call, and its returning 0, which indicates that its been successful.

The only way I seem able to get the scan response packet to update correctly is if I:

  1. Stop advertising
  2. Update scan response packet
  3. Restart advertising

Is there a way to dynamically update the scan response packet whilst advertising?  Or do I need to follow the process of stop, update, restart?

Cheers,

Mike

  • A bit of info I should have included:

    #define BT_LE_ADV_CONN_LSR_AD BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE |\
    												BT_LE_ADV_OPT_USE_NAME |\
    												BT_LE_ADV_OPT_FORCE_NAME_IN_AD,\
    												BT_GAP_ADV_FAST_INT_MIN_2, \
    												BT_GAP_ADV_FAST_INT_MAX_2, NULL)

  • Hi Mike Austin,

    I notice that the data field of your Scan Response BT_DATA macro is NULL, however that is where you supply data to the API. That is most likely the problem. I am not sure how you update the Scan Response data like with that setup though?

    On my end, I set up as followed and just calling bt_le_adv_update_data() worked. As I started with a non-connectable base, I test without the BT_LE_ADV_OPT_CONNECTABLE flag. I don't think it changes anything though.

    static uint8_t mfg_data[BT_GAP_ADV_MAX_ADV_DATA_LEN-2] = { 0xff, 0xff, 0x00 };
    
    static const struct bt_data sd[] = {
    	BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, BT_GAP_ADV_MAX_ADV_DATA_LEN-2),
    };
    
    ...
    
    	while(1) {
    		k_sleep(K_MSEC(1000));
    
    		mfg_data[2]++;
    		printk("mfg_data = {%02x, %02x, %02x}\n", mfg_data[0], mfg_data[1], mfg_data[2]);
    
    		err = bt_le_adv_update_data(ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    		printk("bt_le_adv_update_data %d\n\n", err); 
    		if (err) return;
    	}

    Could you please try it and let me know if it works?

    Best regards,

    Hieu

  • Hi Hieu,

    Got it sorted.  Had nothing to do with how I had set everything up, but was in fact related to an if() statement I had my bt_le_adv_update_data(ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); call inside.  Basically, the if() statement wasn't ever becoming true, so I wasn't ever sending out the updated scan response data.  Should have checked my code better!

    A quick related question - the if() statement was basically checking to see if I had disconnected and was advertising again, as I update some of the info that I send out on the scan response packet via a BLE connection to a client.  So, before I attempt to update the scan response packet I was doing a check to ensure I was back advertising.

    I do this with a bool that I set to 

    bt_status = BLE_ADVERTISING;
    within my .disconnected call back.  But that basically assumes that if I'm disconnected, I'm advertising, as I don't actually know of any way of checking the current BLE status.  It could, for example, have stopped completely.
    Do you know if there are any API's that will return the current BLE status?
    Cheers,
    Mike
  • Hi Mike,

    Glad to know you got it worked out.

    Unfortunately, I also don't think there is any API to help you directly get the advertising status.

    However, I found that if you use Advertisement Set, you can setup some helpful callback while calling bt_le_ext_adv_create().

    If you feel like you have a strong use case, I think you can open a feature request in the Zephyr project. If you do, please share it with the community by giving the link here.

    Hope that helps.

    Best regards,

    Hieu

  • Hi Hieu,

    Just stumbled across this link on DevZone.  I know its a few years old, and probably refers to the older soft devices which I'm not using, but it is basically saying you need to keep track of whether your device is advertising or connected yourself.  I had been doing this, but also had a DISCONNECTED state that I set my flag to when it disconnected.  Seems that the peripheral will automatically return to advertising once its disconnected, and so I now set my flag to ADVERTISING in my .disconnected call back.

    I've come from an Infineon/Cypress background, and they have a bunch of API's you can call to get the current state of the stack, and I just assumed it was something pretty standard.

    Anyway, I'll keep this in mind and just use my own flags to keep track of what's going on with my BLE stack

    Cheers,

    Mike

Related