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

BLE_ERROR_NO_TX_BUFFERS appears at low signal

Hello,

I've created own characteristic and send it from proprietary board acting as peripheral to the Client in form of notifications. I use sd_ble_gatts_hvx() function for this purpose. I have connectionInterval set to 20ms and a sensor which generates data for characteristic with 50Hz data rate. It means that in general I have 1 new data packet to send per each BLE connection event. And all is working ok when RF signal is strong.

When the RF signal is low (happens when distance is big or objects are between) but the connection is still stable, sd_ble_gatts_hvx() function starts giving me BLE_ERROR_NO_TX_BUFFERS error. When signal restores, all becomes good ok.

It seems like when the signal is low the packet buffer is not released from old packets or some procedure starts sending own packets filling the buffer completely. As the result I can not send any new data packets until signal is good again.

Can someone explain me what is the reason of such strange behavior? Because I thought notifications are to be sent in any case and weak signal would just lead to increased packet loss.

P.S. I am using S110, SDK 10, nRF51822.

Parents
  • It's because at the low signal strength you are losing packets / getting errors on the link and the packets getting lost need to be retransmitted until they get through. The buffers are held until the packets all go through obviously as the data is needed to be retransmitted.

    You're not quite right about notifications. Yes they are unacknowledged and not guaranteed to be sent, or passed along by the receiving end, however the link they go over, the Logical Link layer, is a guaranteed, in order, reliable connection. So once a notification packet gets there, it will be constantly retried until it's sent, in order. The LL is reliable.

    Moreover, Nordic's implementation of notifications also promises that if it accepts a packet for notification (ie doesn't return the buffer full error) it will send it to the link layer and from there it will get to the other side (unless the connection fails totally). ie this implementation doesn't decide, after it's accepted a packet but not yet sent it out on the link layer (at which point the LL protocol requires it be retried until success) it won't later decide to drop it before sending it.

    So all you're seeing is BTLE having to retry lots of times to get packets sent and you have to wait until they are before you can use the buffer.

Reply
  • It's because at the low signal strength you are losing packets / getting errors on the link and the packets getting lost need to be retransmitted until they get through. The buffers are held until the packets all go through obviously as the data is needed to be retransmitted.

    You're not quite right about notifications. Yes they are unacknowledged and not guaranteed to be sent, or passed along by the receiving end, however the link they go over, the Logical Link layer, is a guaranteed, in order, reliable connection. So once a notification packet gets there, it will be constantly retried until it's sent, in order. The LL is reliable.

    Moreover, Nordic's implementation of notifications also promises that if it accepts a packet for notification (ie doesn't return the buffer full error) it will send it to the link layer and from there it will get to the other side (unless the connection fails totally). ie this implementation doesn't decide, after it's accepted a packet but not yet sent it out on the link layer (at which point the LL protocol requires it be retried until success) it won't later decide to drop it before sending it.

    So all you're seeing is BTLE having to retry lots of times to get packets sent and you have to wait until they are before you can use the buffer.

Children
  • Thank's a lot for your reply. Now the situation is much more clear. But in this case is it possible to update somehow the data value in the packet that is already put in the buffer? As due to waiting for Link Layer confirmation the information can become obsolete. Or the only possible way to overcome this is by adding timestemps and process received data correspondingly at the Client side?

  • nope - once it's gone, it's gone. Once the softdevice has it, it's going out as it is, you can't change it. All you can do is use less than all 6 packets you have available and have fewer queued up waiting which are potentially getting older. If for instance you only allowed yourself 2 packets 'in flight' at any one time, you know that at most there's two packets worth of retries before you put an updated one in the buffer to go out. If you're not sending that fast it may not matter that you have 1 or 2 packets per connection interval only.

  • Understood. Thank's.

Related