cancel
Showing results for 
Search instead for 
Did you mean: 

Wait until BLE notification has been sent

LWChris
Associate III

I basically have this code:

while (...) { // A
  while (BLE_STATUS_INSUFFICIENT_RESOURCES == aci_gatt_update_char_value(...)) { // B
    osDelay(10);
  }
}
 
while (BLE_STATUS_INSUFFICIENT_RESOURCES == aci_gatt_update_char_value(...)) { // C
  osDelay(10);
}

The upper loop (A) is sending sequential notifications to a characteristic (B).

The lower part is sending a final indication to a different characteristic (C).

On the device that has subscribed to the notifications from B and indications from C, the indication from C seems to arrive earlier than the last notifications from B.

In the end, all notifications are received, but the order is off compared to the code. I was expecting the BLE stack to have an internal message queue, meaning the indication would not be processed until the last notification was sent. But this does not seem to be the case.

If B sends 96 notifications, the order I receive may be:

B1, ..., B40, C, B41, ..., B96

Is there any way to ensure C can only be received after B96 was sent, either by delaying the code, checking the remainder of enqueued notifications, receiving an event when the notification was sent (not received, I know notifications aren't acknowledged), reducing a buffer to 1 message to guarantee any call will return with INSUFFICIENT_RESOURCES until the data was sent?

Best regards

Chris

4 REPLIES 4
Scott Löhr
Senior II

It sure sounds like you are working on a heterogenous system, like probably the STM32WB as the server sending these messages and a BLE app on say Android as the client receiving them? It's hard to believe that either side would be promoting an Indication over 40 enqueued Notifications, but stranger things have been seen - perhaps on the client side the task subscribed to the Indication on C is higher priority than the task churning through the Notifications on B? In any case, just start running some experiments to at least divide and conquer (i.e. determine which side is going out-of-order). Some things to try:

  • on the server side, as soon as you get the Char-C Indication Ack, kill the BLE connection - does the client still receive all of the Char-B Notificaitons? If so, then they had been flushed by the server, so the problem is on your client side.
  • on the client side, as soon as you get the Char-C Indication, kill the BLE connection - does it still get all of the Char-B Notifications?
  • if the server is the ST STM32 Nucleo, as I suspect, implement the client side on another Nucleo and at least prove that the ST BLE stack runs in order.

Good luck hunting!

Remy ISSALYS
ST Employee

Hello,

It's preferable to check if the return of aci_gatt_update_char_value function is different that BLE_STATUS_SUCCESS in your while condition because this function can return BLE_STATUS_INSUFFICIENT_RESOURCES or BLE_STATUS_BUSY.

If with this modification nothing change, maybe you have a problem in scheduling.

Best Regards

LWChris
Associate III

@Scott L�hr​ 

You are right with your assumption of the heterogenous system. The BLE app is actually a Windows program I coded for debugging the BLE interface. The problem was probably caused by my logging. In Windows, Notifications are events, and although events are also handled in a scheduler on Windows, I suppose the logging of the notifications may have taken longer time since it was more information, thereby delaying the queue of that event, while the logging of the short indication was quick. A locking mechanism on the logger made sure two different events wouldn't get mixed up, but I should've probably just off-loaded the data into a queue and handled logging in a separate low-prio task. Anyway, when I disable logging, the order of the events seems to be right again. I will probably still buy an USB-attachable BLE Sniffer so I can verify that with certainty in Wireshark.

@Remy ISSALYS​ 

Would checking for "unequal to BLE_STATUS_SUCCESS" bear the risk of hanging the sensor. E. g. could there be some unrecoverable status that will send the while loop into a never-ending infinite looping pattern (e. g. connection loss)?

Remy ISSALYS
ST Employee

Hello,

Yes, it's a possibility but that shouldn't happen maybe you can add a timeout to avoid to be in infinite loop.

Best Regards