1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-25 17:25:16 +03:00

Prevent GATT operation in progress

This commit is contained in:
Mark Haslinghuis 2025-07-12 23:17:09 +02:00
parent 04ea058b30
commit f7e1be866b

View file

@ -40,6 +40,8 @@ class WebBluetooth extends EventTarget {
return; return;
} }
this.writeQueue = Promise.resolve();
this.connect = this.connect.bind(this); this.connect = this.connect.bind(this);
this.bluetooth.addEventListener("connect", (e) => this.handleNewDevice(e.target)); this.bluetooth.addEventListener("connect", (e) => this.handleNewDevice(e.target));
@ -255,12 +257,6 @@ class WebBluetooth extends EventTarget {
} }
this.readCharacteristic.addEventListener("characteristicvaluechanged", this.handleNotification.bind(this)); this.readCharacteristic.addEventListener("characteristicvaluechanged", this.handleNotification.bind(this));
try {
return await this.readCharacteristic.readValue();
} catch (e) {
console.error(`${this.logHead} Failed to read characteristic value:`, e);
}
} }
handleNotification(event) { handleNotification(event) {
@ -270,9 +266,8 @@ class WebBluetooth extends EventTarget {
buffer[i] = event.target.value.getUint8(i); buffer[i] = event.target.value.getUint8(i);
} }
setTimeout(() => { // Dispatch immediately instead of using setTimeout to avoid race conditions
this.dispatchEvent(new CustomEvent("receive", { detail: buffer })); this.dispatchEvent(new CustomEvent("receive", { detail: buffer }));
}, 0);
} }
startNotifications() { startNotifications() {
@ -358,34 +353,35 @@ class WebBluetooth extends EventTarget {
// There is no writable stream in the bluetooth API // There is no writable stream in the bluetooth API
const dataBuffer = new Uint8Array(data); const dataBuffer = new Uint8Array(data);
try { // Serialize writes to prevent concurrent access
if (this.lastWrite) { this.writeQueue = this.writeQueue
await this.lastWrite; .then(async () => {
} try {
this.lastWrite = this.writeCharacteristic.writeValue(dataBuffer); await this.writeCharacteristic.writeValue(dataBuffer);
await this.lastWrite; this.bytesSent += data.byteLength;
this.bytesSent += data.byteLength;
if (cb) { if (cb) {
cb({ cb({
error: null, error: null,
bytesSent: data.byteLength, bytesSent: data.byteLength,
}); });
} }
} catch (e) { } catch (e) {
console.error(`${this.logHead} Failed to send data:`, e); console.error(`${this.logHead} Failed to send data:`, e);
if (cb) { if (cb) {
cb({ cb({
error: e, error: e,
bytesSent: 0, bytesSent: 0,
}); });
} }
} throw e; // re-throw to keep the queue in a rejected state
}
})
.catch(() => {
// swallow here so queue chain continues on next write
});
return { await this.writeQueue;
bytesSent: data.byteLength,
resultCode: 0,
};
} }
} }