Chaining - current status

Hallo,

currently I evaluate a few possibilities to transmit larger data portions in a broadcast way, means using several advertising schemes. I have a few nRF52840-DK and use NCS v1.9.1 and Zephyr v2.7.99.

One at least semi-automatic way to handle data portions bigger than what is possible to transmit in a single packet is chaining. According to the standard it should be possible to transmit up to 1650 Bytes, which will be automatically splitted and re-assembled.

In one of the posts (https://devzone.nordicsemi.com/f/nordic-q-a/80022/chained-advertisement-nordic-52832-or-52840-how-to-generate-the-chained-advertisement-with-the-nrf-connect-sdk) I found the statement that chaining was not yet implemented, but "the feature to add more than 255 bytes is still on its way". Since it is more than a year after the statement I would like to know what the current situation is. At least the struct bt_data - used in bt_le_ext_adv_set_data(..) to handle advertising data - still contains a uint8_t variable data_len, which means there is a max size of 255. Therefore I assume that chaining is still not implemented. Is that correct?

Kind regards

Axel

Parents
  • Hello Axel,

    I am happy to inform you that chaining periodic advertisements is indeed now supported in the SoftDevice controller.
    You will need to change the config for the data length to reflect the increased data length, for example:

    CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=1650

    Additionally, you are correct that there is a limitation on the ad structures to contain more than 255 bytes, but the solution to this is to use multiple ad structures, like this:
    static const struct bt_data ad[] = {
        BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 200),
        BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 200),
        BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 200),
        BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 200)
    };


    To quickly test this I would recommend starting out by modifying the periodic advertising sample to include this functionality.
    Try this, and let me know in the case that you run into any issues or additional questions - please do not hesitate to ask! :) 

    Best regards,
    Karl
  • Hallo Karl,

    thanks for this info - I'll test it. But I have a few more related questions:

    - The still existing limitation to 255 bytes (uint8_t for length) and the resulting workaround (array of bt_data elements) means in the end that the chaining intention of the standard - I can come up with a bigger portion of data and the stack manages the chaining - is not fully reached. I assume that the reception side will connect all the parts (it does so in first tests with bt_data of up to 255 bytes), but on transmission side it's up to me to do the split. But when testing with a single bt_data of up to 255 byte, one can see that the stack is able to manage the split. Up to 249 bytes there is only one data frame of "normal" extended advertising, and for 250 bytes or more there is one frame with 246 byte and a second chaining frame with the remaining bytes of data. So it seems "only" the length issue (uint8_t), what limits the function of the chaining, but I can imagine that changing this point is not that easy as it seems. Will there be some more work on that issue in the future to meat the intentions?

    - In your code example the length of each bt_data is 200. The maximum here is 246 (see above) - correct?

    - pure curiosity, and maybe you know some details: The standard mentions a max size for chaining of 1650 bytes. Where does this number come from? As far as I can see there is absolutely no connection to frame sizes or something else, what could lead in a mathematical way to 1650. Assuming a max data size per chaining frame of 246 bytes, the last one will contain 174 bytes only - 72 less than possible. So WHY this 1650 bytes???

  • Hello,

    Regarding the first question; apart from having to create a convenience function that splits the data into arrays of bt_data there is no other overhead on either side of the link, so the intention of the chained advertising is still met - it is just that you have to package the data before updating the advertising.

    axel_s said:
    - In your code example the length of each bt_data is 200. The maximum here is 246 (see above) - correct?

    Yes, this is due to the overhead (2 bytes) used for each separate datafield in the advertisements, in addition to the chained advertising metadata.

    axel_s said:
    So WHY this 1650 bytes???

    That is an excellent question, but I unfortunately do not have any good answer for it as it stands.. I will ask some of my colleagues and see if they know the reason for it being exactly 1650, and I'll update you here if I find a good answer to it! :)

    Best regards,
    Karl

  • Hallo Karl,

    thanks for the information - I'm looking forward to your findings regarding the ominous 1650.

    In terms of the data handling, you are right, the effort is not huge. But in an overall view there is a difference in data handling on transmission and reception side - on transmission side I have to package the data, on reception side the stack will do the job. And the stack in general can handle this issue also on transmission side, as a simple example with 255 bytes can show. Such a discrepancy is not a good point, that's why I would prefer to have the stack doing it.

    Or is my assumption regarding the reception side wrong and the stack leaves to that point also on reception side to the programmer? In that case there would be no discrepancy.

    Kind regards

    Axel

Reply
  • Hallo Karl,

    thanks for the information - I'm looking forward to your findings regarding the ominous 1650.

    In terms of the data handling, you are right, the effort is not huge. But in an overall view there is a difference in data handling on transmission and reception side - on transmission side I have to package the data, on reception side the stack will do the job. And the stack in general can handle this issue also on transmission side, as a simple example with 255 bytes can show. Such a discrepancy is not a good point, that's why I would prefer to have the stack doing it.

    Or is my assumption regarding the reception side wrong and the stack leaves to that point also on reception side to the programmer? In that case there would be no discrepancy.

    Kind regards

    Axel

Children
No Data
Related