Skip to content

Commit f85c66c

Browse files
committed
Fixed Raw Uploads and Downloads
1 parent c4fd3f3 commit f85c66c

File tree

3 files changed

+61
-41
lines changed

3 files changed

+61
-41
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# BLE File Transfer JS
2+
3+
JavaScript library for transferring files with Web Bluetooth.

adafruit-ble-file-transfer.js

Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const FLAG_DIRECTORY = 0x01;
2929
const BYTES_PER_WRITE = 20;
3030

3131
class FileTransferClient {
32-
constructor(bleDevice, bufferSize=4096) {
32+
constructor(bleDevice, bufferSize = 4096) {
3333
this._resolve = null;
3434
this._reject = null;
3535
this._command = ANY_COMMAND;
@@ -38,6 +38,7 @@ class FileTransferClient {
3838
this._buffer = new Uint8Array(bufferSize);
3939
this._transfer = null;
4040
this._device = bleDevice;
41+
this._raw = false;
4142
bleDevice.addEventListener("gattserverdisconnected", this.onDisconnected.bind(this));
4243
this._onTransferNotifty = this.onTransferNotifty.bind(this);
4344
}
@@ -75,7 +76,7 @@ class FileTransferClient {
7576
this._transfer.removeEventListener('characteristicvaluechanged', this._onTransferNotifty);
7677
this._transfer.addEventListener('characteristicvaluechanged', this._onTransferNotifty);
7778
await this._transfer.startNotifications();
78-
} catch(e) {
79+
} catch (e) {
7980
console.log("caught connection error", e, e.stack);
8081
this.onDisconnected();
8182
}
@@ -108,34 +109,35 @@ class FileTransferClient {
108109
}
109110

110111
async onTransferNotifty(event) {
111-
this._buffer.set(new Uint8Array(event.target.value.buffer), this._offset);
112-
this._command = this._buffer[0];
113-
this._offset += event.target.value.byteLength;
114-
if (this._command == READ_DATA) {
115-
this._command = await this.processReadData(new DataView(this._buffer.buffer, 0, this._offset));
116-
} else if (this._command == WRITE_PACING) {
117-
this._command = await this.processWritePacing(new DataView(this._buffer.buffer, 0, this._offset));
118-
} else if (this._command == LISTDIR_ENTRY) {
119-
this._command = await this.processListDirEntry(new DataView(this._buffer.buffer, 0, this._offset));
120-
} else if (this._command == MKDIR_STATUS) {
121-
this._command = await this.processMkDirStatus(new DataView(this._buffer.buffer, 0, this._offset));
122-
} else if (this._command == DELETE_STATUS) {
123-
this._command = await this.processDeleteStatus(new DataView(this._buffer.buffer, 0, this._offset));
124-
} else if (this._command == MOVE_STATUS) {
125-
this._command = await this.processMoveStatus(new DataView(this._buffer.buffer, 0, this._offset));
126-
} else {
127-
console.log("Unknown Command: " + this._command);
128-
}
129-
if (this._command != THIS_COMMAND) {
130-
//reset buffer
131-
this._offset = 0;
132-
}
112+
this._buffer.set(new Uint8Array(event.target.value.buffer), this._offset);
113+
this._command = this._buffer[0];
114+
this._offset += event.target.value.byteLength;
115+
if (this._command == READ_DATA) {
116+
this._command = await this.processReadData(new DataView(this._buffer.buffer, 0, this._offset));
117+
} else if (this._command == WRITE_PACING) {
118+
this._command = await this.processWritePacing(new DataView(this._buffer.buffer, 0, this._offset));
119+
} else if (this._command == LISTDIR_ENTRY) {
120+
this._command = await this.processListDirEntry(new DataView(this._buffer.buffer, 0, this._offset));
121+
} else if (this._command == MKDIR_STATUS) {
122+
this._command = await this.processMkDirStatus(new DataView(this._buffer.buffer, 0, this._offset));
123+
} else if (this._command == DELETE_STATUS) {
124+
this._command = await this.processDeleteStatus(new DataView(this._buffer.buffer, 0, this._offset));
125+
} else if (this._command == MOVE_STATUS) {
126+
this._command = await this.processMoveStatus(new DataView(this._buffer.buffer, 0, this._offset));
127+
} else {
128+
console.log("Unknown Command: " + this._command);
129+
}
130+
if (this._command != THIS_COMMAND) {
131+
//reset buffer
132+
this._offset = 0;
133+
}
133134
}
134135

135-
async readFile(filename) {
136+
async readFile(filename, raw = false) {
136137
await this.checkConnection();
137138
this._incomingFile = null;
138139
this._incomingOffset = 0;
140+
this._raw = raw;
139141

140142
var header = new ArrayBuffer(12);
141143
var view = new DataView(header);
@@ -157,7 +159,18 @@ class FileTransferClient {
157159
return p;
158160
}
159161

160-
async writeFile(path, offset, contents, modificationTime) {
162+
async writeFile(path, offset, contents, modificationTime, raw = false) {
163+
let encoder = new TextEncoder();
164+
165+
if (!raw) {
166+
let same = contents.slice(0, offset);
167+
let different = contents.slice(offset);
168+
offset = encoder.encode(same).byteLength;
169+
contents = encoder.encode(different);
170+
} else if (!(contents instanceof Uint8Array)) {
171+
contents = new Uint8Array(contents);
172+
}
173+
161174
await this.checkConnection();
162175
if (modificationTime === undefined) {
163176
modificationTime = Date.now();
@@ -186,7 +199,7 @@ class FileTransferClient {
186199
}
187200

188201
sleep(ms) {
189-
return new Promise(resolve => setTimeout(resolve, ms))
202+
return new Promise(resolve => setTimeout(resolve, ms));
190203
}
191204

192205
async processWritePacing(payload) {
@@ -207,10 +220,10 @@ class FileTransferClient {
207220
return ANY_COMMAND;
208221
}
209222
if (freeSpace == 0) {
210-
this._resolve();
211-
this._reject = null;
212-
this._resolve = null;
213-
return ANY_COMMAND;
223+
this._resolve();
224+
this._reject = null;
225+
this._resolve = null;
226+
return ANY_COMMAND;
214227
}
215228
var header = new ArrayBuffer(12);
216229
var view = new DataView(header);
@@ -247,19 +260,23 @@ class FileTransferClient {
247260
return ANY_COMMAND;
248261
}
249262
if (payload.byteLength < headerSize + chunkLength) {
250-
// need more
251-
return THIS_COMMAND;
263+
// need more
264+
return THIS_COMMAND;
252265
}
253266
// full payload
254267
if (this._incomingFile == null) {
255-
this._incomingFile = new Uint8Array(totalLength);
268+
this._incomingFile = new Uint8Array(totalLength);
256269
}
257270
this._incomingFile.set(new Uint8Array(payload.buffer.slice(headerSize, payload.byteLength)), chunkOffset);
258271
this._incomingOffset += chunkLength;
259272

260273
let remaining = this._incomingFile.byteLength - this._incomingOffset;
261274
if (remaining == 0) {
262-
this._resolve(new TextDecoder().decode(this._incomingFile));
275+
if (this._raw) {
276+
this._resolve(new Blob([this._incomingFile]));
277+
} else {
278+
this._resolve(new TextDecoder().decode(this._incomingFile));
279+
}
263280
this._resolve = null;
264281
this._reject = null;
265282
this._incomingFile = null;
@@ -277,7 +294,7 @@ class FileTransferClient {
277294
return READ_DATA;
278295
}
279296

280-
async processListDirEntry(payload, offset=0) {
297+
async processListDirEntry(payload, offset = 0) {
281298
let paths = [];
282299
let b = this._buffer.buffer;
283300
const headerSize = 28;
@@ -406,14 +423,14 @@ class FileTransferClient {
406423
this._reject = null;
407424
return ANY_COMMAND;
408425
}
409-
426+
410427
async processMoveStatus(payload) {
411428
const headerSize = 2;
412429

413430
if (payload.byteLength < headerSize) {
414431
return THIS_COMMAND;
415432
}
416-
433+
417434
let status = payload.getUint8(1);
418435
if (status != STATUS_OK) {
419436
if (status == STATUS_ERROR_USB_MOUNTED) {
@@ -499,7 +516,7 @@ class FileTransferClient {
499516

500517
let encodedOldPath = new TextEncoder().encode(oldPath);
501518
let encodedNewPath = new TextEncoder().encode(newPath);
502-
519+
503520
var header = new ArrayBuffer(6);
504521
var view = new DataView(header);
505522
view.setUint8(0, MOVE_COMMAND);
@@ -532,4 +549,4 @@ class ValueError extends Error {
532549
}
533550
}
534551

535-
export { FileTransferClient, ProtocolError, ValueError };
552+
export {FileTransferClient, ProtocolError, ValueError};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"publishConfig": {
44
"registry": "https://npm.pkg.github.com"
55
},
6-
"version": "1.0.1",
6+
"version": "1.0.2",
77
"description": "WebBluetooth library for transferring files over BLE",
88
"main": "adafruit-ble-file-transfer.js",
99
"dependencies": {

0 commit comments

Comments
 (0)