BLE Packet retransmission at link layer

Hi,

We are seeing some odd behavior when running in the peripheral role connected to a central device.  Occasionally, it appears the central device needs to retransmit a packet done at the Bluetooth level, not application level.  From our captured sniffer trace, the retransmission occurs because no acknowledgement is sent by the peripheral.  The application running as peripheral, however, ends up processing both the original packet and the re-transmitted packet.  This particular behavior we have observed running the SDK 15.3 on an nrf53832 processor but we are also running an nrf5340 processor with the nrf Connect SDK v2.4.x.

Our questions are as follows:


1) When does the BLE stack release a received packet over the air to the application?  Does it actually delay one connection interval to release the packet confirming the peripheral ACK?

2) Do the SDK 15.3 and nrf Connect SDK provide a method to indicate the packet is a retransmitted packet or even an unacknowledged packet?

Below is a sniffer capture of the re-transmission.  I'm assuming it re-transmitted because the peripheral does not appear to have ACKd the packet.

Thank you.

Parents
  • Hello,

    Can you please upload the sniffer trace? (.pcapng format)

    Packet loss is normal, and the Bluetooth stack handles this for you. 

    It would be easier to tell what the case is if I had the actual sniffer trace, but it looks like the packet 12114 is a retransmission, meaning either the peripheral lost packet 12113, or the central and sniffer lost the reply (containing the ACK) from the peripheral.

    Since the sniffer doesn't contain a reply from the peripheral, and the central seems to be sending the same packet again (retransmission), I guess the packet was never received correctly by the peripheral, so it will not be handled twice.

    But there could also be a case where the peripheral picks up the packet from the central, the peripheral sends a reply (containing the ACK), and the central doesn't pick up the reply correctly. In that case, the central will also retransmit the last message because of the lack of an ACK. But the Bluetooth stack will handle this as well, so that it doesn't seem like the application on the central sent the same packet two times. 

    Are you in fact seeing that the application on the peripheral receives two identical messages? Or do you just want to make sure that this doesn't happen?

    Best regards,

    Edvin

  • Hi Edvin,

    It appears that the application on the peripheral receives two identical messages.  However, the sniffer doesn't pick up the ACK to the first transmission.  As you stated above, the peripheral could send a reply but the central doesn't pick it up.  Does this mean the BLE stack releases received packets to the application layer one connection interval later from when it's ACK'd?

    Thanks,
    Kurt

     badlogdata.pcapng

  • It is indeed a retransmission. If you look at the Sequence Number (SN) and Next Expected Sequence Number (NESN):

    You can see that the SN on 12113 and 12114 are the same, meaning it is in fact a retransmission. The NESN is also 0 in both these cases, meaning it expects the peripheral's SN to be 0 in two packets in a row, meaning it didn't receive any packets between these two.

    kpreiss said:

    Does this mean the BLE stack releases received packets to the application layer one connection interval later from when it's ACK'd?

    If so, then this is a bug. Is there any way for me to reproduce what you are seeing? Do you have a peripheral and central application I can run on 2x nRF52 DKs that will replicate the double message issue that you are seeing in your peripheral application?

    Best regard,

    Edvin

  • I don't have anything that runs on a DK board to reproduce the issue.  This issue is occurring on custom hardware while connected to a phone (mfg?). However, is it your understanding that the stack should not release a packet that has not been ACK'd (i.e. all packets released by the stack are ACK'd packets)? 

Reply Children
  • Yes. Packets that are not ACKed are kept in the stack until they are ACKed. 

    If a device transmits a packet it will only delete the content of a packet once it is ACKed, or if the link is disconnected. 

    If you are the receiver of a packet, the application will be presented the packet when it is received. If the transmitter didn't receive the ACK, then it will retransmit that ACK on the next connection event (the events that occur every connection interval). I have not seen reports that there is a bug that the packets are presented to the application twice when there is a retransmission involved, and seeing as this is fairly old, I would be surprised if this surfaces now.

    How do you determine that a packet is received twice? Was it the case with packet 12114 in your sniffer trace? Or could it be that the payload of another packet was accidentally queued up twice from the central application?

    Best regards,

    Edvin

  • Hi Edvin,

    We use a command response protocol so we see two responses being transmitted back to the central, one for the initial packet (*line 12128 ) and another for the retransmitted packet (line 12130).  It's very possible there is a problem with how we're reading the data out of the BLE stack.  However, I was trying to understand how the stack releases re-transmitted packets to the application layer.  Does the below diagram make sense?

  • The arrow in your diagram does not make sense.

    In the first connection event, the peripheral presents a received packet from the central immediately to its upper layer. An ACK is then sent immediately (after exactly 150 µs) to the central. The central may or may not receive this.

    In the next connection event, the central will retransmit the previous packet if it did not receive an ACK. If the peripheral received the same packet previously (i.e. it detects it is a retransmit), it will not deliver the packet to its upper layer. If it has not seen this packet before, it will deliver it to its upper layer. An ACK is then sent immediately (after 150 µs). The central may or may not receive this.

    As soon as the central receives an ACK, it will release/free the buffer held for this packet, and move on to sending the next packet in the queue (or an empty packet, if empty).

    I have very hard to see that the issue you have would be due to a bluetooth stack bug in the logic above, as retransmissions are extremely common and this would have been caught during testing. There is probably some other issue with the code you have, maybe that you unintentionally send your notification packet from the peripheral twice due to some other reason?

  • Thanks for clarifying that Emil!  That makes perfect sense. 

Related