Skip to content

Instantly share code, notes, and snippets.

@jwhitley
Created August 17, 2017 16:53
Show Gist options
  • Save jwhitley/5925f89ceba2520a6b322b3dbdeaf732 to your computer and use it in GitHub Desktop.
Save jwhitley/5925f89ceba2520a6b322b3dbdeaf732 to your computer and use it in GitHub Desktop.
// This is a "rough sketch" pulled from our application that shows how we use
// RxBluetoothKit and Nordic's DFU library together. It's more than
// pseudocode, yet not standalone, rigorously tested running code. A lot of
// details are simplified or omitted here, e.g. any device-specific details
// you may require, implementations for Nordic's DFU delegate protcols, etc.
import iOSDFULibrary // Nordic's DFU Library
import RxBluetoothKit
enum ExampleDeviceService: String, ServiceIdentifier {
case dfuUpdateService = "YOUR-DFU-GUID-GOES-HERE"
}
class FirmwareUpdater {
private let manager: BluetoothManager
static let dfuScanTimeout: RxTimeInterval = 10
lazy var dfuTimeoutScheduler: ConcurrentDispatchQueueScheduler =
ConcurrentDispatchQueueScheduler(queue: DispatchQueue(label: "com.example.rxbluetooth.timer"))
init() {
// We've found it best to create a separate BluetoothManager instance for
// each DFU activity to prevent a number of problems with non-DFU
// activities, e.g. scanning for and communicating with devices in normal
// usage may go wonky due to the CBCentralManager getting into an odd state.
self.manager = BluetoothManager(queue: .main, options: [
CBCentralManagerOptionRestoreIdentifierKey: "ExampleDFUCentralManager" as NSString
])
}
private func waitForBLE() -> Observable<BluetoothManager> {
return self.manager.rx_state
.filter { $0 == .poweredOn }
.take(1)
.map { _ in self.manager }
}
func updateBand(_ selectedFirmware: DFUFirmware) -> Observable<Void> {
var dfuScan = self.waitForBLE()
.flatMap { $0.scanForPeripherals(withServices: [ExampleDeviceService.dfuUpdateService.uuid], options:nil) }
.take(FirmwareUpdater.dfuScanTimeout, scheduler: dfuTimeoutScheduler)
return dfuScan
.subscribeOn(MainScheduler.instance)
.flatMap { scannedPeripheral -> Observable<Void> in
// We've let RxBluetoothKit handle the BLE workflow up to this point.
// Now extract the CBCentralManager and CBPeripheral and hand those off
// to Nordic's DFU library to initiate and complete the DFU process.
let centralManager = scannedPeripheral.peripheral.cbCentralManager
let peripheral = scannedPeripheral.peripheral.cbPeripheral
let initiator = DFUServiceInitiator(centralManager: centralManager, target: peripheral).with(firmware: selectedFirmware)
initiator.logger = self.delegate
initiator.delegate = self.delegate
initiator.progressDelegate = self.delegate
self.controller = initiator.start()
return Observable.just(())
}
}
}
extension FirmwareUpdater: LoggerDelegate, DFUServiceDelegate, DFUProgressDelegate {
// ... implementations for Nordic's DFU delegate protocols ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment