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

DFU update with Zip SD-BL+APP fails on writing characteristic on second image upload [iOS]

Hello,

I have developed my own iOS app which is capable of DFU update different devices with nRF51 and nRF52 chips.

Using only APP file (both .hex and .zip) works perfectly. Now I am having an issue with updating with a ZIP file containing SD+BL+APP. 

For the full zip, the app successfully uploads the first image, then disconnects, reconnects again, reads services and characteristics, it enables a notification and it finally fails on writing the first characteristics ("Writing is not permitted"). Here are more details:

- I am using Xcode 10.0 and iOS 12.0

- I am using the iOSDFULibrary version updated yesterday (4.1.3?)

- I am trying to update from SDK 12.2.0 and softdevice 3.1.0 to SDK 13.1.0 and softdevice 4.0.5

- I have tried both using the "forceDfu" flag to true and false

- "Service Changed" is enabled in the new firmware (not in the old one)

- The name is changed on the new DFU, but I don't think this is an issue as it successfully reconnect for the second image.

- I am using Secure DFU.


Here is a the log of the app when it fails:

...
98% (1/2)
99% (1/2)
Verbose: Writing to characteristic 8EC90001-F315-4F60-9FB8-838830DAEA50...
Debug: peripheral.writeValue(0x03, for: 8EC90001-F315-4F60-9FB8-838830DAEA50, type: .withResponse)
100% (1/2)
Info: Data written to 8EC90001-F315-4F60-9FB8-838830DAEA50
Info: Notification received from 8EC90001-F315-4F60-9FB8-838830DAEA50, value (0x): 600301502f02005cc7604c
Application: Checksum (Offset = 143184, CRC = 4C60C75C) received
Verbose: Writing to characteristic 8EC90001-F315-4F60-9FB8-838830DAEA50...
Debug: peripheral.writeValue(0x04, for: 8EC90001-F315-4F60-9FB8-838830DAEA50, type: .withResponse)
Info: Data written to 8EC90001-F315-4F60-9FB8-838830DAEA50
Info: Notification received from 8EC90001-F315-4F60-9FB8-838830DAEA50, value (0x): 600401
Application: Data object executed
Application: Upload completed in 66.42 seconds
Debug: [Callback] Central Manager did disconnect peripheral
Info: Disconnected by the remote device
Verbose: Connecting to iBKSDFU52V3...
Debug: centralManager.connect(peripheral, options: nil)
Debug: [Callback] Central Manager did connect peripheral
Info: Connected to iBKSDFU52V3
Verbose: Discovering services...
Debug: peripheral.discoverServices([FE59])
Info: Services discovered
Verbose: Secure DFU Service found
Verbose: Discovering characteristics in DFU Service...
Debug: peripheral.discoverCharacteristics(nil, for: FE59)
Info: DFU characteristics discovered
Verbose: Enabling notifications for 8EC90001-F315-4F60-9FB8-838830DAEA50...
Debug: peripheral.setNotifyValue(true, for: 8EC90001-F315-4F60-9FB8-838830DAEA50)
Verbose: Notifications enabled for 8EC90001-F315-4F60-9FB8-838830DAEA50
Application: Secure DFU Control Point notifications enabled
Verbose: Writing to characteristic 8EC90001-F315-4F60-9FB8-838830DAEA50...
Debug: peripheral.writeValue(0x0601, for: 8EC90001-F315-4F60-9FB8-838830DAEA50, type: .withResponse)
Error: Writing to characteristic failed. Check if Service Changed service is enabled.
Error: Error 3: Writing is not permitted.
Verbose: Disconnecting...
Debug: centralManager.cancelPeripheralConnection(peripheral)
Debug: [Callback] Central Manager did disconnect peripheral
Info: Disconnected

Please let me know if you need me to provide any other information.

Thanks in advance,

BR,

Gabriel.

  • Hi Gabriel,

    Have you tried to update an application which has service changed characteristic enabled ? 

    What you described that the original firmware doesn't have the Service Changed characteristic could be the problem. When there isn't a service changed characteristic, the phone would think that the attribute table is fixed and wouldn't do service discovery to update when the new image updated. 

    What I'm not so sure of is why you can do App update with no problem but can't do SD+BL+APP update. 

    Have you made sure you do DFU two times in your DFU app ? First with SD+BL and then second with APP only ? 

    Do you have the same issue when you test with our nRFConnect/nRFToolbox app ? 

  • Hi Hung Bui, thank you for your reply. 

    I have tried to update an application zip firmware, but over another firmware. Not over the one which fails.

    For the one described above I need to update all together in a ZIP as the changes are really important from one version to another.

    About the service changed, I am not sure if I understand it properly. As far as I know, when we push a SD+BLE+APP in a zip, the first image to be uploaded is the SD+BLE, right? So why it is critical for the old bootloader to have the service changed if it has been already replaced by the time it fails with the second image?

    Also the name changes from one bootloader to another, and the iOS systems seems to get it well, so it seems that the service change should not be a problem.

    About making the DFU two times, this is done automatically by the library itself, right? In the log I see how it starts to upload the first image, then it stops, it reconnects and it tries to start the second image upload. I am not managing this two processes manually. I simply specify firmware type is DFUFirmwareType.softdeviceBootloaderApplication and it does all that by itself.

    As a note, the same process, with the same device and firmware, works as expected in Android. Only by specifying the type to AUTO it uploads both images and it finishes without any issue. So it is an iOS problem.

    And yes, I have tested it with nRFConnect app and it fails with the same error. It uploads the first image and then, it connects again and it returns the error: "Failed to write characteristic".

    Thank you.

  • I believe it has something to do with the fact that the service changed characteristic was missing. 

    As you mentioned when we have new bootloader why lacking service changed characteristic in the old bootloader cause any trouble, it actually can. The phone after it discovery the attribute table of the old bootloader, found that there was no service changed characteristic, it it would assume the table won't change. And by having that the phone would never realize the attribute table has changed after we switch to the new bootloader. 

    The advertising name change wouldn't trigger the phone to think that there is a new attribute table, you still need the service changed characteristic in the old bootloader. 

    The solution is to turn off an on Bluetooth  on the phone to clear the cache. But you would need to do it manually between the 2 DFU update. Another option is to make the new bootloader and the old bootloader look identical in the attribute table, then you don't need to do service changed indication. 

    ( Changing the address of the new bootloader would also another option, but you would need to modify the DFU library to detect that you change the address ) 

    If you are using the DFU library then it already taking care of the 2 phases DFU update. 

Related