Skip to content

Commit bfdeb0d

Browse files
VitroidFPVCopilot
andauthored
Fix: Handle BT-11 BLE boards (#4547)
* Fix: Update characteristic UUID to match * Fix: Update connectionId assignment and optimize handleNotification * Fix: Handle 0xff crc fails * Cleanup: Remove debug logging * Refactor: Enhance error handling in WebBluetooth send method * Fix: Implement handling for BT-11 corruption only * Cleanup: Remove loghead * Nitpick: Update src/js/msp.js Co-authored-by: Copilot <[email protected]> * Nitpick: Update src/js/msp.js Co-authored-by: Copilot <[email protected]> * Refactor: Use specific CRC corruption property * Refactor: Move bluetooth-specific code, separate CRC bypass function * Refactor: Move CRC bypass to WebBluetooth as well * Refactor: Move further remains to WebBluetooth * Refactor: Bring logHead back --------- Co-authored-by: Copilot <[email protected]>
1 parent 5ef9acb commit bfdeb0d

File tree

3 files changed

+61
-14
lines changed

3 files changed

+61
-14
lines changed

src/js/msp.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,14 @@ const MSP = {
263263
this.message_buffer = new ArrayBuffer(this.message_length_expected);
264264
this.message_buffer_uint8_view = new Uint8Array(this.message_buffer);
265265
},
266+
266267
_dispatch_message(expectedChecksum) {
267268
if (this.message_checksum === expectedChecksum) {
268269
// message received, store dataview
269270
this.dataView = new DataView(this.message_buffer, 0, this.message_length_expected);
271+
} else if (serial._webBluetooth.shouldBypassCrc(expectedChecksum)) {
272+
this.dataView = new DataView(this.message_buffer, 0, this.message_length_expected);
273+
this.crcError = false; // Override the CRC error for this specific case
270274
} else {
271275
this.packet_error++;
272276
this.crcError = true;

src/js/protocols/WebBluetooth.js

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class WebBluetooth extends EventTarget {
3535

3636
this.bluetooth = navigator?.bluetooth;
3737

38+
this.bt11_crc_corruption_logged = false;
39+
3840
if (!this.bluetooth) {
3941
console.error(`${this.logHead} Web Bluetooth API not supported`);
4042
return;
@@ -88,6 +90,37 @@ class WebBluetooth extends EventTarget {
8890
};
8991
}
9092

93+
isBT11CorruptionPattern(expectedChecksum) {
94+
if (expectedChecksum !== 0xff || this.message_checksum === 0xff) {
95+
return false;
96+
}
97+
98+
if (!this.connected) {
99+
return false;
100+
}
101+
102+
const deviceDescription = this.deviceDescription;
103+
if (!deviceDescription) {
104+
return false;
105+
}
106+
107+
return deviceDescription?.susceptibleToCrcCorruption ?? false;
108+
}
109+
110+
shouldBypassCrc(expectedChecksum) {
111+
// Special handling for specific BT-11/CC2541 checksum corruption
112+
// Only apply workaround for known problematic devices
113+
const isBT11Device = this.isBT11CorruptionPattern(expectedChecksum);
114+
if (isBT11Device) {
115+
if (!this.bt11_crc_corruption_logged) {
116+
console.log(`${this.logHead} Detected BT-11/CC2541 CRC corruption (0xff), skipping CRC check`);
117+
this.bt11_crc_corruption_logged = true;
118+
}
119+
return true;
120+
}
121+
return false;
122+
}
123+
91124
async loadDevices() {
92125
try {
93126
const devices = await this.getDevices();
@@ -163,7 +196,7 @@ class WebBluetooth extends EventTarget {
163196

164197
if (connectionInfo && !this.openCanceled) {
165198
this.connected = true;
166-
this.connectionId = this.device.port;
199+
this.connectionId = path;
167200
this.bitrate = options.baudRate;
168201
this.bytesReceived = 0;
169202
this.bytesSent = 0;
@@ -177,11 +210,9 @@ class WebBluetooth extends EventTarget {
177210

178211
this.dispatchEvent(new CustomEvent("connect", { detail: connectionInfo }));
179212
} else if (connectionInfo && this.openCanceled) {
180-
this.connectionId = this.device.port;
213+
this.connectionId = path;
181214

182-
console.log(
183-
`${this.logHead} Connection opened with ID: ${connectionInfo.connectionId}, but request was canceled, disconnecting`,
184-
);
215+
console.log(`${this.logHead} Connection opened with ID: ${path}, but request was canceled, disconnecting`);
185216
// some bluetooth dongles/dongle drivers really doesn't like to be closed instantly, adding a small delay
186217
setTimeout(() => {
187218
this.openRequested = false;
@@ -260,11 +291,11 @@ class WebBluetooth extends EventTarget {
260291
}
261292

262293
handleNotification(event) {
263-
const buffer = new Uint8Array(event.target.value.byteLength);
264-
265-
for (let i = 0; i < event.target.value.byteLength; i++) {
266-
buffer[i] = event.target.value.getUint8(i);
267-
}
294+
// Create a proper Uint8Array directly from the DataView buffer
295+
const dataView = event.target.value;
296+
const buffer = new Uint8Array(
297+
dataView.buffer.slice(dataView.byteOffset, dataView.byteOffset + dataView.byteLength),
298+
);
268299

269300
// Dispatch immediately instead of using setTimeout to avoid race conditions
270301
this.dispatchEvent(new CustomEvent("receive", { detail: buffer }));
@@ -312,6 +343,7 @@ class WebBluetooth extends EventTarget {
312343
this.readCharacteristic = false;
313344
this.deviceDescription = false;
314345
this.device = null;
346+
this.bt11_crc_corruption_logged = false;
315347
}
316348
};
317349

@@ -339,14 +371,24 @@ class WebBluetooth extends EventTarget {
339371
}
340372

341373
async send(data, cb) {
342-
if (!this.writeCharacteristic) {
374+
if (!this.writeCharacteristic || typeof this.writeCharacteristic.writeValue !== "function") {
375+
if (cb) {
376+
cb({
377+
error: "No write characteristic available or characteristic is invalid",
378+
bytesSent: 0,
379+
});
380+
}
381+
console.error(`${this.logHead} No write characteristic available or characteristic is invalid`);
382+
return;
383+
}
384+
if (!this.device?.gatt?.connected) {
343385
if (cb) {
344386
cb({
345-
error: "No write characteristic available",
387+
error: "GATT Server is disconnected. Cannot perform GATT operations.",
346388
bytesSent: 0,
347389
});
348390
}
349-
console.error(`${this.logHead} No write characteristic available`);
391+
console.error(`${this.logHead} GATT Server is disconnected. Cannot perform GATT operations.`);
350392
return;
351393
}
352394

src/js/protocols/devices.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ export const bluetoothDevices = [
33
name: "CC2541",
44
serviceUuid: "0000ffe0-0000-1000-8000-00805f9b34fb",
55
writeCharacteristic: "0000ffe1-0000-1000-8000-00805f9b34fb",
6-
readCharacteristic: "0000ffe1-0000-1000-8000-00805f9b34fb",
6+
readCharacteristic: "0000ffe2-0000-1000-8000-00805f9b34fb",
7+
susceptibleToCrcCorruption: true,
78
},
89
{
910
name: "HC-05",

0 commit comments

Comments
 (0)