I've just found through some trial and error that SoftDevice (s130 at least) on the nRF51 DK handles a sequence of notifications in the following manner:
- call sd_ble_gatts_hvx() with the data to be notified
- if the call returns NRF_SUCCESS then send the next part of the data in the sequence
- each time you call the sd_ble_gatts_hvx() method with an NRF_SUCCESS increment a counter by one
- if one gets a BLE_ERROR_NO_TX_PACKETS then that attempt to send will have to be redone and one has to wait for the BLE_GATTS_EVT_HVN_TX_COMPLETE event before trying again.
- Meanwhile in the BLE_GATTS_EVT_HVN_TX_COMPLETE event handler decrement the counter by p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count given in the event
- When the counter decrements to 0 and there is no more to notify, you are done and can proceed to whatever you are doing next.
The interesting thing in this sequence, is that there is an asymmetry in the calls to sd_ble_gatts_hvx() and the number of BLE_GATTS_EVT_HVN_TX_COMPLETE events. All one can say is that the number of calls to sd_ble_gatts_hvx() >= BLE_GATTS_EVT_HVN_TX_COMPLETE.
Okay, that's fine and dandy for the on chip-code, but how does one do this in the pc-ble-driver? Does it work in the same way? Is there the same type of asymmetry where sd_ble_gatts_hvx() >= BLE_GATTS_EVT_HVN_TX_COMPLETE.? Since the pc-ble-driver does not support the sd_app_evt_wait() like it does in the on-chip version, I do not have the same control over the flow as I do on the chip so I have to come up with an equivalent.
For indications where there is a one-to-one relationship between calls and events, a semaphore is an easy and perfect solution. But notifications do not have that symmetry.
If I were to call a sem_wait() when I get a BLE_ERROR_NO_TX_PACKETS and then do a post_sem when I get enough BLE_GATTS_EVT_HVN_TX_COMPLETE events such that the counter is down to 0 would that work? Or are buffers available as soon as the first BLE_GATTS_EVT_HVN_TX_COMPLETE event is received even though the count value returned is only one? How much would it slow down the transfer by waiting for the count to decrement to 0 before calling the sem_post()?
For example say I make 6 calls to sd_ble_gatts_hvx() before I get BLE_ERROR_NO_TX_PACKETS. However, say I fot one BLE_GATTS_EVT_HVN_TX_COMPLETE event before I made my 6th call and got the NO_TX_PACKETs error, so counter is 5. At this point I do a sem_wait().
In the BLE_GATTS_EVT_HVN_TX_COMPLETE event handler should I wait for all events to be received (counter down to 0) before calling sem_post() to continue OR should I continue as soon as I get the first BLE_GATTS_EVT_HVN_TX_COMPLETE event?
I do not know what is goin on under the hood so I have no idea how fast the BLE_GATTS_EVT_HVN_TX_COMPLETE events come relative to the sd_ble_gatts_hvx() calls. Experience on the chip shows that events come with a noticeable delay. But I never had something big like a waveform where I may have to notify a sequence 1000 bytes in 20-byte hunks as fast as I can.
The selection of tags is missing pc-ble-driver. Doesn't that seem like a major miss?