diff --git a/README.md b/README.md index a0a7ed4..8e1bb2f 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,31 @@ # Web Bluetooth DFU Device firmware update with Web Bluetooth -Update device firmware via [Web Bluetooth](https://webbluetoothcg.github.io/web-bluetooth/) using the protocol here: +Update device firmware via [Web Bluetooth](https://webbluetoothcg.github.io/web-bluetooth/) following the protocol here: -[http://developer.nordicsemi.com/nRF51_SDK/nRF51_SDK_v8.x.x/doc/8.1.0/s110/html/a00103.html](http://developer.nordicsemi.com/nRF51_SDK/nRF51_SDK_v8.x.x/doc/8.1.0/s110/html/a00103.html) +http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk52.v0.9.2/bledfu_transport.html?cp=4_0_2_4_2_4 ## Device Configuration -Put this firmware onto an [nrf51822](https://www.nordicsemi.com/eng/Products/nRF51-DK): +You will need an [nRF51](https://www.nordicsemi.com/Products/nRF51-DK) or [nRF52](https://www.nordicsemi.com/Products/Bluetooth-Smart-Bluetooth-low-energy/nRF52-DK) development kit, flashed with the appropriate image: -[NRF51822_DFU_Test_BOOT.hex](https://thegecko.github.io/web-bluetooth-dfu/firmware/NRF51822_DFU_Test_BOOT.hex) +[nrf51_boot_s110.hex](https://thegecko.github.io/web-bluetooth-dfu/firmware/nrf51_boot_s110.hex) -Then reset the device. +[nrf52_boot_s132.hex](https://thegecko.github.io/web-bluetooth-dfu/firmware/nrf52_boot_s132.hex) ## Web Example -Open this site in a Web Bluetooth enabled browser: +Open this site in a [Web Bluetooth](https://webbluetoothcg.github.io/web-bluetooth/) enabled browser: [https://thegecko.github.io/web-bluetooth-dfu/](https://thegecko.github.io/web-bluetooth-dfu/) ## Node Example -Install the npm dependencies and run. +Clone this repository, install the npm dependencies and execute. ``` npm install -node example_node -``` \ No newline at end of file +node example_node +``` + +Where `````` is one of ```nrf51``` or ```nrf52```. \ No newline at end of file diff --git a/dist/dfu.js b/dist/dfu.js index d69681b..94379eb 100644 --- a/dist/dfu.js +++ b/dist/dfu.js @@ -1,10 +1,10 @@ /* @license * * Device firmware update with Web Bluetooth - * Version: 0.0.1 + * Version: 0.0.2 * * Protocol from: - * http://developer.nordicsemi.com/nRF51_SDK/nRF51_SDK_v8.x.x/doc/8.1.0/s110/html/a00103.html + * http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk52.v0.9.2/bledfu_transport.html?cp=4_0_2_4_2_4 * * The MIT License (MIT) * @@ -114,27 +114,32 @@ */ function writeMode(device) { return new Promise(function(resolve, reject) { - var controlChar = null; /* - // Disconnect event currently not implemented... + // TODO: once disconnect event is implemented we should resolve in its callback... device.addEventListener("gattserverdisconnected", () => { log("DFU Target issued GAP Disconnect and reset into Bootloader/DFU mode."); resolve(device); }); */ + var characteristics = null; + connect(device) .then(chars => { log("enabling notifications"); - controlChar = chars.controlChar; - return controlChar.startNotifications(); + characteristics = chars; + return characteristics.controlChar.startNotifications(); }) .then(() => { log("writing modeData"); - return controlChar.writeValue(new Uint8Array([1, 4])); + return characteristics.controlChar.writeValue(new Uint8Array([1, 4])); }) .then(() => { log("modeData written"); - resolve(device); // TODO: once disconnect event is implemented we should resolve in its callback... + // Hack to gracefully disconnect without disconnect event + setTimeout(() => { + characteristics.server.disconnect(); + resolve(device); + }, 2000); }) .catch(error => { error = "writeMode error: " + error; @@ -143,7 +148,7 @@ }); }); } - + /** * Contains basic functionality for performing safety checks on software updates for nRF5 based devices. * Init packet used for pre-checking to ensure the following image is compatible with the device. @@ -175,8 +180,9 @@ return versionChar.readValue() .then(data => { console.log('read versionChar'); - var major = data.getUint8(0); - var minor = data.getUint8(1); + var view = new DataView(data); + var major = view.getUint8(0); + var minor = view.getUint8(1); return transfer(chars, arrayBuffer, imageType, major, minor); }); } else { @@ -232,14 +238,14 @@ log("found packet characteristic"); packetChar = characteristic; service.getCharacteristic(versionUUID) - .then(characteristic => { // Older DFU implementations (from older Nordic SDKs) have no DFU Version characteristic. So this may fail. + // Older DFU implementations (from older Nordic SDKs) have no DFU Version characteristic. So this may fail. + .then(characteristic => { log("found version characteristic"); versionChar = characteristic; complete(); }) .catch(error => { - error += ' no version charactersitic found'; - log(error); + log("info: no version characteristic found"); complete(); }); }) @@ -382,7 +388,7 @@ case OPCODE.VALIDATE_FIRMWARE: log('complete, reset...'); /* - // Disconnect event currently not implemented + // TODO: Resolve in disconnect event handler when implemented in Web Bluetooth API. controlChar.service.device.addEventListener("gattserverdisconnected", () => { resolve(); }); @@ -390,7 +396,11 @@ controlChar.writeValue(new Uint8Array([OPCODE.ACTIVATE_IMAGE_AND_RESET])) .then(() => { log('image activated and dfu target reset'); - resolve(); // TODO: Resolve in disconnect event handler when implemented in Web Bluetooth API. + // Hack to gracefully disconnect without disconnect event + setTimeout(() => { + chars.server.disconnect(); + resolve(); + }, 2000); }) .catch(error => { error = "error resetting: " + error; diff --git a/example_node.js b/example_node.js index 7330544..7bc7f72 100644 --- a/example_node.js +++ b/example_node.js @@ -5,12 +5,30 @@ var fs = require('fs'); var log = console.log; dfu.addLogger(log); -var fileMask = "firmware/NRF51822_{0}_Rob_OTA.hex"; +var fileMask = ""; var fileName = null; +var deviceType = process.argv[2]; +if (!deviceType) { + deviceType = "nrf51"; + log("no device-type specified, defaulting to " + deviceType); +} + +switch(deviceType) { + case "nrf51": + fileMask = "firmware/nrf51_app_{0}.hex"; + break; + case "nrf52": + fileMask = "firmware/nrf52_app.hex"; + break; + default: + log("unknown device-type: " + deviceType); + process.exit(); +} + dfu.findDevice({ services: [0x180D] }) .then(device => { - fileName = fileMask.replace("{0}", device.name === "Hi_Rob" ? "Bye" : "Hi"); + fileName = fileMask.replace("{0}", device.name === "Hi_Rob" ? "bye" : "hi"); log("found device: " + device.name); log("using file name: " + fileName); diff --git a/example_web.html b/example_web.html index c7ff026..1020141 100644 --- a/example_web.html +++ b/example_web.html @@ -2,20 +2,35 @@ web-bluetooth-dfu + + + - - - +
+ + + + +
+ + + + +