DFU problems on Huawei devices
See original GitHub issueHi,
I’m developing an app using the nordic android DFU library, and I try to update the user device’s bootloader + firmware without user interaction.
The issue I’m facing is that it is partially functional: I get many 133 and 129 Bluetooth errors while testing, but also the “DFU CHARACTERISTICS NOT FOUND” one (4102) on Huawei devices. The other devices I’ve tested don’t have that much errors.
Is there a known problem with Huawei devices Bluetooth or did I do something wrong?
My code for both updates below:
Code to start the Bootloader update:
private fun startBootloaderDFUProcess() {
Log.i(TAG, "Starting Bootloader DFU update")
val starter = DfuServiceInitiator(deviceMacAddress!!)
.setDeviceName(deviceName!!)
.setKeepBond(true)
starter.setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true)
starter.setZip(bootloaderPathName!!)
starter.start(context!!, DfuService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
DfuServiceInitiator.createDfuNotificationChannel(context!!)
}
}
Code for the DfuProgressListener
for the Bootloader:
private val dfuBootloaderProgressListener = object : DfuProgressListenerAdapter() {
override fun onEnablingDfuMode(deviceAddress: String) {
super.onEnablingDfuMode(deviceAddress)
dfu_description.text = getString(R.string.dfu_initializing_update)
}
override fun onProgressChanged(
deviceAddress: String,
percent: Int,
speed: Float,
avgSpeed: Float,
currentPart: Int,
partsTotal: Int
) {
super.onProgressChanged(deviceAddress, percent, speed, avgSpeed, currentPart, partsTotal)
mPercent = percent / 2
dfu_loading_bar.progress = mPercent
tv_update_percent.text = getString(R.string.dfu_percent, mPercent)
}
override fun onError(deviceAddress: String, error: Int, errorType: Int, message: String?) {
super.onError(deviceAddress, error, errorType, message)
Log.v(TAG, "onError : $error type : $errorType message : $message")
when (error) {
BOOTLOADER_FW_VERSION_FAILURE -> {
viewModel.launchScanForDfuTarg()
}
DFU_DISCONNECTED -> {
startBootloaderDFUProcess()
}
else -> {
PrefEnovap.saveIsBackBlockedToPref(false)
displayErrorOnSnackbarLong(dfu_base, getString(R.string.dfu_error_disconnection))
(activity as MainActivity).onBackPressed()
}
}
}
override fun onDfuAborted(deviceAddress: String) {
super.onDfuAborted(deviceAddress)
Log.v(TAG, "dfu aborted")
}
override fun onFirmwareValidating(deviceAddress: String) {
super.onFirmwareValidating(deviceAddress)
Log.v(TAG, "onFirmwareValidating")
}
override fun onDeviceDisconnected(deviceAddress: String) {
super.onDeviceDisconnected(deviceAddress)
Log.v(TAG, "onDeviceDisconnected")
}
override fun onDeviceConnected(deviceAddress: String) {
super.onDeviceConnected(deviceAddress)
Log.v(TAG, "onDeviceConnected")
}
override fun onDfuProcessStarting(deviceAddress: String) {
super.onDfuProcessStarting(deviceAddress)
Log.v(TAG, "onDfuProcessStartingBootloader")
if (!enovap_button_dfu.isAnimating) {
enovap_button_dfu.startAnimation()
}
dfu_description.text = getString(R.string.dfu_updating)
mPercent = 0
dfu_loading_bar.progress = mPercent
tv_update_percent.text = getString(R.string.dfu_percent, mPercent)
}
override fun onDfuProcessStarted(deviceAddress: String) {
super.onDfuProcessStarted(deviceAddress)
Log.v(TAG, "onDfuProcessStarted")
}
override fun onDeviceConnecting(deviceAddress: String) {
super.onDeviceConnecting(deviceAddress)
Log.v(TAG, "onDeviceConnecting")
}
override fun onDfuCompleted(deviceAddress: String) {
super.onDfuCompleted(deviceAddress)
Log.v(TAG, "onDfuCompleted")
startFirmwareDFUProcess()
}
}
Code to start the Firmware update:
private fun startFirmwareDFUProcess() {
Log.i(TAG, "Starting Firmware DFU update")
DfuServiceListenerHelper.registerProgressListener(context!!, dfuFirmwareProgressListener)
val starter = DfuServiceInitiator(deviceMacAddress!!)
.setDeviceName(deviceName!!)
.setKeepBond(true)
starter.setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true)
starter.setZip(firmwarePathName!!)
starter.start(context!!, DfuService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
DfuServiceInitiator.createDfuNotificationChannel(context!!)
}
}
Code for the DfuProgressListener
for the Firmware:
private val dfuFirmwareProgressListener = object : DfuProgressListenerAdapter() {
override fun onProgressChanged(
deviceAddress: String,
percent: Int,
speed: Float,
avgSpeed: Float,
currentPart: Int,
partsTotal: Int
) {
super.onProgressChanged(deviceAddress, percent, speed, avgSpeed, currentPart, partsTotal)
enovap_button_dfu.startAnimation()
mPercent = FIRMWARE_START_PERCENT + percent / 2
dfu_loading_bar.progress = mPercent
tv_update_percent.text = getString(R.string.dfu_percent, mPercent)
}
override fun onError(deviceAddress: String, error: Int, errorType: Int, message: String?) {
super.onError(deviceAddress, error, errorType, message)
Log.v(TAG, "onError : $error message : $message")
when (error) {
BOOTLOADER_FW_VERSION_FAILURE -> {
viewModel.launchScanForDfuTarg()
}
else -> {
DfuServiceListenerHelper.unregisterProgressListener(context!!, this)
PrefEnovap.saveIsBackBlockedToPref(false)
displayErrorOnSnackbarLong(dfu_base, getString(R.string.dfu_error_disconnection))
(activity as MainActivity).onBackPressed()
}
}
}
override fun onDfuAborted(deviceAddress: String) {
super.onDfuAborted(deviceAddress)
Log.v(TAG, "dfu aborted")
}
override fun onFirmwareValidating(deviceAddress: String) {
super.onFirmwareValidating(deviceAddress)
Log.v(TAG, "onFirmwareValidating")
}
override fun onDeviceDisconnected(deviceAddress: String) {
super.onDeviceDisconnected(deviceAddress)
Log.v(TAG, "onDeviceDisconnected")
}
override fun onDeviceConnected(deviceAddress: String) {
super.onDeviceConnected(deviceAddress)
Log.v(TAG, "onDeviceConnected")
}
override fun onDfuProcessStarting(deviceAddress: String) {
super.onDfuProcessStarting(deviceAddress)
Log.v(TAG, "onDfuProcessStarting")
dfu_loading_bar.progress = FIRMWARE_START_PERCENT
tv_update_percent.text = getString(R.string.dfu_percent, FIRMWARE_START_PERCENT)
}
override fun onDfuProcessStarted(deviceAddress: String) {
super.onDfuProcessStarted(deviceAddress)
Log.v(TAG, "onDfuProcessStarted")
}
override fun onDeviceConnecting(deviceAddress: String) {
super.onDeviceConnecting(deviceAddress)
Log.v(TAG, "onDeviceConnecting")
}
override fun onDfuCompleted(deviceAddress: String) {
super.onDfuCompleted(deviceAddress)
DfuServiceListenerHelper.unregisterProgressListener(context!!, this)
activity?.runOnUiThread {
PrefEnovap.saveIsBackBlockedToPref(false)
dfu_description.gone()
dfu_icon.fadeOut {}
dfu_icon.gone()
dfu_title.fadeOut {}
dfu_title.gone()
dfu_subtitle.fadeOut {}
dfu_subtitle.gone()
tv_update_percent.fadeOut {}
tv_update_percent.gone()
dfu_loading_bar.fadeOut {}
dfu_loading_bar.gone()
enovap_button_dfu.fadeOut {}
enovap_button_dfu.gone()
enovap_button_dfu.revertAnimation()
dfu_icon.setImageDrawable(getDrawable(context!!, R.drawable.ic_up_to_date))
dfu_title.text = getString(R.string.enovap_up_to_date)
dfu_subtitle.text = getString(R.string.dfu_up_to_date_description)
Handler().postDelayed({
dfu_icon.visible()
dfu_icon.fadeIn {}
dfu_title.visible()
dfu_title.fadeIn {}
dfu_subtitle.visible()
dfu_subtitle.fadeIn {}
enovap_button_dfu_finish.visible()
enovap_button_dfu_finish.fadeIn {}
}, 400)
}
}
}
Issue Analytics
- State:
- Created 4 years ago
- Comments:7 (2 by maintainers)
Top Results From Across the Web
DFU problems on Huawei devices to Upload .hex files #298
So you're using DFU from SDK 6.1 or older. By counting number of services, the library assumes that the device is in DFU...
Read more >Online update failure on my HUAWEI phone/tablet
Learn about 'Online update failure on my HUAWEI phone/tablet'. Find all usage guide, troubleshooting tips and resources for your HUAWEI product.
Read more >Top 9 Huawei Phone Problems and How to Fix Them - Dr.Fone
In this article, we have broken down for you the top 6 problems of Huawei phones and provided you solutions on how to...
Read more >Reboot loop! Factory reset didn't work! - Huawei Ascend P6-U06
1) download the firmware by below link http://consumer.huawei.com/en/mobile-phones/support/downloads/p6-u06-en.htm#anchor 2) Copy it to SD ...
Read more >How to Enter Recovery Mode on Huawei Phone in One Click
It is quite easy and quick to enter Recovery Mode on Huawei devices, but the problem arises when the keys aren't working or...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
The library will do this automatically. Also, if your using non modified DFU bootloader it will send those notifications automatically.
@philips77 When setting setPacketsReceiptNotificationsEnabled to true, what changes that fixes the issue users reported above? What I’m wondering when setting that to true do you have to ensure a notification is received before doing more work, If so, is this on the controller application to implement the notification is received?
Also, I’m curious is it be common practice to set a retry policy?