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

Notifications: How to know who is consuming tx buffers, most efficient way of sending a sequence, what error conditions are received?

I am going to send a sequence of notifications and the documentation provides this information

The API functions that may consume an application packet depending on the parameters supplied to them can be found below:

I am not using the SDK but just SoftDevice (s130 at the moment). What is not clear from the docs is if some of the SoftDevice calls I make, in turn, make calls to sd_ble_l2cap_tx() that I don't know about. It appears to me unlikely that any of the SoftDevice APIs would themselves call sd_ble_gatts_hvx(); that is something only my application is likely to do. So are there 'hidden' sd_ble_l2cap_tx() calls being made or can I safely assume that if my application does not call the method, that the method is never called?

I am trying to figure out the most efficient way to send a sequence of notifications. The documentation suggests two approaches - keeping track of the guaranteed available buffers (fairly involved) or just sending, and if one gets a BLE_ERROR_NO_TX_PACKETS error wait for the BLE_EVT_TX_COMPLETE event.

Related to this question is the error NRF_ERROR_BUSY response. For notifications will that error message ever happen or will I just get a BLE_ERROR_NO_TX_PACKETS error? If I can get both, what is the difference, and how should I behave in the two different cases? With indications the NRF_ERROR_BUSY means call again, or that packet will not get indicated! If notifications can cause that error, then I assume the behavior is the same?

If I chose to notify and always wait for the BLE_EVT_TX_COMPLETE event before the next notification, will this be less efficient? (It is programmatically simpler.)

Parents
  • The softdevice will try to send packets as fast possible, depending on the connection parameters, peer capabilities, other procedures, and packet loss. The simplest may be to have an app_timer that run slightly faster than the connection interval, and just write sd_ble_gatts_hvx() until you receive an error code from the timeout handler. It is also possible to wait for BLE_EVT_TX_COMPLETE before calling sd_ble_gatts_hvx(), however that presumes you have called sd_ble_gatts_hvx() previously, else the BLE_EVT_TX_COMPLETE is not triggered. But both can work.

    The NRF_ERROR_BUSY may happen if you are sending indications (not notifications).

  • I did an experiment where I changed indications to notifications and in all cases the data transfer was slower with notifications. I am trying to understand why.

    In my case I have a long characteristic of 90 or so bytes that are either indicated one after the other or notified one after the other. When using indications I indicated one hunk (MTU = min size 23) waited for the Indication done event, BLE_GATTS_EVT_HVC, and indicated the next hunk and so on. In the notification case the procedure was the same except I waited for the BLE_EVT_TX_COMPLETE event before sending the next notification.

    The wait procedure was the same in both cases, sd_app_evt_wait() and then on wake up do the sd_ble_evt_get() loop. All this was done in the main thread.

    Its not the greatest test given the size of data indicated or notified was not that big, but in all cases the indication case was faster; completely unexpected. Is that some fluke about the handling of the TX buffers that makes it slower?

  • Typically an on-air sniffer log, such as nRF sniffer, may be helpful to find what may be the limiting the throughput.

    Kenneth

Reply Children
Related