This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Missing BLE_GATTS_EVT_HVN_TX_COMPLETE events

Our BLE peripheral uses a custom GATT service similar to the NUS (Nordic UART service) used in the SDK example app_ble_uart. The peripheral receives data on the UART peripheral (not UARTE) from an external device at 115200 baud with full hardware handshaking.

Our PDU data length is configured as 251 and our MTU size as 247.
The peripheral repeatedly calls sd_ble_gatts_hvx with a 244 byte ATT data packet but we only receive 4 BLE_GATTS_EVT_HVN_TX_COMPLETE events.

You can see on the oscilloscope screenshot below that we have called sd_ble_gatts_hvx 11 times (SD_SEND) but have only received TX_COMPLETE 4 times. We keep track of the number of notifications available to us so we no longer try to send after calling sd_ble_gatts_hvx 7 times since the last TX_COMPLETE event.

We are outputting any errors returned by the sd_ble_gatts_hvx call using a spare GPIO line (SD_SEND_ERR) and you can see that there are none.

We have tried keeping the PDU data length configured as 251 and our MTU size as 247, but calling sd_ble_gatts_hvx with 200 byte data payload instead and this has resolved the issue.

So the main question is why do we stop receiving the BLE_GATTS_EVT_HVN_TX_COMPLETE event when we use the maximum payload size?

More detailed setup information:

BLE peripheral = nrf52 dev kit (PCA10040).
BLE central = custom hardware using nrf52832.

We are using the S132 SoftDevice v 7.0.1.
We are not using the nRF SDK driver or HAL layers – we’re interfacing with the peripherals directly, but the chip header files we’re using are taken from SDK version 15.2.

BLE connection parameters:

Connection interval 7.5ms
Event length 7.5ms
Slave latency 0.
Connection supervisory timeout 1s.
Extended event length enabled.

MTU size 247
PDU data length 251
BLE notifications queue size (hvn_tx_queue_size) 7

Happy to provide more information if needed.

Parents
  • Hi,

    There is not a one-to-one mapping between the number of Tx packets and the number of BLE_GATTS_EVT_HVN_TX_COMPLETE. This is because the event comes with a count field, which can be more than 1. I suspect that is the case here.

  • Hi Einar, thanks for your response. 

    We take the count into account when tracking the number of available buffers.

    Here is our event handler:

    __STATIC_INLINE void fnOnNotificationComplete(const uint16_t conn_handle, ble_evt_t const * p_ble_evt)
    {
        ble_gatts_evt_hvn_tx_complete_t const * p_evt_complete = &p_ble_evt->evt.gatts_evt.params.hvn_tx_complete;
        guNotifyBuffersAvailable += p_evt_complete->count; // increase available buffers for notifications by the number of completed
    }

    And we then decrement guNotifyBuffersAvailable each time we call 'sd_ble_gatts_hvx'.

  • The cases covered are:


    NRF_SUCCESS: (just break if we get this)
    BLE_ERROR_INVALID_CONN_HANDLE:
    NRF_ERROR_INVALID_STATE:
    NRF_ERROR_INVALID_ADDR:
    NRF_ERROR_INVALID_PARAM:
    BLE_ERROR_INVALID_ATTR_HANDLE:
    BLE_ERROR_GATTS_INVALID_ATTR_TYPE:
    NRF_ERROR_NOT_FOUND:
    NRF_ERROR_FORBIDDEN:
    NRF_ERROR_DATA_SIZE:
    NRF_ERROR_BUSY:
    BLE_ERROR_GATTS_SYS_ATTR_MISSING:
    NRF_ERROR_RESOURCES:
    NRF_ERROR_TIMEOUT:

    ... but you're right, I've missed out the default case so I'll re-run that test in a minute and get back to you.

    I've attached the Wireshark trace file for you:

    /cfs-file/__key/communityserver-discussions-components-files/4/RetranmissionIssues.pcapng

  • Hi Einar, I have now re-run the test with the default case and was able to re-produce the same result.
    Please see below:

    Associated Wireshark capture:

    /cfs-file/__key/communityserver-discussions-components-files/4/RetranmissionIssues2.pcapng

  • Hi Mark,

    I am not able to explain this. Before looking at your sniffer trace I wanted to suggest that perhaps you have an issue with interrupt priorities or similar in your application (waiting for events in a higher priority than the event, so that it is never serviced).

    But looking at the sniffer trace it looks at bit odd. From #14379 and for the rest of the trace (41 seconds) there is an endless stream of retransmissions. Which is odd in itself, but even more so since it continues for this long (the GATT timeout is 30 seconds). What is the BLE master you are communicating with?

    Einar

  • Hi Einar,

    That's a good point with respect to the GATT timeout.
    Thanks for looking into this further for us.

    I've attached our BLE master project for reference:
    /cfs-file/__key/communityserver-discussions-components-files/4/6864.central.zip

    Mark

  • Hi  Mark,

    To be honest it is the same all over the trace. Looking at the sniffer trace there is a lot of retransmissions. So much that I don't know if the trace makes sense. Have you had your HW properly tuned? Can you test with DK's on both sides so that we know you are using proper HW?

    It may be that you don't get BLE_GATTS_EVT_HVN_TX_COMPLETE events because you don't get data through. And you don't get errors from your call to sd_ble_gatts_hvx() because you stop calling git when the buffer is full (since packets are not successfully sent, even though you do get some data through).

    As mentioned it would be good to test this on knowing good HW. And if that doe snot help, then It would be interesting to see all of your code.

    Einar

Reply
  • Hi  Mark,

    To be honest it is the same all over the trace. Looking at the sniffer trace there is a lot of retransmissions. So much that I don't know if the trace makes sense. Have you had your HW properly tuned? Can you test with DK's on both sides so that we know you are using proper HW?

    It may be that you don't get BLE_GATTS_EVT_HVN_TX_COMPLETE events because you don't get data through. And you don't get errors from your call to sd_ble_gatts_hvx() because you stop calling git when the buffer is full (since packets are not successfully sent, even though you do get some data through).

    As mentioned it would be good to test this on knowing good HW. And if that doe snot help, then It would be interesting to see all of your code.

    Einar

Children
  • Hi Einar,

    We are using the nRF52832 chip inside the ISP1507 SoC, so we have no radio or low-level hardware design of our own.

    The central device consists of a ISP1507 connected to an FT2330XS-R USB UART bridge, with a local 3V3 PSU. There is no other circuitry.

    Is this the hardware configuration you'd expect?

    Is there anything in the code that looks particularly suspicious to you?

    If we're not getting data through over the radio after the GATT timeout / supervisory timeout then why would the BLE link not drop (we are handling BLE_GAP_EVT_DISCONNECTED)?

    Mark

  • Hi Mark,

    Mark Dale said:

    We are using the nRF52832 chip inside the ISP1507 SoC, so we have no radio or low-level hardware design of our own.

    The central device consists of a ISP1507 connected to an FT2330XS-R USB UART bridge, with a local 3V3 PSU. There is no other circuitry.

    I see. There should not be any problems using the ISP1507.

    Mark Dale said:
    Is there anything in the code that looks particularly suspicious to you?

    I am having problems understanding what could be the problem here.  Would it be possible to share your complete project, so that I can get a better overview? Also, is it possible to modify it to run on the DK, so that I can test on my side (using two DK's, one for central and one for peripheral)?

    Mark Dale said:
    If we're not getting data through over the radio after the GATT timeout / supervisory timeout then why would the BLE link not drop (we are handling BLE_GAP_EVT_DISCONNECTED)?

    You are right, you will get a disconnect if no packets make it through for the duration of the supervision timeout. And if there is only a problem on the GATT layer, you will get a timeout there as well.

    Einar

  • Hi Einar,

    Here are the central and peripheral binaries that can be run on two DK's. 

    Central:

    /cfs-file/__key/communityserver-discussions-components-files/4/deployment.hex

    Peripheral (sends 200 bytes ATT payload):

    /cfs-file/__key/communityserver-discussions-components-files/4/deployment.hex

    Peripheral (sends 244 bytes ATT payload):

    /cfs-file/__key/communityserver-discussions-components-files/4/deployment.hex

    The central will automatically connect to the peripheral.
    Any data received by the peripheral over UART will then be sent over the air to the central.
    You should be able to recreate the issue we're seeing with these.

    I'm happy to provide the complete project, but would rather not upload it all here.

    Thanks,
    Mark

  • To clarify, you should already be able to build and run the central side from the project I uploaded previously as there are no I/O changes required for deployment on the development kit.

    When peeking the event length on calling sd_ble_evt_get() I've observed that the event length is always 16 bytes more than the maximum MTU size...
    and I've confirmed that my application works with an MTU size of 231 bytes (247 - 16) but not 232.

    I was using the 'BLE_EVT_LEN_MAX' macro defined in the SDK to calculate the evt_buffer length and this sets the event buffer size to be 247. 

    If I set this event buffer size to 263 (247 + 16) then I am then able to set the ATT data payload to 244 and my application works successfully.

    Why does the event buffer size need to be 16 bytes larger than the event size?

    Thanks,
    Mark

  • Hi Mark,

    Can you upload the files again? There is a bug in this forum which makes uploading a file with the same name as another file in the same thread causes it to get overwritten. So all three files are the same.

    Can you also upload the full projects, so that I can see what you have done in more detail (and if I need to debug on my side)?

Related