central_uart example, how to get Write Response packet?

Hi,

NCS v2.6.0

nRF52 DK

central_uart send packet to peripheral_uart, then peripheral_uart send write response packet to central_uart.

How to get the write response packet in central_uart callback function? I have a large data to send from central_uart to peripheral_uart,

I want to send the first packet from central, then received the write response from peripheral to make sure the packet was received by peripheral, and then send the next packet from central.

There is a similar thread, but it doesn't answer my question.

 Is there response from peripheral_uart after central_uart write rx characteristic 

Parents
  • Hello,

    Just to clarify before digging into this. All packets are retransmitted until they are ACKed in Bluetooth Low Energy. So either the packet is ACKed, or the connection is lost. All packets (from peripheral and central) have a CRC, and if this is incorrect, then it will tell the other device to retransmit that packet. If no packets are received with the correct CRC within the connection supervision timeout period, the link is disconnected. 

    So the typical (and most effective, if you consider data throughput) is to just queue up as many packets as you can. What I used to say in the old SDK is to use the ACK event as a trigger to queue more packets. In the central_uart sample, this would be the ble_data_sent() callback in main.c. This is triggered from the on_sent() callback in nus_client.c, which is triggered when a packet is ACKed. You can even see the bt_gatt_write_params *params in the callback, to determine which packet that was acked. In turn, this is all triggered from the gatt_write_rsp() in gatt.c. 

    Best regards,

    Edvin

Reply
  • Hello,

    Just to clarify before digging into this. All packets are retransmitted until they are ACKed in Bluetooth Low Energy. So either the packet is ACKed, or the connection is lost. All packets (from peripheral and central) have a CRC, and if this is incorrect, then it will tell the other device to retransmit that packet. If no packets are received with the correct CRC within the connection supervision timeout period, the link is disconnected. 

    So the typical (and most effective, if you consider data throughput) is to just queue up as many packets as you can. What I used to say in the old SDK is to use the ACK event as a trigger to queue more packets. In the central_uart sample, this would be the ble_data_sent() callback in main.c. This is triggered from the on_sent() callback in nus_client.c, which is triggered when a packet is ACKed. You can even see the bt_gatt_write_params *params in the callback, to determine which packet that was acked. In turn, this is all triggered from the gatt_write_rsp() in gatt.c. 

    Best regards,

    Edvin

Children
  • Hi,

    Thanks for your info.

    I have a 2MB binary file need to send from central to peripheral, and need to guarantee the 100% receive and optimize the throughput. I send the first packet and wait for the callback function ble_data_sent() to receive ACK, then send the next packet to peripheral, and repeat until the end of the binary file.

    Is there a better solution? 

  • Sounds good, but what I was trying to say was that you can queue multiple packets at once. Queue until it stops returning 0. Then use the ACK callback to queue even more packets. This way, if the softdevice controller finds out that is has time for it, it may send multiple packets within the same connection interval, which will increase your payload throughput. 

    If the speed is not that important, it is perfectly fine to wait for the ACK before you queue the next packet. 

    Either way, there is no risk of loosing packets, and the packets will arrive in the same order as you queued them. The Bluetooth Low Energy protocol will take care of this for you. 

    Best regards,

    Edvin

Related