Dynamically changing Advertisement name when using PHY ENCODED

I'm using the nRF52840 with NCS SDK 2.0.2 and need to be able to change the BLE advertisement name of the peripheral device dynamically.

I have this working when using "normal" BLE strength.    This is accomplished by calling "bt_le_adv_update_data()", but also needs a change in the file adv.c  (Commenting out lines 847-849).  See Case #272157

After getting "normal" BLE working, I am attempting to use "PHY ENCODED" to extend the BLE range using the example in NCS SDK 2.0.2   (See Case #294814).

I can get the initial device name to advertise using PHY ENCODED, but haven't figured out how to change the name dynamically.    I tried using "bt_le_adv_upate_data()" but this doesn't work.

I also tried calling bt_le_ext_adv_set_data() again (with the updated data), but the initial device name continues to be advertised.

What is the sequence needed to dynamically change the advertised name when using PHY ENCODED?   (Why is it different from "normal" BLE)?

Thanks!

Parents
  • Hello

    According to the description of bt_set_name(), it looks like it might be bt_le_ext_adv_set_data() you are looking for?

    Or have you tried using bt_set_name()?

    Best regards,

    Einar

  • Hi Einarh,

    Thanks...

    The text in the bt_set_name() definition says to use  bt_le_adv_update_data or bt_le_ext_adv_set_data once advertising has been started.

    I tried using bt_le_adv_update_data, but it fails with error -EINVAL (-22).   (This is the call I use to change the name when using "normal" BLE.)       Tracing through the code, it looks like bt_le_adv_update_data expects the "struct bt_le_ext_adv" variable (adv) to be in the "bt_dev" structure.    Following the "coded" example, I declared the "adv" variable separately.   And there doesn't seem to be a call to assign the value to the "bt_dev" structure.    So the call to "bt_le_adv_lookup_legacy()" inside bt_le_adv_update_data returns NULL, causing the error.

    So I tried using bt_le_ext_adv_set_data.

    "bt_le_ext_adv_set_data" is used to set the advertising name after the advertising set is created (using "bt_le_ext_adv_create"),     It is then used again when trying to change the name.    The function call returns without error, but the original name is still advertised.

    What is the appropriate way to change the advertising name (when using PHY CODED)?    Thoughts?

    PS...    I also tried stopping advertising prior to calling bt_le_ext_adv_set_data(), then restarting it.    Still advertises with original name...

  • Hi

    Looking at bt_le_ext_adv_update_param():

    When changing the option BT_LE_ADV_OPT_USE_NAME then bt_le_ext_adv_set_data needs to be called in order to update the advertising data and scan response data.

    And then looking at BT_LE_ADV_OPT_USE_NAME:

    Include the GAP device name automatically when advertising.
    By default the GAP device name is put at the end of the scan
    response data.
    When advertising using BT_LE_ADV_OPT_EXT_ADV and not
    BT_LE_ADV_OPT_SCANNABLE then it will be put at the end of the
    advertising data. [...]

    And from bt_le_ext_adv_set_data():

    When both BT_LE_ADV_OPT_EXT_ADV and BT_LE_ADV_OPT_SCANNABLE are enabled then advertising data is ignored. When BT_LE_ADV_OPT_SCANNABLE is not enabled then scan response data is ignored.

    How do you currently include your advertising name in your advertising data? Is it in your advertising data or your response data? If BT_LE_ADV_OPT_SCANNABLE is disabled it seems like the GAP device name set by bt_set_name() will be included in your advertising data, have you tried this?

    -Einar

  • In prj.conf:

    CONFIG_BT_DEVICE_NAME_DYNAMIC=y
    Where are the "defines" you mention set?

    I set the device name via bt_set_name().   But to change the advertising name:

    for "normal" BLE, the advertised name is in the sd[] array and bt_le_adv_update_data() is used to change it.     This works.

    for "coded" BLE , the advertised name is in the ad[] array and I've tried both bt_le_ext_adv_set_data() and bt_le_adv_update_data() to change the name.    As mentioned above, using bt_le_adv_update_data() fails.   Using bt_le_ext_adv_set_data() does not return an error, but the advertised name doesn't change.

    Here is the code for assigning a new name...   Lots of debugging printk statements...    A #ifdef is used to select one set of code.

    For "normal" BLE:

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

    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 variable: %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 updating advertised name: %d\n", err);
        } else {
    printk("Changed advertised name to: %s\n", newName);
        }
      }
      return err;
    }

    For "coded" BLE:

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

    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 variable: %d\n", err);
      } else {
    printk("Changed device name to: %s\n", newName);
    
    btAdvertisingStop();
    
        // 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.
        ad->data = newName;
        ad->data_len = strlen(newName);
        err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), NULL, 0);
        //err = bt_le_adv_update_data(ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
        if(err) {
          printk("Error updating advertised name: %d\n", err);
        } else {
    printk("Changed encoded advertised name to: %s\n", newName);
        }
    btAdvertisingReStart();
      }
      return err;
    }
    
    

    Note...   This works in "normal" BLE, but not in "coded".    (Is scannable data legal in "coded")?

Reply
  • In prj.conf:

    CONFIG_BT_DEVICE_NAME_DYNAMIC=y
    Where are the "defines" you mention set?

    I set the device name via bt_set_name().   But to change the advertising name:

    for "normal" BLE, the advertised name is in the sd[] array and bt_le_adv_update_data() is used to change it.     This works.

    for "coded" BLE , the advertised name is in the ad[] array and I've tried both bt_le_ext_adv_set_data() and bt_le_adv_update_data() to change the name.    As mentioned above, using bt_le_adv_update_data() fails.   Using bt_le_ext_adv_set_data() does not return an error, but the advertised name doesn't change.

    Here is the code for assigning a new name...   Lots of debugging printk statements...    A #ifdef is used to select one set of code.

    For "normal" BLE:

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

    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 variable: %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 updating advertised name: %d\n", err);
        } else {
    printk("Changed advertised name to: %s\n", newName);
        }
      }
      return err;
    }

    For "coded" BLE:

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

    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 variable: %d\n", err);
      } else {
    printk("Changed device name to: %s\n", newName);
    
    btAdvertisingStop();
    
        // 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.
        ad->data = newName;
        ad->data_len = strlen(newName);
        err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), NULL, 0);
        //err = bt_le_adv_update_data(ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
        if(err) {
          printk("Error updating advertised name: %d\n", err);
        } else {
    printk("Changed encoded advertised name to: %s\n", newName);
        }
    btAdvertisingReStart();
      }
      return err;
    }
    
    

    Note...   This works in "normal" BLE, but not in "coded".    (Is scannable data legal in "coded")?

Children
Related