refactor(frontend): clean up and standardize code formatting across various JavaScript files and HTML templates

This commit is contained in:
2026-01-02 19:40:33 -06:00
parent 7aa1560523
commit fe55ec349b
19 changed files with 63967 additions and 16219 deletions

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
class Codec2Lib { class Codec2Lib {
static arrayBufferToBase64(buffer) { static arrayBufferToBase64(buffer) {
let binary = ""; let binary = "";
let bytes = new Uint8Array(buffer); let bytes = new Uint8Array(buffer);
@@ -97,19 +96,7 @@ class Codec2Lib {
static audioFileToRaw(buffer, filename) { static audioFileToRaw(buffer, filename) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const module = { const module = {
arguments: [ arguments: [filename, "-r", "8000", "-L", "-e", "signed-integer", "-b", "16", "-c", "1", "output.raw"],
filename,
"-r",
"8000",
"-L",
"-e",
"signed-integer",
"-b",
"16",
"-c",
"1",
"output.raw",
],
preRun: () => { preRun: () => {
module.FS.writeFile(filename, new Uint8Array(buffer)); module.FS.writeFile(filename, new Uint8Array(buffer));
}, },
@@ -123,5 +110,4 @@ class Codec2Lib {
SOXModule(module); SOXModule(module);
}); });
} }
} }

View File

@@ -2,9 +2,7 @@
* A simple class for recording microphone input and returning the audio encoded in codec2 * A simple class for recording microphone input and returning the audio encoded in codec2
*/ */
class Codec2MicrophoneRecorder { class Codec2MicrophoneRecorder {
constructor() { constructor() {
this.sampleRate = 8000; this.sampleRate = 8000;
this.codec2Mode = "1200"; this.codec2Mode = "1200";
this.audioChunks = []; this.audioChunks = [];
@@ -13,16 +11,14 @@ class Codec2MicrophoneRecorder {
this.audioWorkletNode = null; this.audioWorkletNode = null;
this.microphoneMediaStream = null; this.microphoneMediaStream = null;
this.mediaStreamSource = null; this.mediaStreamSource = null;
} }
async start() { async start() {
try { try {
// load audio worklet module // load audio worklet module
this.audioContext = new AudioContext({ sampleRate: this.sampleRate }); this.audioContext = new AudioContext({ sampleRate: this.sampleRate });
await this.audioContext.audioWorklet.addModule('assets/js/codec2-emscripten/processor.js'); await this.audioContext.audioWorklet.addModule("assets/js/codec2-emscripten/processor.js");
this.audioWorkletNode = new AudioWorkletNode(this.audioContext, 'audio-processor'); this.audioWorkletNode = new AudioWorkletNode(this.audioContext, "audio-processor");
// handle audio received from audio worklet // handle audio received from audio worklet
this.audioWorkletNode.port.onmessage = async (event) => { this.audioWorkletNode.port.onmessage = async (event) => {
@@ -40,42 +36,37 @@ class Codec2MicrophoneRecorder {
// successfully started recording // successfully started recording
return true; return true;
} catch (e) {
} catch(e) {
console.log(e); console.log(e);
return false; return false;
} }
} }
async stop() { async stop() {
// disconnect media stream source // disconnect media stream source
if(this.mediaStreamSource){ if (this.mediaStreamSource) {
this.mediaStreamSource.disconnect(); this.mediaStreamSource.disconnect();
} }
// stop using microphone // stop using microphone
if(this.microphoneMediaStream){ if (this.microphoneMediaStream) {
this.microphoneMediaStream.getTracks().forEach(track => track.stop()); this.microphoneMediaStream.getTracks().forEach((track) => track.stop());
} }
// disconnect the audio worklet node // disconnect the audio worklet node
if(this.audioWorkletNode){ if (this.audioWorkletNode) {
this.audioWorkletNode.disconnect(); this.audioWorkletNode.disconnect();
} }
// close audio context // close audio context
if(this.audioContext && this.audioContext.state !== "closed"){ if (this.audioContext && this.audioContext.state !== "closed") {
this.audioContext.close(); this.audioContext.close();
} }
// concatenate all audio chunks into a single array // concatenate all audio chunks into a single array
var fullAudio = []; var fullAudio = [];
for(const chunk of this.audioChunks){ for (const chunk of this.audioChunks) {
fullAudio = [ fullAudio = [...fullAudio, ...chunk];
...fullAudio,
...chunk,
]
} }
// convert audio to wav // convert audio to wav
@@ -86,7 +77,5 @@ class Codec2MicrophoneRecorder {
const encoded = await Codec2Lib.runEncode(this.codec2Mode, rawBuffer); const encoded = await Codec2Lib.runEncode(this.codec2Mode, rawBuffer);
return encoded; return encoded;
} }
} }

View File

@@ -1,127 +1,117 @@
<html> <html>
<body> <body>
<div> <div>
<div style="margin-bottom: 1rem">
<div>Select a *.wav audio file.</div>
<input id="file-input" type="file" accept="audio/wav" />
</div>
<div style="margin-bottom:1rem;"> <div style="margin-bottom: 1rem">
<div>Select a *.wav audio file.</div> <span>Select Codec2 Mode:</span>
<input id="file-input" type="file" accept="audio/wav"/> <select id="codec-mode">
</div> <option value="3200">3200</option>
<option value="2400">2400</option>
<option value="1600">1600</option>
<option value="1400">1400</option>
<option value="1300">1300</option>
<option value="1200">1200</option>
<option value="700C" selected>700C</option>
<option value="450">450</option>
<option value="450PWB">450PWB</option>
</select>
</div>
<div style="margin-bottom:1rem;"> <div style="margin-bottom: 1rem">
<span>Select Codec2 Mode:</span> <div>Click to encode audio file as Codec2</div>
<select id="codec-mode"> <button type="submit" onclick="encode()">Encode</button>
<option value="3200">3200</option> </div>
<option value="2400">2400</option>
<option value="1600">1600</option>
<option value="1400">1400</option>
<option value="1300">1300</option>
<option value="1200">1200</option>
<option value="700C" selected>700C</option>
<option value="450">450</option>
<option value="450PWB">450PWB</option>
</select>
</div>
<div style="margin-bottom:1rem;"> <div style="margin-bottom: 1rem">
<div>Click to encode audio file as Codec2</div> <div>Codec2 audio represented as Base64</div>
<button type="submit" onclick="encode()">Encode</button> <textarea id="encoded-output" style="width: 500px" rows="8"></textarea>
</div> </div>
<div style="margin-bottom:1rem;"> <div style="margin-bottom: 1rem">
<div>Codec2 audio represented as Base64</div> <div>Click to decode Codec2 audio back to WAVE audio</div>
<textarea id="encoded-output" style="width:500px" rows="8"></textarea> <button type="submit" onclick="decode()">Decode</button>
</div> </div>
<div style="margin-bottom:1rem;"> <div style="margin-bottom: 1rem">
<div>Click to decode Codec2 audio back to WAVE audio</div> <div>Decoded audio available to listen to</div>
<button type="submit" onclick="decode()">Decode</button> <audio id="decoded-audio" controls></audio>
</div> </div>
<div style="margin-bottom:1rem;"> <div style="margin-bottom: 1rem">
<div>Decoded audio available to listen to</div> <div>Input File Size: <span id="input-size">0 Bytes</span></div>
<audio id="decoded-audio" controls></audio> <div>Encoded Data Size: <span id="encoded-size">0 Bytes</span></div>
</div> <div>Decoded Data Size: <span id="decoded-size">0 Bytes</span></div>
</div>
</div>
<script src="c2enc.js"></script>
<script src="c2dec.js"></script>
<script src="sox.js"></script>
<script src="codec2-lib.js"></script>
<script>
// find elements
const codecModeElement = document.getElementById("codec-mode");
const encodedOutputElement = document.getElementById("encoded-output");
const fileInputElement = document.getElementById("file-input");
const decodedAudioElement = document.getElementById("decoded-audio");
const inputSizeElement = document.getElementById("input-size");
const encodedSizeElement = document.getElementById("encoded-size");
const decodedSizeElement = document.getElementById("decoded-size");
<div style="margin-bottom:1rem;"> // update file size stats on change
<div>Input File Size: <span id="input-size">0 Bytes</span></div> fileInputElement.onchange = function () {
<div>Encoded Data Size: <span id="encoded-size">0 Bytes</span></div> if (fileInputElement.files.length > 0) {
<div>Decoded Data Size: <span id="decoded-size">0 Bytes</span></div> const file = fileInputElement.files[0];
</div> inputSizeElement.innerText = formatBytes(file.size);
}
};
</div> async function encode() {
<script src="c2enc.js"></script> const file = fileInputElement.files[0];
<script src="c2dec.js"></script> if (!file) {
<script src="sox.js"></script> alert("select a file first");
<script src="codec2-lib.js"></script> return;
<script> }
// find elements const mode = codecModeElement.value;
const codecModeElement = document.getElementById("codec-mode");
const encodedOutputElement = document.getElementById("encoded-output");
const fileInputElement = document.getElementById("file-input");
const decodedAudioElement = document.getElementById("decoded-audio");
const inputSizeElement = document.getElementById("input-size");
const encodedSizeElement = document.getElementById("encoded-size");
const decodedSizeElement = document.getElementById("decoded-size");
// update file size stats on change const buffer = await Codec2Lib.readFileAsArrayBuffer(file);
fileInputElement.onchange = function() { const rawBuffer = await Codec2Lib.audioFileToRaw(buffer, file.name || "input.wav");
if(fileInputElement.files.length > 0){ const encoded = await Codec2Lib.runEncode(mode, rawBuffer);
const file = fileInputElement.files[0];
inputSizeElement.innerText = formatBytes(file.size);
}
}
async function encode() { encodedOutputElement.value = Codec2Lib.arrayBufferToBase64(encoded);
inputSizeElement.innerText = formatBytes(file.size);
encodedSizeElement.innerText = formatBytes(encoded.length);
}
const file = fileInputElement.files[0]; async function decode() {
if(!file){ const mode = codecModeElement.value;
alert("select a file first"); const input = encodedOutputElement.value;
return;
}
const mode = codecModeElement.value; const encoded = Codec2Lib.base64ToArrayBuffer(input);
const decodedRaw = await Codec2Lib.runDecode(mode, encoded);
const decodedWav = await Codec2Lib.rawToWav(decodedRaw);
const buffer = await Codec2Lib.readFileAsArrayBuffer(file); decodedAudioElement.src = URL.createObjectURL(new Blob([decodedWav], { type: "audio/wav" }));
const rawBuffer = await Codec2Lib.audioFileToRaw(buffer, file.name || "input.wav"); decodedSizeElement.innerText = formatBytes(decodedWav.length);
const encoded = await Codec2Lib.runEncode(mode, rawBuffer); }
encodedOutputElement.value = Codec2Lib.arrayBufferToBase64(encoded); function formatBytes(bytes) {
inputSizeElement.innerText = formatBytes(file.size); if (bytes === 0) {
encodedSizeElement.innerText = formatBytes(encoded.length); return "0 Bytes";
}
} const k = 1024;
const decimals = 0;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
async function decode() { const i = Math.floor(Math.log(bytes) / Math.log(k));
const mode = codecModeElement.value; return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + " " + sizes[i];
const input = encodedOutputElement.value; }
</script>
const encoded = Codec2Lib.base64ToArrayBuffer(input); </body>
const decodedRaw = await Codec2Lib.runDecode(mode, encoded);
const decodedWav = await Codec2Lib.rawToWav(decodedRaw);
decodedAudioElement.src = URL.createObjectURL(new Blob([decodedWav], { type: "audio/wav" }));
decodedSizeElement.innerText = formatBytes(decodedWav.length);
}
function formatBytes(bytes) {
if(bytes === 0){
return '0 Bytes';
}
const k = 1024;
const decimals = 0;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
}
</script>
</body>
</html> </html>

View File

@@ -1,5 +1,4 @@
class AudioProcessor extends AudioWorkletProcessor { class AudioProcessor extends AudioWorkletProcessor {
constructor() { constructor() {
super(); super();
this.bufferSize = 4096; // Adjust the buffer size as needed this.bufferSize = 4096; // Adjust the buffer size as needed
@@ -52,4 +51,4 @@ class AudioProcessor extends AudioWorkletProcessor {
} }
} }
registerProcessor('audio-processor', AudioProcessor); registerProcessor("audio-processor", AudioProcessor);

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,15 @@
class WavEncoder { class WavEncoder {
static encodeWAV(samples, sampleRate = 8000, numChannels = 1) { static encodeWAV(samples, sampleRate = 8000, numChannels = 1) {
const buffer = new ArrayBuffer(44 + samples.length * 2); const buffer = new ArrayBuffer(44 + samples.length * 2);
const view = new DataView(buffer); const view = new DataView(buffer);
// RIFF chunk descriptor // RIFF chunk descriptor
this.writeString(view, 0, 'RIFF'); this.writeString(view, 0, "RIFF");
view.setUint32(4, 36 + samples.length * 2, true); // file length view.setUint32(4, 36 + samples.length * 2, true); // file length
this.writeString(view, 8, 'WAVE'); this.writeString(view, 8, "WAVE");
// fmt sub-chunk // fmt sub-chunk
this.writeString(view, 12, 'fmt '); this.writeString(view, 12, "fmt ");
view.setUint32(16, 16, true); // sub-chunk size view.setUint32(16, 16, true); // sub-chunk size
view.setUint16(20, 1, true); // audio format (1 = PCM) view.setUint16(20, 1, true); // audio format (1 = PCM)
view.setUint16(22, numChannels, true); // number of channels view.setUint16(22, numChannels, true); // number of channels
@@ -21,27 +19,25 @@ class WavEncoder {
view.setUint16(34, 16, true); // bits per sample view.setUint16(34, 16, true); // bits per sample
// data sub-chunk // data sub-chunk
this.writeString(view, 36, 'data'); this.writeString(view, 36, "data");
view.setUint32(40, samples.length * 2, true); // data chunk length view.setUint32(40, samples.length * 2, true); // data chunk length
// write the PCM samples // write the PCM samples
this.floatTo16BitPCM(view, 44, samples); this.floatTo16BitPCM(view, 44, samples);
return buffer; return buffer;
} }
static writeString(view, offset, string) { static writeString(view, offset, string) {
for(let i = 0; i < string.length; i++){ for (let i = 0; i < string.length; i++) {
view.setUint8(offset + i, string.charCodeAt(i)); view.setUint8(offset + i, string.charCodeAt(i));
} }
} }
static floatTo16BitPCM(output, offset, input) { static floatTo16BitPCM(output, offset, input) {
for(let i = 0; i < input.length; i++, offset += 2){ for (let i = 0; i < input.length; i++, offset += 2) {
const s = Math.max(-1, Math.min(1, input[i])); const s = Math.max(-1, Math.min(1, input[i]));
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true); output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);
} }
} }
} }

View File

File diff suppressed because one or more lines are too long

View File

@@ -1,17 +1,17 @@
{ {
"name": "MeshChat", "name": "MeshChat",
"short_name": "MeshChat", "short_name": "MeshChat",
"description": "A simple mesh network communications app powered by the Reticulum Network Stack.", "description": "A simple mesh network communications app powered by the Reticulum Network Stack.",
"scope": "/", "scope": "/",
"start_url": "/", "start_url": "/",
"icons": [ "icons": [
{ {
"src": "/favicons/favicon-512x512.png", "src": "/favicons/favicon-512x512.png",
"sizes": "512x512", "sizes": "512x512",
"type": "image/png" "type": "image/png"
} }
], ],
"display": "standalone", "display": "standalone",
"theme_color": "#FFFFFF", "theme_color": "#FFFFFF",
"background_color": "#FFFFFF" "background_color": "#FFFFFF"
} }

View File

@@ -53,11 +53,11 @@ Once the firmware is flashed to the device, you will need to provision the EEPRO
- Set firmware hash in eeprom - Set firmware hash in eeprom
- Collect device info - Collect device info
- `product` - `product`
- `model` - `model`
- `hardware_revision` - `hardware_revision`
- `serial_number` - `serial_number`
- `made` (unix timestamp of device creation) - `made` (unix timestamp of device creation)
- Write device info to eeprom - Write device info to eeprom
- Create an MD5 checksum of the device info - Create an MD5 checksum of the device info
- Write 16 byte device info checksum to eeprom - Write 16 byte device info checksum to eeprom

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,268 +1,256 @@
;(function (root, factory) { (function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
module.exports = exports = factory(require("./core")); module.exports = exports = factory(require("./core"));
} } else if (typeof define === "function" && define.amd) {
else if (typeof define === "function" && define.amd) { // AMD
// AMD define(["./core"], factory);
define(["./core"], factory); } else {
} // Global (browser)
else { factory(root.CryptoJS);
// Global (browser) }
factory(root.CryptoJS); })(this, function (CryptoJS) {
} (function (Math) {
}(this, function (CryptoJS) { // Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var Hasher = C_lib.Hasher;
var C_algo = C.algo;
(function (Math) { // Constants table
// Shortcuts var T = [];
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var Hasher = C_lib.Hasher;
var C_algo = C.algo;
// Constants table // Compute constants
var T = []; (function () {
for (var i = 0; i < 64; i++) {
T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;
}
})();
// Compute constants /**
(function () { * MD5 hash algorithm.
for (var i = 0; i < 64; i++) { */
T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0; var MD5 = (C_algo.MD5 = Hasher.extend({
} _doReset: function () {
}()); this._hash = new WordArray.init([0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]);
},
/** _doProcessBlock: function (M, offset) {
* MD5 hash algorithm. // Swap endian
*/ for (var i = 0; i < 16; i++) {
var MD5 = C_algo.MD5 = Hasher.extend({ // Shortcuts
_doReset: function () { var offset_i = offset + i;
this._hash = new WordArray.init([ var M_offset_i = M[offset_i];
0x67452301, 0xefcdab89,
0x98badcfe, 0x10325476
]);
},
_doProcessBlock: function (M, offset) { M[offset_i] =
// Swap endian (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
for (var i = 0; i < 16; i++) { (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00);
// Shortcuts }
var offset_i = offset + i;
var M_offset_i = M[offset_i];
M[offset_i] = ( // Shortcuts
(((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | var H = this._hash.words;
(((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
);
}
// Shortcuts var M_offset_0 = M[offset + 0];
var H = this._hash.words; var M_offset_1 = M[offset + 1];
var M_offset_2 = M[offset + 2];
var M_offset_3 = M[offset + 3];
var M_offset_4 = M[offset + 4];
var M_offset_5 = M[offset + 5];
var M_offset_6 = M[offset + 6];
var M_offset_7 = M[offset + 7];
var M_offset_8 = M[offset + 8];
var M_offset_9 = M[offset + 9];
var M_offset_10 = M[offset + 10];
var M_offset_11 = M[offset + 11];
var M_offset_12 = M[offset + 12];
var M_offset_13 = M[offset + 13];
var M_offset_14 = M[offset + 14];
var M_offset_15 = M[offset + 15];
var M_offset_0 = M[offset + 0]; // Working varialbes
var M_offset_1 = M[offset + 1]; var a = H[0];
var M_offset_2 = M[offset + 2]; var b = H[1];
var M_offset_3 = M[offset + 3]; var c = H[2];
var M_offset_4 = M[offset + 4]; var d = H[3];
var M_offset_5 = M[offset + 5];
var M_offset_6 = M[offset + 6];
var M_offset_7 = M[offset + 7];
var M_offset_8 = M[offset + 8];
var M_offset_9 = M[offset + 9];
var M_offset_10 = M[offset + 10];
var M_offset_11 = M[offset + 11];
var M_offset_12 = M[offset + 12];
var M_offset_13 = M[offset + 13];
var M_offset_14 = M[offset + 14];
var M_offset_15 = M[offset + 15];
// Working varialbes // Computation
var a = H[0]; a = FF(a, b, c, d, M_offset_0, 7, T[0]);
var b = H[1]; d = FF(d, a, b, c, M_offset_1, 12, T[1]);
var c = H[2]; c = FF(c, d, a, b, M_offset_2, 17, T[2]);
var d = H[3]; b = FF(b, c, d, a, M_offset_3, 22, T[3]);
a = FF(a, b, c, d, M_offset_4, 7, T[4]);
d = FF(d, a, b, c, M_offset_5, 12, T[5]);
c = FF(c, d, a, b, M_offset_6, 17, T[6]);
b = FF(b, c, d, a, M_offset_7, 22, T[7]);
a = FF(a, b, c, d, M_offset_8, 7, T[8]);
d = FF(d, a, b, c, M_offset_9, 12, T[9]);
c = FF(c, d, a, b, M_offset_10, 17, T[10]);
b = FF(b, c, d, a, M_offset_11, 22, T[11]);
a = FF(a, b, c, d, M_offset_12, 7, T[12]);
d = FF(d, a, b, c, M_offset_13, 12, T[13]);
c = FF(c, d, a, b, M_offset_14, 17, T[14]);
b = FF(b, c, d, a, M_offset_15, 22, T[15]);
// Computation a = GG(a, b, c, d, M_offset_1, 5, T[16]);
a = FF(a, b, c, d, M_offset_0, 7, T[0]); d = GG(d, a, b, c, M_offset_6, 9, T[17]);
d = FF(d, a, b, c, M_offset_1, 12, T[1]); c = GG(c, d, a, b, M_offset_11, 14, T[18]);
c = FF(c, d, a, b, M_offset_2, 17, T[2]); b = GG(b, c, d, a, M_offset_0, 20, T[19]);
b = FF(b, c, d, a, M_offset_3, 22, T[3]); a = GG(a, b, c, d, M_offset_5, 5, T[20]);
a = FF(a, b, c, d, M_offset_4, 7, T[4]); d = GG(d, a, b, c, M_offset_10, 9, T[21]);
d = FF(d, a, b, c, M_offset_5, 12, T[5]); c = GG(c, d, a, b, M_offset_15, 14, T[22]);
c = FF(c, d, a, b, M_offset_6, 17, T[6]); b = GG(b, c, d, a, M_offset_4, 20, T[23]);
b = FF(b, c, d, a, M_offset_7, 22, T[7]); a = GG(a, b, c, d, M_offset_9, 5, T[24]);
a = FF(a, b, c, d, M_offset_8, 7, T[8]); d = GG(d, a, b, c, M_offset_14, 9, T[25]);
d = FF(d, a, b, c, M_offset_9, 12, T[9]); c = GG(c, d, a, b, M_offset_3, 14, T[26]);
c = FF(c, d, a, b, M_offset_10, 17, T[10]); b = GG(b, c, d, a, M_offset_8, 20, T[27]);
b = FF(b, c, d, a, M_offset_11, 22, T[11]); a = GG(a, b, c, d, M_offset_13, 5, T[28]);
a = FF(a, b, c, d, M_offset_12, 7, T[12]); d = GG(d, a, b, c, M_offset_2, 9, T[29]);
d = FF(d, a, b, c, M_offset_13, 12, T[13]); c = GG(c, d, a, b, M_offset_7, 14, T[30]);
c = FF(c, d, a, b, M_offset_14, 17, T[14]); b = GG(b, c, d, a, M_offset_12, 20, T[31]);
b = FF(b, c, d, a, M_offset_15, 22, T[15]);
a = GG(a, b, c, d, M_offset_1, 5, T[16]); a = HH(a, b, c, d, M_offset_5, 4, T[32]);
d = GG(d, a, b, c, M_offset_6, 9, T[17]); d = HH(d, a, b, c, M_offset_8, 11, T[33]);
c = GG(c, d, a, b, M_offset_11, 14, T[18]); c = HH(c, d, a, b, M_offset_11, 16, T[34]);
b = GG(b, c, d, a, M_offset_0, 20, T[19]); b = HH(b, c, d, a, M_offset_14, 23, T[35]);
a = GG(a, b, c, d, M_offset_5, 5, T[20]); a = HH(a, b, c, d, M_offset_1, 4, T[36]);
d = GG(d, a, b, c, M_offset_10, 9, T[21]); d = HH(d, a, b, c, M_offset_4, 11, T[37]);
c = GG(c, d, a, b, M_offset_15, 14, T[22]); c = HH(c, d, a, b, M_offset_7, 16, T[38]);
b = GG(b, c, d, a, M_offset_4, 20, T[23]); b = HH(b, c, d, a, M_offset_10, 23, T[39]);
a = GG(a, b, c, d, M_offset_9, 5, T[24]); a = HH(a, b, c, d, M_offset_13, 4, T[40]);
d = GG(d, a, b, c, M_offset_14, 9, T[25]); d = HH(d, a, b, c, M_offset_0, 11, T[41]);
c = GG(c, d, a, b, M_offset_3, 14, T[26]); c = HH(c, d, a, b, M_offset_3, 16, T[42]);
b = GG(b, c, d, a, M_offset_8, 20, T[27]); b = HH(b, c, d, a, M_offset_6, 23, T[43]);
a = GG(a, b, c, d, M_offset_13, 5, T[28]); a = HH(a, b, c, d, M_offset_9, 4, T[44]);
d = GG(d, a, b, c, M_offset_2, 9, T[29]); d = HH(d, a, b, c, M_offset_12, 11, T[45]);
c = GG(c, d, a, b, M_offset_7, 14, T[30]); c = HH(c, d, a, b, M_offset_15, 16, T[46]);
b = GG(b, c, d, a, M_offset_12, 20, T[31]); b = HH(b, c, d, a, M_offset_2, 23, T[47]);
a = HH(a, b, c, d, M_offset_5, 4, T[32]); a = II(a, b, c, d, M_offset_0, 6, T[48]);
d = HH(d, a, b, c, M_offset_8, 11, T[33]); d = II(d, a, b, c, M_offset_7, 10, T[49]);
c = HH(c, d, a, b, M_offset_11, 16, T[34]); c = II(c, d, a, b, M_offset_14, 15, T[50]);
b = HH(b, c, d, a, M_offset_14, 23, T[35]); b = II(b, c, d, a, M_offset_5, 21, T[51]);
a = HH(a, b, c, d, M_offset_1, 4, T[36]); a = II(a, b, c, d, M_offset_12, 6, T[52]);
d = HH(d, a, b, c, M_offset_4, 11, T[37]); d = II(d, a, b, c, M_offset_3, 10, T[53]);
c = HH(c, d, a, b, M_offset_7, 16, T[38]); c = II(c, d, a, b, M_offset_10, 15, T[54]);
b = HH(b, c, d, a, M_offset_10, 23, T[39]); b = II(b, c, d, a, M_offset_1, 21, T[55]);
a = HH(a, b, c, d, M_offset_13, 4, T[40]); a = II(a, b, c, d, M_offset_8, 6, T[56]);
d = HH(d, a, b, c, M_offset_0, 11, T[41]); d = II(d, a, b, c, M_offset_15, 10, T[57]);
c = HH(c, d, a, b, M_offset_3, 16, T[42]); c = II(c, d, a, b, M_offset_6, 15, T[58]);
b = HH(b, c, d, a, M_offset_6, 23, T[43]); b = II(b, c, d, a, M_offset_13, 21, T[59]);
a = HH(a, b, c, d, M_offset_9, 4, T[44]); a = II(a, b, c, d, M_offset_4, 6, T[60]);
d = HH(d, a, b, c, M_offset_12, 11, T[45]); d = II(d, a, b, c, M_offset_11, 10, T[61]);
c = HH(c, d, a, b, M_offset_15, 16, T[46]); c = II(c, d, a, b, M_offset_2, 15, T[62]);
b = HH(b, c, d, a, M_offset_2, 23, T[47]); b = II(b, c, d, a, M_offset_9, 21, T[63]);
a = II(a, b, c, d, M_offset_0, 6, T[48]); // Intermediate hash value
d = II(d, a, b, c, M_offset_7, 10, T[49]); H[0] = (H[0] + a) | 0;
c = II(c, d, a, b, M_offset_14, 15, T[50]); H[1] = (H[1] + b) | 0;
b = II(b, c, d, a, M_offset_5, 21, T[51]); H[2] = (H[2] + c) | 0;
a = II(a, b, c, d, M_offset_12, 6, T[52]); H[3] = (H[3] + d) | 0;
d = II(d, a, b, c, M_offset_3, 10, T[53]); },
c = II(c, d, a, b, M_offset_10, 15, T[54]);
b = II(b, c, d, a, M_offset_1, 21, T[55]);
a = II(a, b, c, d, M_offset_8, 6, T[56]);
d = II(d, a, b, c, M_offset_15, 10, T[57]);
c = II(c, d, a, b, M_offset_6, 15, T[58]);
b = II(b, c, d, a, M_offset_13, 21, T[59]);
a = II(a, b, c, d, M_offset_4, 6, T[60]);
d = II(d, a, b, c, M_offset_11, 10, T[61]);
c = II(c, d, a, b, M_offset_2, 15, T[62]);
b = II(b, c, d, a, M_offset_9, 21, T[63]);
// Intermediate hash value _doFinalize: function () {
H[0] = (H[0] + a) | 0; // Shortcuts
H[1] = (H[1] + b) | 0; var data = this._data;
H[2] = (H[2] + c) | 0; var dataWords = data.words;
H[3] = (H[3] + d) | 0;
},
_doFinalize: function () { var nBitsTotal = this._nDataBytes * 8;
// Shortcuts var nBitsLeft = data.sigBytes * 8;
var data = this._data;
var dataWords = data.words;
var nBitsTotal = this._nDataBytes * 8; // Add padding
var nBitsLeft = data.sigBytes * 8; dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - (nBitsLeft % 32));
// Add padding var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); var nBitsTotalL = nBitsTotal;
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] =
(((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) |
(((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00);
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] =
(((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) |
(((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00);
var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000); data.sigBytes = (dataWords.length + 1) * 4;
var nBitsTotalL = nBitsTotal;
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (
(((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) |
(((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00)
);
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
(((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) |
(((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00)
);
data.sigBytes = (dataWords.length + 1) * 4; // Hash final blocks
this._process();
// Hash final blocks // Shortcuts
this._process(); var hash = this._hash;
var H = hash.words;
// Shortcuts // Swap endian
var hash = this._hash; for (var i = 0; i < 4; i++) {
var H = hash.words; // Shortcut
var H_i = H[i];
// Swap endian H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
for (var i = 0; i < 4; i++) { }
// Shortcut
var H_i = H[i];
H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | // Return final computed hash
(((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); return hash;
} },
// Return final computed hash clone: function () {
return hash; var clone = Hasher.clone.call(this);
}, clone._hash = this._hash.clone();
clone: function () { return clone;
var clone = Hasher.clone.call(this); },
clone._hash = this._hash.clone(); }));
return clone; function FF(a, b, c, d, x, s, t) {
} var n = a + ((b & c) | (~b & d)) + x + t;
}); return ((n << s) | (n >>> (32 - s))) + b;
}
function FF(a, b, c, d, x, s, t) { function GG(a, b, c, d, x, s, t) {
var n = a + ((b & c) | (~b & d)) + x + t; var n = a + ((b & d) | (c & ~d)) + x + t;
return ((n << s) | (n >>> (32 - s))) + b; return ((n << s) | (n >>> (32 - s))) + b;
} }
function GG(a, b, c, d, x, s, t) { function HH(a, b, c, d, x, s, t) {
var n = a + ((b & d) | (c & ~d)) + x + t; var n = a + (b ^ c ^ d) + x + t;
return ((n << s) | (n >>> (32 - s))) + b; return ((n << s) | (n >>> (32 - s))) + b;
} }
function HH(a, b, c, d, x, s, t) { function II(a, b, c, d, x, s, t) {
var n = a + (b ^ c ^ d) + x + t; var n = a + (c ^ (b | ~d)) + x + t;
return ((n << s) | (n >>> (32 - s))) + b; return ((n << s) | (n >>> (32 - s))) + b;
} }
function II(a, b, c, d, x, s, t) { /**
var n = a + (c ^ (b | ~d)) + x + t; * Shortcut function to the hasher's object interface.
return ((n << s) | (n >>> (32 - s))) + b; *
} * @param {WordArray|string} message The message to hash.
*
* @return {WordArray} The hash.
*
* @static
*
* @example
*
* var hash = CryptoJS.MD5('message');
* var hash = CryptoJS.MD5(wordArray);
*/
C.MD5 = Hasher._createHelper(MD5);
/** /**
* Shortcut function to the hasher's object interface. * Shortcut function to the HMAC's object interface.
* *
* @param {WordArray|string} message The message to hash. * @param {WordArray|string} message The message to hash.
* * @param {WordArray|string} key The secret key.
* @return {WordArray} The hash. *
* * @return {WordArray} The HMAC.
* @static *
* * @static
* @example *
* * @example
* var hash = CryptoJS.MD5('message'); *
* var hash = CryptoJS.MD5(wordArray); * var hmac = CryptoJS.HmacMD5(message, key);
*/ */
C.MD5 = Hasher._createHelper(MD5); C.HmacMD5 = Hasher._createHmacHelper(MD5);
})(Math);
/** return CryptoJS.MD5;
* Shortcut function to the HMAC's object interface. });
*
* @param {WordArray|string} message The message to hash.
* @param {WordArray|string} key The secret key.
*
* @return {WordArray} The HMAC.
*
* @static
*
* @example
*
* var hmac = CryptoJS.HmacMD5(message, key);
*/
C.HmacMD5 = Hasher._createHmacHelper(MD5);
}(Math));
return CryptoJS.MD5;
}));

View File

File diff suppressed because one or more lines are too long

View File

@@ -3,7 +3,6 @@
* https://github.com/adafruit/Adafruit_nRF52_nrfutil/blob/master/nordicsemi/dfu/dfu_transport_serial.py * https://github.com/adafruit/Adafruit_nRF52_nrfutil/blob/master/nordicsemi/dfu/dfu_transport_serial.py
*/ */
class Nrf52DfuFlasher { class Nrf52DfuFlasher {
DFU_TOUCH_BAUD = 1200; DFU_TOUCH_BAUD = 1200;
SERIAL_PORT_OPEN_WAIT_TIME = 0.1; SERIAL_PORT_OPEN_WAIT_TIME = 0.1;
TOUCH_RESET_WAIT_TIME = 1.5; TOUCH_RESET_WAIT_TIME = 1.5;
@@ -23,8 +22,8 @@ class Nrf52DfuFlasher {
FLASH_PAGE_SIZE = 4096; FLASH_PAGE_SIZE = 4096;
FLASH_PAGE_ERASE_TIME = 0.0897; FLASH_PAGE_ERASE_TIME = 0.0897;
FLASH_WORD_WRITE_TIME = 0.000100; FLASH_WORD_WRITE_TIME = 0.0001;
FLASH_PAGE_WRITE_TIME = (this.FLASH_PAGE_SIZE/4) * this.FLASH_WORD_WRITE_TIME; FLASH_PAGE_WRITE_TIME = (this.FLASH_PAGE_SIZE / 4) * this.FLASH_WORD_WRITE_TIME;
// The DFU packet max size // The DFU packet max size
DFU_PACKET_MAX_SIZE = 512; DFU_PACKET_MAX_SIZE = 512;
@@ -66,7 +65,6 @@ class Nrf52DfuFlasher {
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async enterDfuMode() { async enterDfuMode() {
// open port // open port
await this.serialPort.open({ await this.serialPort.open({
baudRate: this.DFU_TOUCH_BAUD, baudRate: this.DFU_TOUCH_BAUD,
@@ -80,7 +78,6 @@ class Nrf52DfuFlasher {
// wait TOUCH_RESET_WAIT_TIME for device to enter into DFU mode // wait TOUCH_RESET_WAIT_TIME for device to enter into DFU mode
await this.sleepMillis(this.TOUCH_RESET_WAIT_TIME * 1000); await this.sleepMillis(this.TOUCH_RESET_WAIT_TIME * 1000);
} }
/** /**
@@ -90,7 +87,6 @@ class Nrf52DfuFlasher {
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async flash(firmwareZipBlob, progressCallback) { async flash(firmwareZipBlob, progressCallback) {
// read zip file // read zip file
const blobReader = new window.zip.BlobReader(firmwareZipBlob); const blobReader = new window.zip.BlobReader(firmwareZipBlob);
const zipReader = new window.zip.ZipReader(blobReader); const zipReader = new window.zip.ZipReader(blobReader);
@@ -98,7 +94,7 @@ class Nrf52DfuFlasher {
// find manifest file // find manifest file
const manifestFile = zipEntries.find((zipEntry) => zipEntry.filename === "manifest.json"); const manifestFile = zipEntries.find((zipEntry) => zipEntry.filename === "manifest.json");
if(!manifestFile){ if (!manifestFile) {
throw "manifest.json not found in firmware file!"; throw "manifest.json not found in firmware file!";
} }
@@ -122,10 +118,9 @@ class Nrf52DfuFlasher {
// self._dfu_send_image(HexType.BOOTLOADER, self.manifest.bootloader) // self._dfu_send_image(HexType.BOOTLOADER, self.manifest.bootloader)
// flash application image // flash application image
if(manifest.application){ if (manifest.application) {
await this.dfuSendImage(this.HEX_TYPE_APPLICATION, zipEntries, manifest.application, progressCallback); await this.dfuSendImage(this.HEX_TYPE_APPLICATION, zipEntries, manifest.application, progressCallback);
} }
} }
/** /**
@@ -137,7 +132,6 @@ class Nrf52DfuFlasher {
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async dfuSendImage(programMode, zipEntries, firmwareManifest, progressCallback) { async dfuSendImage(programMode, zipEntries, firmwareManifest, progressCallback) {
// open port // open port
await this.serialPort.open({ await this.serialPort.open({
baudRate: this.FLASH_BAUD, baudRate: this.FLASH_BAUD,
@@ -147,9 +141,9 @@ class Nrf52DfuFlasher {
await this.sleepMillis(this.SERIAL_PORT_OPEN_WAIT_TIME * 1000); await this.sleepMillis(this.SERIAL_PORT_OPEN_WAIT_TIME * 1000);
// file sizes // file sizes
var softdeviceSize = 0 var softdeviceSize = 0;
var bootloaderSize = 0 var bootloaderSize = 0;
var applicationSize = 0 var applicationSize = 0;
// read bin file (firmware) // read bin file (firmware)
const binFile = zipEntries.find((zipEntry) => zipEntry.filename === firmwareManifest.bin_file); const binFile = zipEntries.find((zipEntry) => zipEntry.filename === firmwareManifest.bin_file);
@@ -160,12 +154,12 @@ class Nrf52DfuFlasher {
const init_packet = await datFile.getData(new window.zip.Uint8ArrayWriter()); const init_packet = await datFile.getData(new window.zip.Uint8ArrayWriter());
// only support flashing application for now // only support flashing application for now
if(programMode !== this.HEX_TYPE_APPLICATION){ if (programMode !== this.HEX_TYPE_APPLICATION) {
throw "not implemented"; throw "not implemented";
} }
// determine application size // determine application size
if(programMode === this.HEX_TYPE_APPLICATION){ if (programMode === this.HEX_TYPE_APPLICATION) {
applicationSize = firmware.length; applicationSize = firmware.length;
} }
@@ -180,7 +174,6 @@ class Nrf52DfuFlasher {
// todo // todo
// sleep(self.dfu_transport.get_activate_wait_time()) // sleep(self.dfu_transport.get_activate_wait_time())
} }
/** /**
@@ -190,21 +183,19 @@ class Nrf52DfuFlasher {
* @return {number} - Calculated CRC value of binaryData * @return {number} - Calculated CRC value of binaryData
*/ */
calcCrc16(binaryData, crc = 0xffff) { calcCrc16(binaryData, crc = 0xffff) {
if (!(binaryData instanceof Uint8Array)) {
if(!(binaryData instanceof Uint8Array)){
throw new Error("calcCrc16 requires Uint8Array input"); throw new Error("calcCrc16 requires Uint8Array input");
} }
for(let b of binaryData){ for (let b of binaryData) {
crc = (crc >> 8 & 0x00FF) | (crc << 8 & 0xFF00); crc = ((crc >> 8) & 0x00ff) | ((crc << 8) & 0xff00);
crc ^= b; crc ^= b;
crc ^= (crc & 0x00FF) >> 4; crc ^= (crc & 0x00ff) >> 4;
crc ^= (crc << 8) << 4; crc ^= (crc << 8) << 4;
crc ^= ((crc & 0x00FF) << 4) << 1; crc ^= ((crc & 0x00ff) << 4) << 1;
} }
return crc & 0xFFFF; return crc & 0xffff;
} }
/** /**
@@ -214,24 +205,22 @@ class Nrf52DfuFlasher {
* @returns {*[]} * @returns {*[]}
*/ */
slipEncodeEscChars(dataIn) { slipEncodeEscChars(dataIn) {
let result = []; let result = [];
for(let i = 0; i < dataIn.length; i++){ for (let i = 0; i < dataIn.length; i++) {
let char = dataIn[i]; let char = dataIn[i];
if(char === 0xC0){ if (char === 0xc0) {
result.push(0xDB); result.push(0xdb);
result.push(0xDC); result.push(0xdc);
} else if(char === 0xDB) { } else if (char === 0xdb) {
result.push(0xDB); result.push(0xdb);
result.push(0xDD); result.push(0xdd);
} else { } else {
result.push(char); result.push(char);
} }
} }
return result; return result;
} }
/** /**
@@ -241,7 +230,6 @@ class Nrf52DfuFlasher {
* @returns {*[]} * @returns {*[]}
*/ */
createHciPacketFromFrame(frame) { createHciPacketFromFrame(frame) {
// increase sequence number, but roll over at 8 // increase sequence number, but roll over at 8
this.sequenceNumber = (this.sequenceNumber + 1) % 8; this.sequenceNumber = (this.sequenceNumber + 1) % 8;
@@ -251,27 +239,19 @@ class Nrf52DfuFlasher {
this.DATA_INTEGRITY_CHECK_PRESENT, this.DATA_INTEGRITY_CHECK_PRESENT,
this.RELIABLE_PACKET, this.RELIABLE_PACKET,
this.HCI_PACKET_TYPE, this.HCI_PACKET_TYPE,
frame.length, frame.length
); );
// create packet data // create packet data
let data = [ let data = [...slipHeaderBytes, ...frame];
...slipHeaderBytes,
...frame,
];
// add crc of data // add crc of data
const crc = this.calcCrc16(new Uint8Array(data), 0xffff); const crc = this.calcCrc16(new Uint8Array(data), 0xffff);
data.push(crc & 0xFF); data.push(crc & 0xff);
data.push((crc & 0xFF00) >> 8); data.push((crc & 0xff00) >> 8);
// add escape characters // add escape characters
return [ return [0xc0, ...this.slipEncodeEscChars(data), 0xc0];
0xc0,
...this.slipEncodeEscChars(data),
0xc0,
];
} }
/** /**
@@ -280,7 +260,7 @@ class Nrf52DfuFlasher {
*/ */
getEraseWaitTime() { getEraseWaitTime() {
// always wait at least 0.5 seconds // always wait at least 0.5 seconds
return Math.max(0.5, ((this.total_size / this.FLASH_PAGE_SIZE) + 1) * this.FLASH_PAGE_ERASE_TIME); return Math.max(0.5, (this.total_size / this.FLASH_PAGE_SIZE + 1) * this.FLASH_PAGE_ERASE_TIME);
} }
/** /**
@@ -306,8 +286,7 @@ class Nrf52DfuFlasher {
* @param app_size * @param app_size
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async sendStartDfu(mode, softdevice_size = 0, bootloader_size = 0, app_size = 0){ async sendStartDfu(mode, softdevice_size = 0, bootloader_size = 0, app_size = 0) {
// create frame // create frame
const frame = [ const frame = [
...this.int32ToBytes(this.DFU_START_PACKET), ...this.int32ToBytes(this.DFU_START_PACKET),
@@ -324,7 +303,6 @@ class Nrf52DfuFlasher {
// wait for initial erase // wait for initial erase
await this.sleepMillis(this.getEraseWaitTime() * 1000); await this.sleepMillis(this.getEraseWaitTime() * 1000);
} }
/** /**
@@ -332,8 +310,7 @@ class Nrf52DfuFlasher {
* @param initPacket * @param initPacket
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async sendInitPacket(initPacket){ async sendInitPacket(initPacket) {
// create frame // create frame
const frame = [ const frame = [
...this.int32ToBytes(this.DFU_INIT_PACKET), ...this.int32ToBytes(this.DFU_INIT_PACKET),
@@ -343,7 +320,6 @@ class Nrf52DfuFlasher {
// send hci packet // send hci packet
await this.sendPacket(this.createHciPacketFromFrame(frame)); await this.sendPacket(this.createHciPacketFromFrame(frame));
} }
/** /**
@@ -353,26 +329,26 @@ class Nrf52DfuFlasher {
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async sendFirmware(firmware, progressCallback) { async sendFirmware(firmware, progressCallback) {
const packets = []; const packets = [];
var packetsSent = 0; var packetsSent = 0;
// chunk firmware into separate packets // chunk firmware into separate packets
for(let i = 0; i < firmware.length; i += this.DFU_PACKET_MAX_SIZE){ for (let i = 0; i < firmware.length; i += this.DFU_PACKET_MAX_SIZE) {
packets.push(this.createHciPacketFromFrame([ packets.push(
...this.int32ToBytes(this.DFU_DATA_PACKET), this.createHciPacketFromFrame([
...firmware.slice(i, i + this.DFU_PACKET_MAX_SIZE), ...this.int32ToBytes(this.DFU_DATA_PACKET),
])); ...firmware.slice(i, i + this.DFU_PACKET_MAX_SIZE),
])
);
} }
// send initial progress // send initial progress
if(progressCallback){ if (progressCallback) {
progressCallback(0); progressCallback(0);
} }
// send each packet one after the other // send each packet one after the other
for(var i = 0; i < packets.length; i++){ for (var i = 0; i < packets.length; i++) {
// send packet // send packet
await this.sendPacket(packets[i]); await this.sendPacket(packets[i]);
@@ -381,18 +357,14 @@ class Nrf52DfuFlasher {
// update progress // update progress
packetsSent++; packetsSent++;
if(progressCallback){ if (progressCallback) {
const progress = Math.floor((packetsSent / packets.length) * 100); const progress = Math.floor((packetsSent / packets.length) * 100);
progressCallback(progress); progressCallback(progress);
} }
} }
// finished sending firmware, send DFU Stop Data packet // finished sending firmware, send DFU Stop Data packet
await this.sendPacket(this.createHciPacketFromFrame([ await this.sendPacket(this.createHciPacketFromFrame([...this.int32ToBytes(this.DFU_STOP_DATA_PACKET)]));
...this.int32ToBytes(this.DFU_STOP_DATA_PACKET),
]));
} }
/** /**
@@ -411,9 +383,9 @@ class Nrf52DfuFlasher {
createSlipHeader(seq, dip, rp, pktType, pktLen) { createSlipHeader(seq, dip, rp, pktType, pktLen) {
let ints = [0, 0, 0, 0]; let ints = [0, 0, 0, 0];
ints[0] = seq | (((seq + 1) % 8) << 3) | (dip << 6) | (rp << 7); ints[0] = seq | (((seq + 1) % 8) << 3) | (dip << 6) | (rp << 7);
ints[1] = pktType | ((pktLen & 0x000F) << 4); ints[1] = pktType | ((pktLen & 0x000f) << 4);
ints[2] = (pktLen & 0x0FF0) >> 4; ints[2] = (pktLen & 0x0ff0) >> 4;
ints[3] = (~(ints[0] + ints[1] + ints[2]) + 1) & 0xFF; ints[3] = (~(ints[0] + ints[1] + ints[2]) + 1) & 0xff;
return new Uint8Array(ints); return new Uint8Array(ints);
} }
@@ -422,13 +394,8 @@ class Nrf52DfuFlasher {
* @param num * @param num
* @returns {number[]} * @returns {number[]}
*/ */
int32ToBytes(num){ int32ToBytes(num) {
return [ return [num & 0x000000ff, (num & 0x0000ff00) >> 8, (num & 0x00ff0000) >> 16, (num & 0xff000000) >> 24];
(num & 0x000000ff),
(num & 0x0000ff00) >> 8,
(num & 0x00ff0000) >> 16,
(num & 0xff000000) >> 24,
];
} }
/** /**
@@ -436,11 +403,7 @@ class Nrf52DfuFlasher {
* @param num * @param num
* @returns {number[]} * @returns {number[]}
*/ */
int16ToBytes(num){ int16ToBytes(num) {
return [ return [num & 0x00ff, (num & 0xff00) >> 8];
(num & 0x00FF),
(num & 0xFF00) >> 8,
];
} }
} }

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because one or more lines are too long

View File

File diff suppressed because one or more lines are too long