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?

  • Edvin, the entire concern is about the API bt_le_per_adv_set_data(). Yes, I can send 1650 bytes of data, but this data does not get updated using this API if packet chaining comes into the picture. What you have shown here is about the extended advertising API, which I have not talked about anywhere in the entire query.

    You have quoted it three times but my concern is not related to the API that you are quoting. Also, if I have to stop advertising and re-start it for updating the data in periodic advertisements as well, this essentially means that I am re-establishing the sync everytime I wish to update the data. Specification does not say this. Infact, the Bluetooth SIG explicitly states in each of its official documents, that periodic advertising events can carry varying payload.

    This has not been said anywhere for extended advertisements.

    I'll quote a statement from one of the SIG documents:

    Advertising takes place at fixed intervals called the periodic advertising interval and the advertising data payload may change

    The re-start thing that you have shown three times is nowhere written for the periodic advertising APIs. Also, I have been asking again only because there has not been a single crisp answer telling me whether at all it's possible to send unique data each time using periodic advertising events, because it is not happening right now using the bt_le_per_adv_set_data() API for large data. It only happens for small payload sizes that fit into a single PDU.

    Did you try using bt_le_per_adv_set_data()

    Yes Edvin, if you read through my query properly, I have used this API only, and have talked about it multiple times.

    Thanks
    Sukriti

  • Ok, I understand Suktiti,

    It is a bit difficult to keep track when that much time passes by, and I may not be that good at reading all the previous replies in a case. Please understand that we try to handle many (!) questions every day.

    I will check with our SoftDevice controller team how it is intended to update chained advertisements larger than BT_HCI_LE_PER_ADV_FRAG_MAX_LEN bytes (252 bytes). I will keep you posted.

    Best regards,

    Edvin

  • Ok, so I discussed this with our SoftDevice Controller team, and I will try to summarize it here.

    As I mentioned, there is a check inside bt_le_per_adv_set_data() that returns an error if the "total_len_bytes > BT_HCI_LE_PER_ADV_FRAG_MAX_LEN". 

    I asked them what would be the way to do it if you wanted to change all (up to 1650 bytes) at once, which would be a reasonable thing to want to do. They replied that you can't do this. That is:

    "You can change all advertising data at once, but only if the total advertising data length is less than or equal to 252 bytes. The reason you cannot use more is that if you have more than 252 bytes, the data will have to be forwarded to the controller in multiple steps due to the fact that HCI packets have a maximum packet length."

    So I interpret this as: You need to change the advertising in multiple calls to bt_le_per_adv_set_data(). You can do so as fast or as slow as you like, but the HCI messages that are sent from the controller to the Bluetooth Low Energy stack can max hold 252 bytes (of payload). 

    So you can try to update the data in chunks of 252 bytes, and iterate through the entire advertising data set. 

    Best regards,

    Edvin

  • Thank you so much Edvin, I will try changing the data through multiple calls to the API as you suggested. 

Related