This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

app_context_load() needs delay before sd_ble_gatts_service_changed()?

Hi:

I'm supporting a nrf52832 project that is using SDK 11 with S132 Softdevice 2.0.0, and would like to get to the bottom of a lingering workaround that's been in place.  The project is using the legacy DFU and Device Manager.

I've reviewed this guide (https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v11.0.0%2Fbledfu_appextending.html) and the referenced example hrs+dfu example project and I believe we have all the specified pieces included into our project.

In testing with an iOS phone/tablet bonded with our board, and using the nRF Connect app to perform DFU: 

The symptom we're observing is if we implement app_context_load() as in the example as-is, the DFU updates the software successfully.  But when we attempt to reconnect, the sd_ble_gatts_service_changed() returns NRF_ERROR_INVALID_STATE, and the nRF Connect app will not rediscover our application services until the phone/tablet is power cycled.

However, when a delay is added in app_context_load() before calling sd_ble_gatts_service_changed(),  upon reconnect after successful DFU, the sd_ble_gatts_service_changed() returns success.  Additionally, we added a RTT print when BLE_GATTS_EVT_SC_CONFIRM event is received, which we do observe in this case.  iOS phone/tablet is able to rediscover application services upon 2nd reconnect.  --Curiously when I attempt the same DFU with Android nRF Connect, the app_context_load() gets context but does not fall into calling the service_changed() function.  I am able to manually rediscover services through the menu option.

It is my understanding that the delay time (200ms works today) was not needed until we had hit a certain number of application services, after which it was added and increased over time in development.  Presently our application has 8 custom services in addition to Device Information, Battery, and DFU services.  

Any guidance in understanding what we might be masking with adding delay and helping to get our firmware to more reliably trigger service changed after DFU with mobile applications is greatly appreciated.  Thanks!

Joseph

  • Hello Joseph,

    The service changed indication will not be sent if there happens to be an ongoing ATT MTU exchange when you call sd_ble_gatts_service_changed() (will return invalid state in such case). I think this is what happens here. And the delay changes the timing just enough to avoid this procedure conflict.

    Timing of MTU requests from the phone may vary depending on OS and BT chipsets. In other words, a fixed delay is not guaranteed to be reliable. I think the original implementation should have included a mechanism to retry sending when sd_ble_gatts_service_changed() reports invalid state like the Peer manager does in the current SDK.

    Best regards,

    Vidar

  • Hi Vidar:

    Thanks for your response and input.  We've been able to remove the fixed delay and add a retry block within our task loop to indicate the serviced changed after DFU update.

    Joseph

Related