Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How long does notification data need to be valid?

Hello,

I'm wondering how long do I need to keep the data I want to send alive.

Here's the use case:

My data changed so I need to notify the central. Since the data changed, the current attribute value is invalid and needs to be updated. I build the data on-the-fly using a single global buffer that is shared among multiple characteristics, and then I send that data with sd_ble_gatts_hvx. According to the documentation, this call also updates the attribute value, so I kill two birds with one stone.

My question is whether the hvx_params struct passed to sd_ble_gatts_hvx gets buffered by the softdevice or whether I need to keep it alive until I get a BLE_GATTS_EVT_HVN_TX_COMPLETE event. I haven't had problems so far, but since I am sharing this buffer between multiple characteristics, I am afraid this has the potential to become a bug if the data doesn't get copied by the softdevice.

If the data is not buffered after that call, then I would need to create several buffers or at least a bigger one with offsets in order to make sure that the data I already passed to the sd_ble_gatts_hvx doesn't get overwritten by a new notification on another characteristic.

Thanks for your help. Also, any suggestions on how to approach this in case the softdevice does not buffer the data, are appreciated.

This is, by the way, not documented anywhere as far as I know, and it would be nice to have it in the API calls. I'm using SDK 13.1 and SoftDevice S132 4.0.2.

Parents
  • Hello,

    I have not seen the source code for this part of the softdevice, but as you can see in e.g. the ble_app_uart example, which uses the ble_nus_string_send() function to send text strings, the ble_gatts_hvx_params_t hvx_params is created within this function, and will not be kept once the ble_nus_string_send() function returns. You will notice that if you try to send several times, it can store up several messages in the sending buffer, but it will eventually return NRF_ERROR_RESOURCES, which indicates that the buffer is full. Then you will have to wait for the BLE_GATTS_EVT_HVN_TX_COMPLETE to be able to queue up more strings in the sending buffer.

    So to answer your question, yes, the softdevice copies the data from the hvx_params, so you do not have to keep the data after sd_ble_gatts_hvx has returned NRF_SUCCESS. If it returns NRF_ERROR_RESOURCES, you would want to keep the data for the next BLE_GATTS_EVT_HVN_TX_COMPLETE event, so that you can queue it up in the softdevice again.

    Even if the packet is lost over the air, the softdevice will retransmit it, and does not need the data from the application to do that.

    Best regards,

    Edvin

  • Hi Edvin, thanks for your answer! Good to know that the hvx_params struct gets buffered. I actually just realized that I asked the wrong question: I really didn't mean to ask about the hvx_params struct itself, but rather the data pointed by it. How long do I need to keep it alive?

    If the softdevice only stores the pointer, then ok, I can let the hvx_params struct get out of scope. I want to know how long do I need the data pointed by hvx_params.p_data to be kept alive.

    I see in the example you mentioned that the data buffer is declared static in the UART event handler, and gets overwritten every time you get new data. I'm wondering whether the data itself (the one in the UART event handler data buffer) gets buffered by the SoftDevice, or just the pointer to it. Right now I don't know whether my code works because the SoftDevice buffers the data, or because the data gets transmitted over BLE faster than I can currently overwrite the data in that buffer.

    I hope I made myself a bit clearer now.

Reply
  • Hi Edvin, thanks for your answer! Good to know that the hvx_params struct gets buffered. I actually just realized that I asked the wrong question: I really didn't mean to ask about the hvx_params struct itself, but rather the data pointed by it. How long do I need to keep it alive?

    If the softdevice only stores the pointer, then ok, I can let the hvx_params struct get out of scope. I want to know how long do I need the data pointed by hvx_params.p_data to be kept alive.

    I see in the example you mentioned that the data buffer is declared static in the UART event handler, and gets overwritten every time you get new data. I'm wondering whether the data itself (the one in the UART event handler data buffer) gets buffered by the SoftDevice, or just the pointer to it. Right now I don't know whether my code works because the SoftDevice buffers the data, or because the data gets transmitted over BLE faster than I can currently overwrite the data in that buffer.

    I hope I made myself a bit clearer now.

Children
No Data
Related