This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Change queue length of Handle Value Notifications? SDK 15.3.0

I am developing an application that sends an image with BLE to an android phone. It is remarkable similar to the Image transfer demo (https://github.com/NordicPlayground/nrf52-ble-image-transfer-demo), except with SDK 15.3.0. The code I have written calls sd_ble_gatts_hvx to write packets until a NRF_ERROR_RESOURCES is returned, and then I wait for a BLE_GATTS_EVT_HVN_TX_COMPLETE event which starts the next set of writes. 

The SoftDevice online documentation for sd_ble_gatts_hvx corroborates this, but the documentation also claims that the queue size can be configured. 


The number of Handle Value Notifications that can be queued is configured by 
ble_gatts_conn_cfg_t::hvn_tx_queue_size When the queue is full, the function call will return NRF_ERROR_RESOURCES. A BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete.

As far as I can tell this is out of date. All the links send me to older versions of the documentation. And to be honest the online documentation is a nightmare to navigate. Does this structure no longer exist? What's the deal? Is there any way to change the hvn tx queue size?

  • I didn't quite understand  what links that you refer to that are referring to older versions of the documentation. Can you please specify?

    Throughput in BLE is a bit complex. But is there a reason why you want to increase this queue size? I have not tested it before, but as long as you make sure you have sufficient MTU (set it to 247, and the softdevice should negotiate to the maximum given by the connected device).

    You may try to increase the queue size, but that won't give any higher throughput. 

    BR,
    Edvin

  • Well first of all I would pose a challenge to you to find the reference info for the ble gatts functions in the online documentation. https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.3.0%2Findex.html 

    More specifically the page that references sd_ble_gatts_hvx, I've been able to find this page that references the function: 

    https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.3.0%2Fgroup__ble__gatts__app.html

    but you can see there the link goes to the 6.1.0 version of the documentation. 

        But is there a reason why you want to increase this queue size?

    Because the documentation implies it is possible? Do I need a reason to do something the documentation says is possible? If you really need to know why it is because we have a flash chip that we are reading data out of and the reads are relatively slow compared to the BLE transfer and I would like to be reading the flash while the hvx transmissions are occuring. Since we are bottlenecked by the flash read and not the hvx transmissions, a larger hvx queue size would allow for less waiting around. 

    I also found this reference in ble_gatts.h in the comments for sd_ble_gatts_hvx

    * @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size

    But I can not find this ble_gatts_conn_cfg_t struct anywhere in the softdevice library. 

     

  • csulz said:
    Because the documentation implies it is possible? Do I need a reason to do something the documentation says is possible? If you really need to know why it is because we have a flash chip that we are reading data out of and the reads are relatively slow compared to the BLE transfer and I would like to be reading the flash while the hvx transmissions are occuring. Since we are bottlenecked by the flash read and not the hvx transmissions, a larger hvx queue size would allow for less waiting around. 

     Hehe! Ok. The reason I asked is because in most cases with questions like this, the reason behind it is that the user thinks this is how to increase the throughput of a BLE link, while it in many cases is not the solution. 

    Trust me, I am trying to help you here, but the first link you provided doesn't contain any gatts function references. Did you mean gattc functions? I know that infocenter is a bit weird on links, because the URL doesn't update when you click links, and the URL doesn't always work if you copy it from your browser either. I have found the easiest method is to right click the link you want to copy and select "copy link".

    So I'll assume that you actually refer to the gatts functions. They are listed in the softdevice section. The second link that you provided is a link to the serialization library in the SDKs. I don't think this is what you are looking for. Also, I am sorry, but I don't know what softdevice or nRF chip you are using, so I'll use the S140 for the nRF52840 as a reference. (this is my best guess, based on your other ticket with USB DFU), and I'll use S140 v 6.1.1, based on your link to SDK15.3.0.

    You will find the link in:

    nRF52 Series ->  SoftDevices -> S140 SoftDevice -> S140 SoftDevice v6.1.1 API -> API Reference -> Generic Attribute Profile (GATT) Server -> Functions -> sd_ble_gatts_hvx()

    ble_conn_cfg_t is used in ble_conn_cfg_t, which can be used in sd_ble_cfg_set(). 

    If you look at the examples (I used ble_app_uart from SDK17 as a reference), in main.c -> ble_stack_init() -> nrf_sdh_ble_default_cfg_set() there is a section:

    #if (NRF_SDH_BLE_TOTAL_LINK_COUNT != 0)
        // Configure the connection count.
        memset(&ble_cfg, 0, sizeof(ble_cfg));
        ble_cfg.conn_cfg.conn_cfg_tag                     = conn_cfg_tag;
        ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count   = NRF_SDH_BLE_TOTAL_LINK_COUNT;
        ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = NRF_SDH_BLE_GAP_EVENT_LENGTH;
    
        ret_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, *p_ram_start);
        if (ret_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_CONN_CFG_GAP.",
                          nrf_strerror_get(ret_code));
        }

    Try to add the following directly after, but before the rest of the function:

        ble_cfg.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = 4;
        ret_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_cfg, *p_ram_start);
        if (ret_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_CONN_CFG_GATTS.", nrf_strerror_get(ret_code));
        }

    In this case, that should allow you to queue 4 times the MTU of the service you are using, meaning you can queue up more packets.

    Best regards,

    Edvin

  • Hi Edvin, I have a similar question and I came across this other post that seems to recommend a different solution, and I'd like to better understand the difference: https://devzone.nordicsemi.com/f/nordic-q-a/28616/how-to-set-the-queue-size-of-notification

    That answer implies that if the GAP event length is long enough and ble_common_opt_conn_evt_ext_t is enabled (which appears to be enabled by default, despite the documentation saying otherwise), more notifications can be queued up regardless of the hvn_tx_queue_size value, and the soft device just handles it automatically. Your answer implies that making the queue longer will allow the same thing. Are they both valid ways of doing the same thing, or are there some differences between those two methods?

    Thanks!

  • They are a bit different, but both will do that. The event length extension will allow for larger packets, and hence it will increase the queue size, while setting the queue size directly will also do that. Regardless, the queue size is only that, a queue, while the connection event length will affect the actual throughput of the connection.

    There are many devzone tickets regarding this topic, and I guess it is a bit random that you found this one exactly. If you have general questions regarding the queue size, I suggest that you create a new ticket where you ask those questions.

    Best regards,

    Edvin

Related