Updating data in chained periodic advertising (1,650 bytes)

Hi team!

I have some doubts regarding updating the advertising data using periodic advertisements. We were able to advertise 1,650 bytes of data using periodic advertisements. But data does not get updated. I have explained everything in the points below. I request you to read through all of them. (Thanks in advance for your patience!)

The zephyr sample periodic_adv was taken as the base code. nRF Connect SDK v2.0.0 was used. The board used was nRF52840 DK. 

  1. Without chaining, the maximum AD Data buffer size that can be provided is 250 bytes. We provided the following buffer:
    static uint8_t mfg_data[] = { 0x59, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    			     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
    			     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
     			     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
    			     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
    			     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
    			     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
    			     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
     			     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
    			     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
    			     0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
    			     0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
    			     0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
    			     0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
    			     0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
                                 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB};
    static const struct bt_data ad[] = {BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 250),};


    and this was the main function:

    void main(void)
    {
    	struct bt_le_ext_adv *adv;
    	int err;
    
    	printk("Starting Periodic Advertising Demo\n");
    
          printk("Starting Periodic Advertising Demo\n");
          
          /*Function for setting a custom random static address*/
          set_random_static_address();
    
    	/* Initialize the Bluetooth Subsystem */
    	err = bt_enable(NULL);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return;
    	}
    
    	
    /* Create a non-connectable non-scannable advertising set */
    	err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_IDENTITY, NULL, &adv);
    	if (err) {
    		printk("Failed to create advertising set (err %d)\n", err);
    		return;
    	}
    	/* Set periodic advertising parameters */
    	struct bt_le_per_adv_param periodic_param = BT_LE_PER_ADV_PARAM_INIT(0x1f40, 0x1f40, BT_LE_PER_ADV_OPT_NONE); //for 10s
    
    	err = bt_le_per_adv_set_param(adv, &periodic_param);
    	if (err) {
    		printk("Failed to set periodic advertising parameters (err %d)\n", err);
    		return;
    	}
    
    
    	err = bt_le_per_adv_start(adv);
    	if (err) {
    		printk("Failed to enable periodic advertising (err %d)\n", err);
    		return;
    	}
    
    	/* Enable Extended Advertising */
    	printk("Start Extended Advertising...");
    		err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
    		if (err) {
    			printk("Failed to start extended advertising (err %d)\n", err);
    			return;
    		}
    		printk("done.\n");
    
    	while (true) {
    		
                mfg_data[2]=0;
    		for (int i = 0; i < 5; i++) {
    			k_sleep(K_SECONDS(10));
    
    			mfg_data[2]++;
    
    			printk("Set Periodic Advertising Data...");
    			err = bt_le_per_adv_set_data(adv, ad, ARRAY_SIZE(ad));
    			if (err) {
    				printk("Failed (err %d)\n", err);
    				return;
    			}
    			printk("done.\n");
    		}
    		
    	}
    }
    


    Please notice that the bt_le_per_adv_set_data() has only been called inside the while loop, after calling the bt_le_per_adv_start() function. This is the PuTTY output for this code:



    Clearly, the updated data gets successfully advertised. It was also verified using Wireshark, AUX_SYNC_IND packets with updated data are received at intervals of 10 seconds, which is also the value of periodic advertising interval.

  2. Next, the same code was used to advertise 1,650 bytes (maximum allowed) of advertising data, and the same approach was used as mentioned in one of my previous tickets (link). The following buffer was provided:

    static uint8_t mfg_data[] = { 0x59, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    			     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
    			     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
     			     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
    			     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
    			     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
    			     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
    			     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
     			     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
    			     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
    			     0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
    			     0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
    			     0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
    			     0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
    			     0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
                                 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB};
    
    
    static const struct bt_data ad[] = {BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),
    				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),  
    				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),  
    				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),  
    				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),  
    				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),  
    				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 112),};


    No changes were made to the main function. It was the same as mentioned in the first point. This was the output at the PuTTY terminal:



    The function bt_le_per_adv_set_data() threw error EINVAL. 

  3. Next, using the same buffer (for 1,650 bytes) we called the bt_le_per_adv_set_data() once before the bt_le_per_adv_start() function, and then again called bt_le_per_adv_set_data() inside the while loop at intervals of 10 seconds for updating the data, as shown in the code below:

    void main(void)
    {
    	struct bt_le_ext_adv *adv;
    	int err;
    
    	printk("Starting Periodic Advertising Demo\n");
    
          printk("Starting Periodic Advertising Demo\n");
          
          /*Function for setting a custom random static address*/
          set_random_static_address();
    
    	/* Initialize the Bluetooth Subsystem */
    	err = bt_enable(NULL);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return;
    	}
    
    	
    /* Create a non-connectable non-scannable advertising set */
    	err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_IDENTITY, NULL, &adv);
    	if (err) {
    		printk("Failed to create advertising set (err %d)\n", err);
    		return;
    	}
    	/* Set periodic advertising parameters */
    	struct bt_le_per_adv_param periodic_param = BT_LE_PER_ADV_PARAM_INIT(0x1f40, 0x1f40, BT_LE_PER_ADV_OPT_NONE); //for 10s
    
    	err = bt_le_per_adv_set_param(adv, &periodic_param);
    	if (err) {
    		printk("Failed to set periodic advertising parameters (err %d)\n", err);
    		return;
    	}
    
    
    	printk("Set Periodic Advertising Data...");
    			err = bt_le_per_adv_set_data(adv, ad, ARRAY_SIZE(ad));
    			if (err) {
    				printk("Failed (err %d)\n", err);
    				return;
    			}
    			printk("done.\n"); 
    
        
        /* Enable Periodic Advertising */
    	err = bt_le_per_adv_start(adv);
    	if (err) {
    		printk("Failed to enable periodic advertising (err %d)\n", err);
    		return;
    	}
    
    	/* Enable Extended Advertising */
    	printk("Start Extended Advertising...");
    		err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
    		if (err) {
    			printk("Failed to start extended advertising (err %d)\n", err);
    			return;
    		}
    		printk("done.\n");
    
    	while (true) {
    		
                mfg_data[2]=0;
    		for (int i = 0; i < 5; i++) {
    			k_sleep(K_SECONDS(10));
    
    			mfg_data[2]++;
    
    			printk("Set Periodic Advertising Data...");
    			err = bt_le_per_adv_set_data(adv, ad, ARRAY_SIZE(ad));
    			if (err) {
    				printk("Failed (err %d)\n", err);
    				return;
    			}
    			printk("done.\n");
    		}
    		
    	}
    }
    


    This is what we got at the PuTTY terminal:


    In this case, the periodic advertising data was set once, but data updation failed with error -22. We observed the received packets in Wireshark. PDUs with 1,650 bytes of payload were received at intervals of 10 seconds (periodic advertising interval), but all of them contained the same data since data updation failed. 

Now, I have the following concerns:

  • It is clear that it is possible to advertise 1,650 bytes of data in periodic advertisements. But, why does this data not get updated?
  • The bt_le_per_adv_set_data() function fails when called after the bt_le_per_adv_start() function, but works fine if called before bt_le_per_adv_start() function. Why is this happening?
  • If the order of these two functions matters, why are no errors encountered when the bt_le_per_adv_set_data() function is called after bt_le_per_adv_start(), in cases when there is no chaining? (sending up to 250 bytes of AD Data)

I am also attaching the complete code and the prj.conf file for your reference:

/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_vs.h>
#include <sys/byteorder.h>

static uint8_t mfg_data[] = { 0x59, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
			     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
			     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
 			     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
			     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
			     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
			     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
			     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
 			     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
			     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
			     0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
			     0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
			     0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
			     0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
			     0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
                             0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB};


static const struct bt_data ad[] = {BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),
				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),  
				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),  
				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),  
				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),  
				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 254),  
				    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 112),};


static void set_random_static_address(void)
{
int err;
        int err1;
printk("Starting iBeacon Demo\n");
       
bt_addr_le_t addr;

//convert the string into a binary address and stores this address in a buffer whose address is addr.
err=bt_addr_le_from_str("DE:AD:BE:AF:BA:11","random" , &addr);  //Only random static address can be given when the type is set to "random"
                if (err) {
printk("Invalid BT address (err %d)\n", err);
                         }

//create a new Identity address. This must be done before enabling Bluetooth. Addr is the address used for the new identity
err1=bt_id_create(&addr, NULL);
                if (err1 < 0) {
printk("Creating new ID failed (err %d)\n", err1);
}
            printk("Created new address\n");
 }


void main(void)
{
	struct bt_le_ext_adv *adv;
	int err;

	printk("Starting Periodic Advertising Demo\n");

      printk("Starting Periodic Advertising Demo\n");
      set_random_static_address();

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


/* Create a non-connectable non-scannable advertising set */
	err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_IDENTITY, NULL, &adv);
	if (err) {
		printk("Failed to create advertising set (err %d)\n", err);
		return;
	}
	/* Set periodic advertising parameters */
	struct bt_le_per_adv_param periodic_param = BT_LE_PER_ADV_PARAM_INIT(0x1f40, 0x1f40, BT_LE_PER_ADV_OPT_NONE); //for 10s

	err = bt_le_per_adv_set_param(adv, &periodic_param);
	if (err) {
		printk("Failed to set periodic advertising parameters (err %d)\n", err);
		return;
	}

	

	/* Enable Periodic Advertising */
	printk("Set Periodic Advertising Data...");
			err = bt_le_per_adv_set_data(adv, ad, ARRAY_SIZE(ad));
			if (err) {
				printk("Failed (err %d)\n", err);
				return;
			}
			printk("done.\n"); 

	err = bt_le_per_adv_start(adv);
	if (err) {
		printk("Failed to enable periodic advertising (err %d)\n", err);
		return;
	}

	/* Enable Extended Advertising */
	printk("Start Extended Advertising...");
		err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
		if (err) {
			printk("Failed to start extended advertising (err %d)\n", err);
			return;
		}
		printk("done.\n");

	while (true) {
		
            mfg_data[2]=0;
		for (int i = 0; i < 5; i++) {
			k_sleep(K_SECONDS(10));

			mfg_data[2]++;

			printk("Set Periodic Advertising Data...");
			err = bt_le_per_adv_set_data(adv, ad, ARRAY_SIZE(ad));
			if (err) {
				printk("Failed (err %d)\n", err);
				return;
			}
			printk("done.\n");
		}
		
	}
}

CONFIG_BT=y
CONFIG_BT_EXT_ADV=y
CONFIG_BT_PER_ADV=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_DEVICE_NAME="Test Periodic Advertising"

CONFIG_LOG=y
CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_ADV_PERIODIC=y
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=1650
CONFIG_SENSOR_LOG_LEVEL_DBG=y


I also have another doubt regarding periodic advertisements

Going by the Bluetooth core specification (version 5.3, Page 2768):


When including the ADI field is enabled by the Host and where the periodic advertising data is not changed for every periodic advertising event, the Controller should include the ADI field in the AUX_SYNC_IND PDU.


Does this mean that if the data is changed for every periodic advertising event, ADI field should be included in the AUX_SYNC_IND PDU? I also came across this section in the feature enhancement document of Bluetooth version 5.3:

The ADI field of the Common Extended Advertising Payload Format may now optionally be included in AUX_SYNC_IND periodic advertising PDUs by the controller in a broadcasting device at the request of the host.

and..

AUX_SYNC_IND PDUs may now include the ADI field. The inclusion of the ADI field in this PDU type is optional however and the controller’s link layer implementation will only include ADI in this packet type if the host requests that this be done by sending an HCI LE Set Periodic Advertising Enable command to the controller.

How exactly does the host "request" the inclusion of ADI in AUX_SYNC_IND? By changing advertising data in every periodic advertising event?

In my implementation where I update the advertising data in each periodic advertising event (which I'm currently able to do only when there are no chain PDUs used), Extended advertising header is absent in each AUX_SYNC_IND PDU, which means that ADI field is absent.

Is ADI inclusion not implemented in the SDK yet? Or is there a problem with my understanding?

  • Typically, there is a separate API to update the advertisements after you have started advertising. I am not that familiar with the extended chained advertisements, and I am a bit confused as of what API you are currently using (there are a lot of different snippets in your original post), but I see that in one snippet, you are trying to use bt_le_per_adv_set_data() in your main loop. I don't see an API that is obviously intended to update the chained advertisements, but I see in the declaration of bt_le_ext_adv_set_data() that it says:

     * @note When updating the advertising data while advertising the advertising
     *       data and scan response data length must be smaller or equal to what
     *       can be fit in a single advertising packet. Otherwise the
     *       advertiser must be stopped.

    So try stopping the advertisement first, using 

    int bt_le_ext_adv_stop(struct bt_le_ext_adv *adv);

    and then update, and start the advertisements again.

    Best regards,

    Edvin

  • Thanks Edvin. Just to make things clearer, we are trying to update the data in periodic advertising events using the API  bt_le_per_adv_set_data(). The data is larger than the capacity of a single packet. We tested what the declaration of bt_le_ext_adv_set_data() suggests, but this does not work for bt_le_per_adv_set_data(). 

    I would again like to highlight the fact that the data gets updated using the bt_le_per_adv_set_data() API when the data fits in a single packet, even without the need of stopping extended advertising. But as the data becomes large (chain PDUs have to be used), this does not work. The chains are advertised successfully if we don't update the data.

  • Hello,

    Yes, as I mentioned in the previously reply, it says in the description/documentation of the declaration of that function in bluetooth.h in the declaration for bt_le_ext_adv_set_data(), line 989 -> 1025:

    /**
     * @brief Set an advertising set's advertising or scan response data.
     *
     * Set advertisement data or scan response data. If the advertising set is
     * currently advertising then the advertising data will be updated in
     * subsequent advertising events.
     *
     * When both @ref BT_LE_ADV_OPT_EXT_ADV and @ref BT_LE_ADV_OPT_SCANNABLE are
     * enabled then advertising data is ignored.
     * When @ref BT_LE_ADV_OPT_SCANNABLE is not enabled then scan response data is
     * ignored.
     *
     * If the advertising set has been configured to send advertising data on the
     * primary advertising channels then the maximum data length is
     * @ref BT_GAP_ADV_MAX_ADV_DATA_LEN bytes.
     * If the advertising set has been configured for extended advertising,
     * then the maximum data length is defined by the controller with the maximum
     * possible of @ref BT_GAP_ADV_MAX_EXT_ADV_DATA_LEN bytes.
     *
     * @note Not all scanners support extended data length advertising data.
     *
     * @note When updating the advertising data while advertising the advertising
     *       data and scan response data length must be smaller or equal to what
     *       can be fit in a single advertising packet. Otherwise the
     *       advertiser must be stopped.
     *
     * @param adv     Advertising set object.
     * @param ad      Data to be used in advertisement packets.
     * @param ad_len  Number of elements in ad
     * @param sd      Data to be used in scan response packets.
     * @param sd_len  Number of elements in sd
     *
     * @return Zero on success or (negative) error code otherwise.
     */
    int bt_le_ext_adv_set_data(struct bt_le_ext_adv *adv,
    			   const struct bt_data *ad, size_t ad_len,
    			   const struct bt_data *sd, size_t sd_len);

    Where the note that I referenced in the previous reply is particularly relevant.

    So for chained advertisements to update, you need to stop the advertisements, set the data as if you set it the first time, and then restart advertising.

    FYI: I will be out of office for the next 3-4 weeks. Please open a new ticket for follow up questions, as I will not be able to monitor my DevZone tickets.

    Best regards,

    Edvin

  • Hi Edvin! 

    Hope you're back now.

    We invested a lot of time in framing the query properly, but sadly, nobody has dedicatedly attended the query. Can you please assign this to someone who can look into it properly? It's been over two months now. 

    If not, please let me know. I'll open a fresh ticket. 

    Thanks,

    Sukriti 

  • Hello Sukriti,

    Did you try to stop -> reinitialize -> and start the advertisements again? I don't really see that this ticket needs any reassignment. 

    As I have quoted 3 times now:

    * @note When updating the advertising data while advertising the advertising
    * data and scan response data length must be smaller or equal to what
    * can be fit in a single advertising packet. Otherwise the
    * advertiser must be stopped.

    It says in the declaration of the function you are trying to use. It is not possible to use bt_le_ext_adv_set_data() to update more than a single packet unless you stop the advertisements, and restart it. 

    Did you try using bt_le_per_adv_set_data()? As far as I can tell, it doesn't say that there are any length limitations on this call. However, the advertisement (old or new) can not be connectable, scannable nor anonymous. 

    Best regards,

    Edvin

Related