Using bt_le_adv_update_data()

This is a continuation of Case ID: 272157

That case resolved issues I had dynamically changing the device name (and having that new name show up in advertising).

It seemed to work OK when developing the code using the nRF52840-DK board.

i'm now using that code with nRF Connect SDK 2.0.0 and Visual Studio code (and Zephyr) on a custom board.   The target device is nrf52840 in a BL654PA module.

The code to "rename" the device is:

int newBleAdvName(char *newName) {
  int err;

  // Update the device name
  printk("Set new name: %s\n",newName);
  err = bt_set_name(newName);
  if(err) {
    printk("Error setting device name: %d\n", err);
  } else {
printk("Changed device name to: %s\n", newName);
    // Update the advertising and scan response data needed to update the advertised device name
    // Only need to modify the scan response data in this example as name is in scan response here.
    sd->data = newName;
    sd->data_len = strlen(newName);
    err = bt_le_adv_update_data(ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    if(err) {
      printk("Error setting advertised name: %d\n", err);
    } else {
printk("Changed advertised name to: %s\n", newName);
    }
  }
  return err;
}

When invoked, function fails, returning error code -11    From errno.h        #define EAGAIN 11       /**< No more contexts */  

Here is a screen capture of the RTT console output during that time:

If I set a breakpoint to try to step through, I get an exception:

I suspect this is due to some real-time interaction with the BLE stack, so I think the error code message is what I need to resolve.

It's unclear to me what "No more contexts" means or how to correct this.

Do you have any suggestions?

Thanks!

Parents
  • The hardfault gave the faulting instruction address. Can you check in your .map file what function exists there. What is the context in which you are calling newBleAdvName?

  • Hi Susheel,

    Thanks...

    The hardfault only occurs when I insert breakpoints (attempting to debug), so I think this is associated with BLE realtime issues being violated.    But the hardfault address points to:

    0x38 modules/nrf/subsys/mpsl/init/lib..__nrf__subsys__mpsl__init.a(mpsl_init.c.obj)

    newBleAdvName is called due to a characteristic being written to the device (from the central) that assigns a new device name to the device.    So it is called from a "characteristic written" callback in the device.    This is the expected behavior, but the calls to bt_set_name and bt_le_adv_update_data return -11.     I'm not sure what the "No more contexts" indicates.

    Thanks again!                                                                                                                                                                                                                                                                                                                                                                      

  • Does advertising have to be active for "bt_le_adv_update_data" to execute successfully?   Is this what the "context" error refers to?

Reply Children
  • I do not think that the advertising needs to be active but it needs to be enabled before you can update data.

    in zephyr\subsys\bluetooth\host\adv.c:bt_le_adv_update_data: 

    847 (NCSv2.0.0)

    	if (!atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
    		return -EAGAIN;
    	}

  • Thanks...    I saw this when I was trying to figure out why this is failing.

    It appears that the flag "BT_ADV_ENABLED" is an internal flag, maintained by the code in adv.c

    And from a quick reading of the code, it looks like this flag indicates whether or not advertising is active.

    So if I want to dynamically change the advertised name, do I need to make sure advertising is active before calling bt_le_adv_update_data?    If so, how?  There doesn't seem to be a call that exposes "BT_ADV_ENABLED" (for testing).   

    What I intend (have implemented) is a BLE characteristic (that can be written to the peripheral) that contains a new device name.   When written, the peripheral saves the name, but also attempts to call bt_le_adv_update_data.    Note that to receive the characteristic the device (peripheral) has to be connected, so advertising is not active.  So when the new name is received, bt_le_adv_update_data fails with an error code of -11, which appears to be the test of BT_ADB_ENABLED.     The intent is for this device to use the new name when the device starts advertising again.  (I actually disconnect from the device (from the central) after confirmation of writing the new name has been reported, so the device will start advertising again.)    But since the call to bt_le_adv_update_data failed, the new name is not used.

    Also note that when the device is turned on (reset), the name to use for advertising is read from persistent storage and, after advertising is "started", assigned using bt_le_adv_update_data.    This call works with no error message.

    So it appears that advertising needs to be active for this call to work.   Is there a reason for this?

    Thanks...

  • As a test, I commented out the three lines (847-849) of adv.c, where the BT_ADV_ENABLED flag is tested.    This eliminates the test that causes the name-change failure.    

    This results in the name being changed as intended/expected.   

    So now the question becomes, does this break anything else?    Is this a "bug" in this function?

    Thanks...

  • I cannot see that there is anything in the specification that says that the advertiser needs to be enabled to change the data. It seems like this check might not be needed to update the advertising data offline (when advertiser is not running)

  • OK, thanks...   I'll continue to "comment it out" in my code.    Can you start the process of having it removed from the official code?

    Thanks!

Related