This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Acknowledging BLE Notifications and Indications

Other Parts Discussed in Thread: CC2541

I wrote a simple peripheral application using CC2541. The application sends some high-throughput data using Notifications.

I'm still perplexed by retransmission and acknowledgement logic when using BLE Notifications and Indications. Specifically:

  • The BLE specification says that Indications are acknowledged by the GATT layer, while Notifications are not.
  • It also says, (see e.g. TI and others on this), that each and every packet is acknowledged and, if necessary, retransmitted by the Link-Layer.
  • Retransmission will persist until either the packet is acknowledged or the link is dropped. This is true regardless of the transport method (Read / Write / Notification / Indication).
  • While sending sequential data I do experience lost packets from time to time.


Some questions:

  • What happens if I update a Notified Characteristic before it was successfully transmitted (i.e. update the data and call GATTServApp_ProcessCharCfg())? Will the original data be lost?
  • If so, is there a way, other than using Indications, for the application to know if the previous packet was transmitted successfully?

  • Hello,

    If you are experiencing lost packets, it's likely being dropped at the App layer (above GATT).

    You can implement a bi-directional flow control by using another characteristic that the Client updates periodically. A good example is the Serial to BLE Bridge example on the BLE Wiki: processors.wiki.ti.com/.../SerialBLEbridge

    Best wishes
  • Thanks JXS.

    Do you mean at the App layer of the receiving side?

    I'm still interested in knowing what happens if I call GATTServApp_ProcessCharCfg() before the previous value was successfully transmitted though. Can you please elaborate about that?
  • It can be lost at the App layer of either side. For example if no TX buffers are available.

    GATTServApp_ProcessCharCfg() will call GATT_Indication(). If the data is updated after GATT_Indication(), then the previous data will be sent. Essentially, GATT_Indication() enqueues the data in the stack. So long as the return code is SUCCESS and the connection does not drop, then that data will get sent.

    Best wishes
  • Thanks JXS.

    To make sure, please consider the following scenario:

    • I update the value of a notified Char: simpleProfileChar4 = 5;
    • I call GATTServApp_ProcessCharCfg(...) 
    • Before the notification gets sent (either waiting for the next connection event, or retrying), I update again: simpleProfileChar4 = 6
    • ...and I call GATTServApp_ProcessCharCfg(...) again

    Assuming the link is not dropped, and withholding memory issues, will both notified values (5, 6) guaranteed to be transmitted and re-transmitted until they reach the central (or the until link is dropped)?

    Is update order guaranteed as-well?

    BTW, what does  GATT_Notification() do? The inline documentation is unclear to me.

    Thanks again for your help,

    Boaz