"Unable to allocate TX context" at the beginning of a stream

Hi,

In my system I have a timer that ticks at 1kHz frequency, collects some data and sends it over BLE via bt_nus_send. It works fine, but in the beginning of the stream for the first few messages I get the following in the debug log:

[00:00:16.970,672] <err> bt_conn: Unable to allocate TX context
[00:00:16.970,672] <wrn> ble_bsp: Failed to send data over BLE connection. bt_nus_send return value = -105
[00:00:16.972,656] <err> bt_conn: Unable to allocate TX context
[00:00:16.972,686] <wrn> ble_bsp: Failed to send data over BLE connection. bt_nus_send return value = -105
[00:00:16.973,663] <err> bt_conn: Unable to allocate TX context
[00:00:16.973,663] <wrn> ble_bsp: Failed to send data over BLE connection. bt_nus_send return value = -105
[00:00:16.975,860] <err> bt_conn: Unable to allocate TX context
[00:00:16.975,860] <wrn> ble_bsp: Failed to send data over BLE connection. bt_nus_send return value = -105
[00:00:16.983,093] <err> bt_conn: Unable to allocate TX context
[00:00:16.983,123] <wrn> ble_bsp: Failed to send data over BLE connection. bt_nus_send return value = -105
[00:00:21.978,057] <wrn> bt_att: Not connected
[00:00:21.978,088] <wrn> ble_bsp: Failed to send data over BLE connection. bt_nus_send return value = -128
[00:00:21.978,302] <wrn> bt_att: Not connected
[00:00:21.978,302] <wrn> ble_bsp: Failed to send data over BLE connection. bt_nus_send return value = -22

After those few drops, it works fine.

My question is, is there any concrete explanation to why this is the case?

Additional info:

  • NRF Connect SDK: v1.8.0 and v1.9.1 were used, there was no difference between them
  • nrf52840 dongle is used to communicate with nrf5340 dev board, where the dongle is central and nrf5340dk is a nus peripheral
  • PC is running Windows 10, communicating via Blatann library
  • nrf5340's antenna is a few centimeters away from nrf52840 USB dongle

Connection parameters:

  • 7.5ms Conn interval
  • 1ms Slave latency
  • 247 MTU
  • 251 DLE
  • 2M PHY
Parents
  • After you establish a connection, then central and peripheral will start to negotiate the Connection parameters outlined above.

    You should wait until this negotiation is finished before starting to send data. Note this can take upwards of 2-3 seconds.

    Until such time, hold off on making calls to bt_nus_send()

  • That is not the case, on my central I await all of the connection paramater updates before proceeding with stream initiation.

    To further test it out, I put a 5s delay in my central after negotiating the connection paramaters and the results are the same.

  • Hmmm ... who is streaming the data ... the central or the peripheral ?  If the peripheral, then the waiting for end of connection negotiations should occur on the peripheral.

    peripheral uses bt_nus_send(), whereas central uses bt_nus_client_send() ... so from your logs it seems that your Peripheral is streaming the data. 

    Do you have code on the peripheral side to ensure that you do not call bt_nus_send() until all negotiations are complete ? It would be helpful to paste some code to review.

  • The peripheral is streaming the data, but it wont initiate the stream until central tells it to, and central is configured to send that command only after connection parameters are negotiated (+ some additional time)

  • OK, understood now.

    Can you show a bit of code leading up to the bt_nus_send() area ?

    Can you show the Peripheral logs showing connection negotiation, including the receiving the "go ahead" command from the Central, to a short time after the error logs you posted above?

    Helpful if Peripheral outputs logs upon reception/confirmation of the above connection negotiations.

    If you are using security/encryption, you may need to wait for that to complete also.

    In Peripheral code, you should have callbacks for security_changed(), le_param_updated(), le_phy_updated(), le_data_length_updated()

    I couldn't get a callback working for MTU update ( see atu_mtu_notification_callback() ), but you can print it out right after receiving your "go ahead" command from the Central. See bt_gatt_get_mtu(current_conn)

Reply
  • OK, understood now.

    Can you show a bit of code leading up to the bt_nus_send() area ?

    Can you show the Peripheral logs showing connection negotiation, including the receiving the "go ahead" command from the Central, to a short time after the error logs you posted above?

    Helpful if Peripheral outputs logs upon reception/confirmation of the above connection negotiations.

    If you are using security/encryption, you may need to wait for that to complete also.

    In Peripheral code, you should have callbacks for security_changed(), le_param_updated(), le_phy_updated(), le_data_length_updated()

    I couldn't get a callback working for MTU update ( see atu_mtu_notification_callback() ), but you can print it out right after receiving your "go ahead" command from the Central. See bt_gatt_get_mtu(current_conn)

Children
No Data
Related