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))
                }
Related