NordicSemiconductor/IOS-DFU-Library

DFU progress stuck on iOS 17.0

Boon-FM opened this issue · 5 comments

DFU Bootloader version (please complete the following information):

  • SDK version: Not sure, it's on mbed 2 on NRF51822. Should be Legacy DFU looking at the logs.
  • Bonding used: yes
  • Library version: [4.13.0], [4.11.1]

Device information (please complete the following information):

  • Device: Different iPhones
  • OS: iOS 17.0

Describe the bug
DFU can be initiated without any problem, how ever the progress stuck at random progress (Sometimes 1% sometimes 60% sometimes success if super lucky). Only happens on iOS 17.0. Everything is working fine for iOS 16 and below.
Suspect that's a bug from Apple side on iOS 17.0, but might as well post here.

Logs

// DFULog: from LoggerDelegate
// DFU Progress DidUpdate: from DFUProgressDelegate
// DFU State Changed: from DFUServiceDelegate
DFU State Changed: Connecting
DFULog: I: Connected to AIRE2 2304 41:EB:61
DFULog: V: Discovering services...
DFULog: D: peripheral.discoverServices(nil)
DFULog: I: Services discovered
DFULog: V: Starting Legacy DFU...
DFULog: I: Connected to AIRE2 2304 41:EB:61
DFULog: I: Services discovered
DFULog: V: Legacy DFU Service found
DFULog: V: Discovering characteristics in DFU Service...
DFULog: D: peripheral.discoverCharacteristics(nil, for: 00001530-1212-EFDE-1523-785FEABCD123)
DFULog: I: DFU characteristics discovered
DFU State Changed: Starting
DFULog: V: Enabling notifications for 00001531-1212-EFDE-1523-785FEABCD123...
DFULog: D: peripheral.setNotifyValue(true, for: 00001531-1212-EFDE-1523-785FEABCD123)
DFULog: V: Notifications enabled for 00001531-1212-EFDE-1523-785FEABCD123
DFULog: A: DFU Control Point notifications enabled
DFULog: W: Application with buttonless update found
DFU State Changed: Enabling DFU Mode
DFULog: V: Writing to characteristic 00001531-1212-EFDE-1523-785FEABCD123...
DFULog: D: peripheral.writeValue(0x0104, for: 00001531-1212-EFDE-1523-785FEABCD123, type: .withResponse)
DFULog: D: [Callback] Central Manager did disconnect peripheral
DFULog: I: Disconnected by the remote device
DFULog: V: Scanning for the DFU Bootloader...
DFULog: D: centralManager.scanForPeripherals(withServices, [00001530-1212-EFDE-1523-785FEABCD123])
DFULog: I: DFU Bootloader found with name DfuTarg
DFULog: V: Connecting to DfuTarg...
DFULog: D: centralManager.connect(peripheral, options: nil)
DFULog: D: [Callback] Central Manager did connect peripheral
DFULog: I: Connected to DfuTarg
DFULog: V: Discovering services...
DFULog: D: peripheral.discoverServices([00001530-1212-EFDE-1523-785FEABCD123])
DFULog: I: Services discovered
DFULog: V: Legacy DFU Service found
DFULog: V: Discovering characteristics in DFU Service...
DFULog: D: peripheral.discoverCharacteristics(nil, for: 00001530-1212-EFDE-1523-785FEABCD123)
DFULog: I: DFU characteristics discovered
DFULog: V: Reading DFU Version number...
DFULog: D: peripheral.readValue(00001534-1212-EFDE-1523-785FEABCD123)
DFULog: I: Read Response received from 00001534-1212-EFDE-1523-785FEABCD123, value (0x): 0600
DFULog: A: Version number read: 0.6
DFU State Changed: Starting
DFULog: V: Enabling notifications for 00001531-1212-EFDE-1523-785FEABCD123...
DFULog: D: peripheral.setNotifyValue(true, for: 00001531-1212-EFDE-1523-785FEABCD123)
DFULog: V: Notifications enabled for 00001531-1212-EFDE-1523-785FEABCD123
DFULog: A: DFU Control Point notifications enabled
DFULog: V: Writing to characteristic 00001531-1212-EFDE-1523-785FEABCD123...
DFULog: D: peripheral.writeValue(0x0104, for: 00001531-1212-EFDE-1523-785FEABCD123, type: .withResponse)
DFULog: V: Writing image sizes (0b, 0b, 59912b) to characteristic 00001532-1212-EFDE-1523-785FEABCD123...
DFULog: D: peripheral.writeValue(0x000000000000000008ea0000, for: 00001532-1212-EFDE-1523-785FEABCD123, type: .withoutResponse)
DFULog: I: Data written to 00001531-1212-EFDE-1523-785FEABCD123
DFULog: A: Start DFU (Op Code = 1, Upload Mode = 4) request sent
DFULog: I: Notification received from 00001531-1212-EFDE-1523-785FEABCD123, value (0x): 100101
DFULog: A: Response (Op Code = Start DFU, Status = Success) received
DFULog: A: Writing Initialize DFU Parameters (Op Code = 2, Type = Begin)...
DFULog: V: Writing to characteristic 00001531-1212-EFDE-1523-785FEABCD123...
DFULog: D: peripheral.writeValue(0x0200, for: 00001531-1212-EFDE-1523-785FEABCD123, type: .withResponse)
DFULog: V: Writing to characteristic 00001532-1212-EFDE-1523-785FEABCD123...
DFULog: D: peripheral.writeValue(0xffffffff000000000100feffb9b3, for: 00001532-1212-EFDE-1523-785FEABCD123, type: .withoutResponse)
DFULog: V: Writing to characteristic 00001531-1212-EFDE-1523-785FEABCD123...
DFULog: D: peripheral.writeValue(0x0201, for: 00001531-1212-EFDE-1523-785FEABCD123, type: .withResponse)
DFULog: I: Data written to 00001531-1212-EFDE-1523-785FEABCD123
DFULog: I: Data written to 00001531-1212-EFDE-1523-785FEABCD123
DFULog: I: Notification received from 00001531-1212-EFDE-1523-785FEABCD123, value (0x): 100201
DFULog: A: Response (Op Code = Initialize DFU Parameters, Status = Success) received
DFULog: A: Initialize DFU Parameters completed
DFU State Changed: Uploading
DFULog: V: Writing to characteristic 00001531-1212-EFDE-1523-785FEABCD123...
DFULog: D: peripheral.writeValue(0x080c00, for: 00001531-1212-EFDE-1523-785FEABCD123, type: .withResponse)
DFULog: I: Data written to 00001531-1212-EFDE-1523-785FEABCD123
DFULog: A: Packet Receipt Notif Req (Op Code = 8, Value = 12) request sent
DFULog: V: Writing to characteristic 00001531-1212-EFDE-1523-785FEABCD123...
DFULog: D: peripheral.writeValue(0x03, for: 00001531-1212-EFDE-1523-785FEABCD123, type: .withResponse)
DFULog: I: Data written to 00001531-1212-EFDE-1523-785FEABCD123
DFULog: A: Uploading firmware...
DFULog: V: Sending firmware to DFU Packet characteristic...
DFU Progress Did Update: 0
DFU Progress Did Update: 1
DFU Progress Did Update: 2
DFU Progress Did Update: 3
DFU Progress Did Update: 4
DFU Progress Did Update: 5
DFU Progress Did Update: 6
DFU Progress Did Update: 7
DFU Progress Did Update: 8
DFU Progress Did Update: 9
DFU Progress Did Update: 10
DFU Progress Did Update: 11
DFU Progress Did Update: 12
DFU Progress Did Update: 13
DFU Progress Did Update: 14
DFU Progress Did Update: 15
DFU Progress Did Update: 16
DFU Progress Did Update: 17
DFU Progress Did Update: 18
DFU Progress Did Update: 19
DFU Progress Did Update: 20
DFU Progress Did Update: 21
DFU Progress Did Update: 22
DFU Progress Did Update: 23
DFU Progress Did Update: 24
DFU Progress Did Update: 25
DFU Progress Did Update: 26
DFU Progress Did Update: 27
DFU Progress Did Update: 28
// The progress is stuck here
// Note, the device turned itself off after a few minutes
DFULog: D: [Callback] Central Manager did disconnect peripheral
DFULog: I: Disconnected by the remote device
DFU State Changed: Connecting
DFULog: V: Connecting to DfuTarg...
DFULog: D: centralManager.connect(peripheral, options: nil)
DFULog: W: Connection timeout!
DFULog: D: centralManager.cancelPeripheralConnection(peripheral)
DFULog: E: [Callback] Central Manager failed to connect to peripheral (timeout)
DFU did Error: DFUError(rawValue: 201) Device failed to connect

Did you try enabling Package Receipt Notifications (PRN) with different values?
It may be that the phone sends the fw too fast for the nRF51 to be able to send. PRNs will slow the upload down and sync transmitter with the receiver.

To enable PRSs use:

@objc public var packetReceiptNotificationParameter: UInt16 = 12

Starting from iOS 11 the PRNs can be disabled (see code below), but if you have transfer issues enabling them may help:

// Starting from iOS 11 and macOS 10.13 there is a new API that removes the need of PRNs.
// However, some devices may still work better with them enabled! A specially those
// based on SDK older than 8.0 where the flash saving was slower and modern phones
// can send data faster then that which causes the DFU bootloader to abort with an error.
if #available(iOS 11.0, macOS 10.13, *) {
dfuInitiator.packetReceiptNotificationParameter = 0
}

Btw, seems like the root cause of the issue is on the iOS side. Perhaps the connection interval was changed or more data can be sent in a connection interval. You may also try increasing the distance between the iPhone and your device to cause some transfer issues. Retransmitting will slow down the upload. But of course this is a very unreliable method.

After testing with some phones, we found out that the bug only happens on some phone models (For example, it's no iPhone XS but not on iPhone SE (2nd Gen)).
The PRN was enabled with the default value 12. Lowering the PRN value to 10 or below fixed the bug on iPhone XS. Weirdly, disable the PRN also fixes the bug, not sure what's happening there. Thanks for helping @philips77 .

I try to change the value of packetReceiptNotificationParameter from 12 to 0, but on the iPad 12 mini with iOS 17 the problem persists

I'm testing on iOS 17.0.3 and cannot reproduce the issue.