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

Using Older library with new products

Hello im an Android developer and we have an app that uses an older library but still works with are older products.

we currently use 

implementation 'no.nordicsemi.android:dfu:1.8.1'

Works great with are older products but we currently started a new product with all latest chips and libraries..

so we need to make a BLE update in app.we currently do it for all of our products but for this one i fail at reconnecting to DFU device?

Start load device in DFU then try to reconnect but just hangs..

i noticed our library is really old put if i update that i need to update the entire app and the older devices might not work anymore..

is there a patch i can do for this?


scanning part

private fun getScanDfuDeviceObservable(): Observable<Boolean> {
        addLog("getScanDfuDeviceObservable")
        this._currentConnectionManager.disconnect()

        this._updateStateObservable.onNext(WssBleFirmwareUpdateState.SCANNING_DEVICE_IN_DFU)

        val settings = ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // change if needed
                .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) // change if needed
                .build()

        val observable = Observable.create<Boolean> {
            this._deviceScanObservableEmitter = it
        }

        this.forceDeviceDisconnection()
        this._scanDisposable?.dispose()

        return observable.doOnSubscribe {
            this._scanDisposable?.dispose()
            this._scanDisposable =
                    //We wait 3 seconds
                    Observable.just(true).delay(2, TimeUnit.SECONDS).concatMap {
                        this.rxBleClient.scanBleDevices(settings)
                    }.subscribe({
                        //Should we validate macAddress as well?
                        if (it.bleDevice.name.equals(DFU_TARG, true)) {
                            this._scanDisposable?.dispose()
                            this._scanDisposable = null
                            addLog("getScanDfuDeviceObservable", "Found the device")
                            this._rxBleDeviceDfu = it.bleDevice
                            if (!this._deviceScanObservableEmitter.isDisposed) {
                                this._deviceScanObservableEmitter.onNext(true)
                                this._deviceScanObservableEmitter.onComplete()
                            }

                        }
                    }, {
                        this._scanDisposable?.dispose()
                        this._scanDisposable = null
                        if (!this._deviceScanObservableEmitter.isDisposed) {
                            this._deviceScanObservableEmitter.onError(it)
                            this._deviceScanObservableEmitter.onComplete()
                        }
                    })
        }.timeout(5, TimeUnit.SECONDS, Observable.error(TimeoutException()))
                .doOnError {
                    this._scanDisposable?.dispose()
                }
                .retry(5)
                .take(1)
                .delay(5, TimeUnit.SECONDS) // If we are too fast, the update won't work
                .onErrorResumeNext { it: Throwable ->
                    addLog("getScanDfuDeviceObservable", "Error: ${getThrowableMessage(it)}")
                    if (it is TimeoutException) {
                        Observable.error(WssBleFirmwareUpdateException(WssBleFirmwareUpdateExceptionType.UNABLE_TO_FIND_DFU_DEVICE))
                    } else {
                        Observable.error(WssBleFirmwareUpdateException(WssBleFirmwareUpdateExceptionType.ERROR_SCANNING_FOR_DFU_DEVICE, it))
                    }
                }
    }



and then the upload
this.forceDeviceDisconnection()

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            DfuServiceInitiator.createDfuNotificationChannel(this.context)
        }

        this._updateStateObservable.onNext(WssBleFirmwareUpdateState.INITIALIZING_DFU)

        val observable = Observable.create<Boolean> {
            _dfuObservableEmitter = it
        }
        
        this is from the forum.gives me the same results

//        var numberOfPackets: Int
//        try {
//            numberOfPackets = 12
//        } catch (e: NumberFormatException) {
//            numberOfPackets = DfuServiceInitiator.DEFAULT_PRN_VALUE
//        }
//https://devzone.nordicsemi.com/f/nordic-q-a/50163/android-kotlin-sample-code-for-dfu
//        return observable.delay(6, TimeUnit.SECONDS).doOnSubscribe {
//        val starter = DfuServiceInitiator(this.deviceMacAddress)
//                .setDeviceName(this._deviceName)
//                .setKeepBond(false)
//                .setForceDfu(true)
//                .setPacketsReceiptNotificationsEnabled(false)
//                .setPacketsReceiptNotificationsValue(numberOfPackets)
//                .setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true)
//
//        starter.setZip(this._downloadedFwUri!!)
//
//
//        starter.start(this.context.applicationContext, DfuService::class.java)
//
//                    }.retry(4).take(1)
//                .onErrorResumeNext { it: Throwable ->
//                    this.disposeDfuServiceController()
//                    addLog("getUploadFirmwareObservable", "Error: ${getThrowableMessage(it)}")
//                    Observable.error(WssBleFirmwareUpdateException(WssBleFirmwareUpdateExceptionType.ERROR_UPLOADING_FIRMWARE, it))
//                }



        return observable.delay(6, TimeUnit.SECONDS).doOnSubscribe {
            addLog("getUploadFirmwareObservable", "Trying to start the service")
            Timber.d("getDfuObservable - doOnSubscribe - MacAddress ${deviceMacAddress}")

            this.disposeDfuServiceController()
            this._dfuServiceController = DfuServiceInitiator(this.deviceMacAddress)
                    .setDeviceName(this._deviceName)
                    .setForeground(true)
                    .setForceDfu(true)
                    .setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true)
                    .setZip(this._downloadedFwUri!!)
                    .setKeepBond(false)
                    .start(this.context.applicationContext, DfuService::class.java)
        }.retry(4).take(1)
                .onErrorResumeNext { it: Throwable ->
                    this.disposeDfuServiceController()
                    addLog("getUploadFirmwareObservable", "Error: ${getThrowableMessage(it)}")
                    Observable.error(WssBleFirmwareUpdateException(WssBleFirmwareUpdateExceptionType.ERROR_UPLOADING_FIRMWARE, it))
                }
Parents
  • Hi Techker, 

    Please provide information on: 

    - Which SDK and softdevice version you used in your legacy product ?

    - Which SDK and softdevice version you used in your new product ? 

    - Please described what exactly you did in your step and at which step the device didn't behave as it should ?

    - If you use nRF Connect/Toolbox app to do DFU can do you DFU for the new product? 

  • Hello, im waiting on Hardware team to reply for hardware used

    on my side we have the nordic DFU library no.nordicsemi.android:dfu:1.8.1

    On product i only have info on new hardware  BLE CPU\nRF52833

    i think(no news yet) nRF52832

    for Android issue: we update the firmware of the BLE with our app

    we connect -->set device in dfu-->upload fw then success

    new product we stop at set device in dfu we cannot reconnect to the device, it find the DFUTag but connect reconnect

    with Nrf tool box i dont see were to put device in dfu so i use a tool we did internal to set it to DFU. With the toolbox then we can reconnect and update the BLE fw. both old and new.

    im thinking its our library we are using that is to old?

    Update : new product

               SDK: nRF5_SDK_16.0.0_98a08e2;

               s140_nrf52_7.0.1_softdevice.

    BLE card of Older device:

    -          nRF5_SDK_11.0.0_89a8197;

    -          s132_nrf52_2.0.1_softdevice.

  • "new product we stop at set device in dfu we cannot reconnect to the device, it find the DFUTag but connect reconnect" => I assume you meant "it find the DFUTag but can not reconnect" ? 

    In nRFToolbox the app detects if the application has the DFU buttonless service or not and if it has it can automatically switch the application to DFU mode when you start DFU. So it will be one single step to switch the device to DFU mode and start DFU after that. 

    Have you tried to test using nRFToolbox to update your new product ? To see if you have the same problem as with your app ? 

  • Correct 

    i have tried the nRFToolbox  to update works fine.but again the library is updated..
    thats my issue im stuck on 1.8.1 
    just seen the soure on GitHub but i only see were to upload to dfu not to set device in dfu?
    In nRFToolbox the app detects if the application has the DFU buttonless service or not and if it has it can automatically switch the application to DFU mode when you start DFU. So it will be one single step to switch the device to DFU mode and start DFU after that. 
  • We need to figure out why your app doesn't want to connect to the bootloader after it switched. 
    If you put the device to bootloader manually (using nrf Connect for example) and then use your app to do DFU , would it work ? 
    DFU library v1.8.1 released Dec 2018, I don't think it's too old for the current bootloader. 

  • i will need to do a test app..cause are app needs a first handshake with the device to be able to connect to it..so if i put the device in dfu with another app it wont be able to connect..ok thx for the help il see what i can figure out.thx

Reply Children
No Data
Related