From cad90ebd2e1a3416069277f1fddc69d2ba18bf0e Mon Sep 17 00:00:00 2001 From: a2nr Date: Tue, 30 Jun 2026 18:14:03 +0700 Subject: [PATCH] fix(frontend): route DATA through sendCommand for readValue() fallback sendCommandWithRetry now delegates to sendCommand() instead of using raw writeValueWithResponse + await ackPromise. This ensures DATA chunks also benefit from the readValue() state poll fallback when Android BLE notify is unreliable after idle. --- frontend/src/lib/services/ble-deployer.ts | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/frontend/src/lib/services/ble-deployer.ts b/frontend/src/lib/services/ble-deployer.ts index 800ffcc..66feb20 100644 --- a/frontend/src/lib/services/ble-deployer.ts +++ b/frontend/src/lib/services/ble-deployer.ts @@ -410,25 +410,17 @@ export class BLEHardwareDeployer { } } - private async sendCommandWithRetry(cmd: number, index: number, data: Uint8Array, chunkCRC: number): Promise { - const payload = new Uint8Array(4 + data.length + 4); - payload[0] = cmd; - payload[1] = index & 0xFF; - payload[2] = (index >> 8) & 0xFF; - payload[3] = data.length; - payload.set(data, 4); - payload.set([ - chunkCRC & 0xFF, (chunkCRC >> 8) & 0xFF, (chunkCRC >> 16) & 0xFF, (chunkCRC >> 24) & 0xFF - ], 4 + data.length); - + private async sendCommandWithRetry(cmd: number, index: number, data: Uint8Array, _chunkCRC: number): Promise { + /* Route through sendCommand() which has readValue() state poll + * fallback for DATA (same as INIT/END). The _chunkCRC is kept + * for API compatibility — sendCommand computes CRC internally. */ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) { try { - const ackPromise = this.waitForAck(index); - await this.flashingChar!.writeValueWithResponse(payload); - await ackPromise; + await this.sendCommand(cmd, index, data); return; } catch (err) { if (attempt === MAX_RETRIES - 1) throw err; + console.log(`[BLE-CMD] DATA idx=${index}: retry ${attempt + 1}/${MAX_RETRIES}`, err); await new Promise(r => setTimeout(r, 500)); } }