question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

DFU fails on Android 8 and 8.1 after "Reading DFU version number..." but succeeds on Android version < 8

See original GitHub issue

I use a simplified version of the nrfToolbox sources (removed unused features) and Android-DFU-Library V 1.9.0 The DFUActivity of the nRFTooldbox sources is basically unchanged I only replaced the deprecated preference values with the default ones. See code fragment below.

Bootloader/Softdevice is from Adafruit nRF52 Arduino, version used is 0.9.3

ZIP file for update is identical for all tests on Android 7.1.1, Android 8.0 and Android 8.1

If I run the app on Android 7 or older the DFU update works as expected, but on Android 8.0 (Huawei Mediapad M5) and 8.1 (Samsung Galaxy J7 core) the DFU update fails after device is forced into bootloader, reconnected and then trying to read the DFU version number. See Android catlog below. On Android 8 and 8.1 it seems the DFU service is too slow and the device reboots into the application while the DFU service still tries to read the DFU version. On Android older than 7 I see in the timestamp ~90 milliseconds from requesting the DFU version to receiving the DFU version On Android 8.1 I see in the timestamps ~ 5 seconds from requesting the DFU version to read error and disconnect.

Logcat shows in case of failure:

10:30:42.917  I/DfuImpl: Reading DFU version number...
10:30:47.139  E/DfuImpl: Characteristic read error: 133
10:30:47.140  D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=7 device=E0:22:0C:0E:98:BD
10:30:47.140  W/DfuBaseService: Target device disconnected with status: 8
10:30:47.141  E/DfuBaseService: Unable to read version number: device disconnected

Any idea?

Code used to start DFU service:

		final DfuServiceInitiator starter = new DfuServiceInitiator(mSelectedDevice.getAddress())
				.setDeviceName(mSelectedDevice.getName())
				.setKeepBond(true)
				.setForceDfu(true)
				.setPacketsReceiptNotificationsEnabled(true)
				.setPacketsReceiptNotificationsValue(DfuServiceInitiator.DEFAULT_PRN_VALUE)
				.setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true)
				.setForeground(true);
		if (mFileType == DfuService.TYPE_AUTO) {
			starter.setZip(mFileStreamUri, mFilePath);
			if (mScope != null)
				starter.setScope(mScope);
		} else {
			starter.setBinOrHex(mFileType, mFileStreamUri, mFilePath).setInitFile(mInitFileStreamUri, mInitFilePath);
		}
		starter.start(this, DfuService.class);

Catlog from Android 7.1.1 (successful OTA update)

10:42:14.609  I/DfuBaseService: DFU service created. Version: 1.9.0
10:42:14.767  I/DfuBaseService: Connecting to the device...
10:42:14.769  D/BluetoothGatt: connect() - device: E0:22:0C:0E:98:BD, auto: false
10:42:14.769  D/BluetoothGatt: registerApp()
10:42:14.770  D/BluetoothGatt: registerApp() - UUID=b77baf40-0d60-401d-8d3c-6e5d06de6850
10:42:14.772  D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
10:42:16.997  D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=E0:22:0C:0E:98:BD
10:42:16.999  I/DfuBaseService: Action received: android.bluetooth.device.action.ACL_CONNECTED
10:42:17.001  I/DfuBaseService: Connected to GATT server
10:42:17.006  D/BluetoothGatt: discoverServices() - device: E0:22:0C:0E:98:BD
10:42:17.010  I/DfuBaseService: Attempting to start service discovery... succeed
10:42:18.268  D/BluetoothGatt: onSearchComplete() = Device=E0:22:0C:0E:98:BD Status=0
10:42:18.269  I/DfuBaseService: Services discovered
10:42:19.284  I/DfuImpl: Reading DFU version number...
10:42:19.364  W/BluetoothGatt: onCharacteristicRead() - Device=E0:22:0C:0E:98:BD handle=21 Status=0
10:42:19.367  I/DfuImpl: Version number read: 0.1 -> Application with Legacy buttonless update from SDK 7.0 or newer
10:42:19.371  W/DfuImpl: Application with legacy buttonless update found
10:42:19.372  I/DfuImpl: Enabling notifications...
10:42:19.376  D/BluetoothGatt: setCharacteristicNotification() - uuid: 00001531-1212-efde-1523-785feabcd123 enable: true
10:42:19.874  I/art: Do partial code cache collection, code=231KB, data=200KB
10:42:19.875  I/art: After code cache collection, code=229KB, data=198KB
10:42:19.875  I/art: Increasing code cache capacity to 1024KB
10:42:20.486  I/DfuImpl: Sending Start DFU command (Op Code = 1, Upload Mode = 4)
10:42:40.575  D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=6 device=E0:22:0C:0E:98:BD
10:42:40.575  W/DfuBaseService: Target device disconnected with status: 8
10:42:40.581  D/BluetoothGatt: refresh() - device: E0:22:0C:0E:98:BD
10:42:40.589  I/DfuBaseService: Action received: android.bluetooth.device.action.ACL_DISCONNECTED
10:42:40.593  I/DfuBaseService: Refreshing result: true
10:42:40.594  I/DfuBaseService: Cleaning up...
10:42:40.596  D/BluetoothGatt: close()
10:42:40.596  D/BluetoothGatt: unregisterApp() - mClientIf=6
10:42:40.599  I/DfuImpl: Starting service that will connect to the DFU bootloader
10:42:42.675  I/DfuBaseService: Connecting to the device...
10:42:42.679  D/BluetoothGatt: connect() - device: E0:22:0C:0E:98:BD, auto: false
10:42:42.679  D/BluetoothGatt: registerApp()
10:42:42.680  D/BluetoothGatt: registerApp() - UUID=f46d4775-1ba9-4c17-b9e1-c5b16858d6fd
10:42:42.683  D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
10:42:47.158  D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=E0:22:0C:0E:98:BD
10:42:47.158  I/DfuBaseService: Connected to GATT server
10:42:47.160  I/DfuBaseService: Action received: android.bluetooth.device.action.ACL_CONNECTED
10:42:47.162  D/BluetoothGatt: discoverServices() - device: E0:22:0C:0E:98:BD
10:42:47.165  I/DfuBaseService: Attempting to start service discovery... succeed
10:42:47.792  D/BluetoothGatt: onSearchComplete() = Device=E0:22:0C:0E:98:BD Status=0
10:42:47.792  I/DfuBaseService: Services discovered
10:42:48.808  I/DfuImpl: Reading DFU version number...
10:42:48.899  W/BluetoothGatt: onCharacteristicRead() - Device=E0:22:0C:0E:98:BD handle=21 Status=0
10:42:48.901  I/DfuImpl: Version number read: 0.8 -> Bootloader from SDK 9.0 or newer. Signature supported
10:42:48.906  W/DfuImpl: Legacy DFU bootloader found
10:42:49.908  I/DfuImpl: Enabling notifications...
10:42:49.911  D/BluetoothGatt: setCharacteristicNotification() - uuid: 00001531-1212-efde-1523-785feabcd123 enable: true
10:42:50.973  I/DfuImpl: Sending Start DFU command (Op Code = 1, Upload Mode = 4)
10:42:51.046  I/DfuImpl: Sending image size array to DFU Packet (0b, 0b, 78820b)
10:42:51.340  I/DfuImpl: Sending the Initialize DFU Parameters START (Op Code = 2, Value = 0)
10:42:51.435  I/DfuImpl: Sending 14 bytes of init packet
10:42:51.436  I/DfuImpl: Sending init packet (Value = 52-00-FF-FF-FF-FF-FF-FF-01-00-B7-00-7E-E8)
10:42:51.444  I/DfuImpl: Sending the Initialize DFU Parameters COMPLETE (Op Code = 2, Value = 1)
10:42:51.532  I/DfuImpl: Sending Receive Firmware Image request (Op Code = 3)
10:42:51.651  I/DfuImpl: Uploading firmware...
10:43:41.698  I/DfuImpl: Response received (Op Code = 16, Req Op Code = 3, Status = 1)
10:43:41.699  I/DfuImpl: Transfer of 78820 bytes has taken 49644 ms
10:43:41.700  I/DfuImpl: Sending Validate request (Op Code = 4)
10:43:41.795  I/DfuImpl: Response received (Op Code = 16, Req Op Code = 4, Status = 1)
10:43:41.805  I/DfuImpl: Sending Activate and Reset request (Op Code = 5)
10:43:42.186  D/BluetoothGatt: onClientConnectionState() - status=19 clientIf=6 device=E0:22:0C:0E:98:BD
10:43:42.187  W/DfuBaseService: Target device disconnected with status: 19
10:43:42.188  D/BluetoothGatt: refresh() - device: E0:22:0C:0E:98:BD
10:43:42.191  I/DfuBaseService: Refreshing result: true
10:43:42.191  I/DfuBaseService: Cleaning up...
10:43:42.192  D/BluetoothGatt: close()
10:43:42.192  D/BluetoothGatt: unregisterApp() - mClientIf=6
10:43:42.194  I/DfuBaseService: Action received: android.bluetooth.device.action.ACL_DISCONNECTED
10:43:43.642  I/DfuBaseService: DFU service destroyed
10:43:43.887  D/mali_winsys: new_window_surface returns 0x3000,  [679x88]-format:1

Catlog from Android 8.1 (OTA update failed)

10:30:35.150  I/DfuBaseService: DFU service created. Version: 1.9.0
10:30:35.285  I/DfuBaseService: Connecting to the device...
10:30:35.288  D/BluetoothGatt: connect() - device: E0:22:0C:0E:98:BD, auto: false
10:30:35.288  D/BluetoothGatt: registerApp()
10:30:35.288  D/BluetoothGatt: registerApp() - UUID=0e2b0b79-4c6b-43ed-9a43-3cefd31a84d8
10:30:35.291  D/BluetoothGatt: onClientRegistered() - status=0 clientIf=7
10:30:35.345  D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=7 device=E0:22:0C:0E:98:BD
10:30:35.345  I/DfuBaseService: Connected to GATT server
10:30:35.347  I/DfuBaseService: Waiting 1600 ms for a possible Service Changed indication...
10:30:35.347  D/BluetoothGatt: discoverServices() - device: E0:22:0C:0E:98:BD
10:30:35.349  I/DfuBaseService: Attempting to start service discovery... succeed
10:30:35.353  I/DfuBaseService: Action received: android.bluetooth.device.action.ACL_CONNECTED
10:30:35.360  D/BluetoothGatt: onSearchComplete() = Device=E0:22:0C:0E:98:BD Status=0
10:30:35.361  I/DfuBaseService: Services discovered
10:30:35.792  D/BluetoothGatt: onConnectionUpdated() - Device=E0:22:0C:0E:98:BD interval=9 latency=0 timeout=200 status=0
10:30:36.386  I/DfuImpl: Reading DFU version number...
10:30:36.413  I/DfuImpl: Version number read: 0.1 -> Application with Legacy buttonless update from SDK 7.0 or newer
10:30:36.417  I/DfuImpl: Reading Service Changed CCCD value...
10:30:36.447  W/DfuImpl: Application with legacy buttonless update found
10:30:36.449  I/DfuImpl: Enabling notifications...
10:30:36.452  D/BluetoothGatt: setCharacteristicNotification() - uuid: 00001531-1212-efde-1523-785feabcd123 enable: true
10:30:37.504  I/DfuImpl: Sending Start DFU command (Op Code = 1, Upload Mode = 4)
10:30:39.562  D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=7 device=E0:22:0C:0E:98:BD
10:30:39.563  W/DfuBaseService: Target device disconnected with status: 8
10:30:39.566  I/DfuBaseService: Cleaning up...
10:30:39.567  D/BluetoothGatt: close()
10:30:39.567  D/BluetoothGatt: unregisterApp() - mClientIf=7
10:30:39.571  I/DfuImpl: Starting service that will connect to the DFU bootloader
10:30:39.574  I/DfuBaseService: Action received: android.bluetooth.device.action.ACL_DISCONNECTED
10:30:41.631  I/DfuBaseService: Connecting to the device...
10:30:41.633  D/BluetoothGatt: connect() - device: E0:22:0C:0E:98:BD, auto: false
10:30:41.633  D/BluetoothGatt: registerApp()
10:30:41.634  D/BluetoothGatt: registerApp() - UUID=657996be-c909-481a-9321-a7fe8c78efb9
10:30:41.637  D/BluetoothGatt: onClientRegistered() - status=0 clientIf=7
10:30:41.871  D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=7 device=E0:22:0C:0E:98:BD
10:30:41.872  I/DfuBaseService: Connected to GATT server
10:30:41.875  I/DfuBaseService: Waiting 1600 ms for a possible Service Changed indication...
10:30:41.876  D/BluetoothGatt: discoverServices() - device: E0:22:0C:0E:98:BD
10:30:41.878  I/DfuBaseService: Attempting to start service discovery... succeed
10:30:41.879  I/DfuBaseService: Action received: android.bluetooth.device.action.ACL_CONNECTED
10:30:41.898  D/BluetoothGatt: onSearchComplete() = Device=E0:22:0C:0E:98:BD Status=0
10:30:41.899  I/DfuBaseService: Services discovered
10:30:42.917  I/DfuImpl: Reading DFU version number...
10:30:47.139  E/DfuImpl: Characteristic read error: 133
10:30:47.140  D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=7 device=E0:22:0C:0E:98:BD
10:30:47.140  W/DfuBaseService: Target device disconnected with status: 8
10:30:47.141  E/DfuBaseService: Unable to read version number: device disconnected
10:30:47.141  I/DfuBaseService: Cleaning up...
10:30:47.141  D/BluetoothGatt: close()
10:30:47.142  D/BluetoothGatt: unregisterApp() - mClientIf=7
10:30:47.204  I/DfuBaseService: Action received: android.bluetooth.device.action.ACL_DISCONNECTED
10:30:47.224  I/DfuBaseService: DFU service destroyed

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5

github_iconTop GitHub Comments

1reaction
beegee-tokyocommented, Mar 26, 2019

@philips77 Just to push a notification to you about above solution.

0reactions
beegee-tokyocommented, Mar 26, 2019

Last update and closing this issue. Hope you can confirm the solution and implement these changes into the DFU library.

Solved the problem with following change in DfuBaseService:

In DfuBaseService.java >> private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() >> public void onConnectionStateChange() I changed

if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_BONDED) {
	logi("Waiting 1600 ms for a possible Service Changed indication...");
	waitFor(1600);
	// After 1.6s the services are already discovered so the following gatt.discoverServices() finishes almost immediately.

	// NOTE: This also works with shorted waiting time. The gatt.discoverServices() must be called after the indication is received which is
	// about 600ms after establishing connection. Values 600 - 1600ms should be OK.
}

to

if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_BONDED) {
	logi("Remove bond before starting DFU");
	try {
		Method m = gatt.getDevice().getClass()
			.getMethod("removeBond", (Class[]) null);
		m.invoke(gatt.getDevice(), (Object[]) null);
	} catch (Exception e) {
		Log.e(TAG, e.getMessage());
	}
	return;
}

That solved the DFU problem on Android 8.0 and 8.1 and works as well on Android 7.1.1 and older (tested on Samsung Galaxy Tab 10 Android 7.1.1 and Samsung Galaxy Tab A Android 5.0.2).

In addition I limit PRN with

if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
//	starter.setPacketsReceiptNotificationsValue(DfuServiceInitiator.DEFAULT_PRN_VALUE);
	starter.setPacketsReceiptNotificationsValue(10);
	Log.e(TAG, "Android SDK < 26 (8.0) set PRN to 10");
} else {
	starter.setPacketsReceiptNotificationsValue(4);
	Log.e(TAG, "Android SDK >= 26 (8.0) set PRN to 4");
}

when calling the DfuServiceInitiator.

Read more comments on GitHub >

github_iconTop Results From Across the Web

dfu fails in nrf51822AC - Nordic Q&A
I successfully added dfu service but failed to program the device over dfu using nrf connect app on android phone.
Read more >
Migrating to Android 8.0
Update your target version and use Android 8.0 features. This section explains how to enable full support for Android 8.0 (API level 26)...
Read more >
Bug listing with status UNCONFIRMED as at 2022/12/14 12 ...
Bug:128538 - "sys-apps/coreutils: /bin/hostname should be installed from coreutils not sys-apps/net-tools" status:UNCONFIRMED resolution: severity:enhancement ...
Read more >
Android - CVE - Search Results
CWE-302 Authentication Bypass by Assumed-Immutable Data in AliveCor Kardia App version 5.17.1-754993421 and prior on Android allows an unauthenticated attacker ...
Read more >
Introducing the Adafruit Bluefruit LE Friend - Octopart
This tutorial uses the Android version of nRF UART but the iOS UI is ... The AT parser will no longer responsd after...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found