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

DFU Service Update for iOS

Hello guys,

I am using this repo to update my device's firmware but after the update is complete, the iPhone cannot find the correct devices services anymore.

To detail it better step by step:

My App can connect to the device and find it's Bluetooth services; Then I update the firmware through Bluetooth using DFU mode option from this repo; After that, when I connect to the device again (through BT), I cannot find the correct services. The only available services is the DFUUpdateService;

If I turn my device's BT off and on again, then I can gather the correct services. It is like if the device's services are being stored by the iOS itself.

Does anyone know how to fix that?

  • Hi, assume you are using a bootloader from SDK prior to v.8.0.0? In SDK 8.0.0 and later the bootloader was implemented with the Service changed characteristic required to tell the central to perform a new service discovery.

    The central caches the attributes once during the first connection in order to avoid doing service discovery on subsequent connections. This reduces the time and number of packet transfers required when reconnecting. Problem is that the the attribute table changes when entering DFU mode, and the DFU controller (iphone)needs to to a re-discovery in order to get the correct handles for the new attribute table. Otherwise the iphone app will fail to do DFU.

    This behavior is according to Bluetooth specifications. That is, the attribute handles should not change over time unless a special characteristic called service changed (SC) is present in the attribute table. When SC is used and there is no bonding with the peer, the ATT table will be seen as valid for the duration of the current connection. So the client will always do a rediscovery on subsequent connections. However, it is not that simple for bonded devices, here the server needs to send a SC indication to trigger a re-discovery of the handles, and a proper API for doing that was first added in S110 v.8.0.0. In other words, defining IS_SRVC_CHANGED_CHARACT_PRESENT as '1' should solve the issue if bonding is not to be supported on your device. Core spec. 4.1, vol 3, part G, section 2.5.2 provides more details about attribute caching if it is of interest.

    If you need to use a bootlaoder prior to v.8.0.0 you can workaround this by incrementing the GAP address by '1' and thus make the device appear as a different one seen from the central once you enter DFU mode, see "advertising openly" implemantion in new bootlaoder. Note that this will not be supported with bond sharing. Another option is to move the dfu service to the top of the ATT table to have the same attribute handles in your application and bootloader for the DFU service.

Related