From 00c63605176b1542596d348a12eb5ef59ea05399 Mon Sep 17 00:00:00 2001 From: AlCalzone Date: Thu, 24 Oct 2024 23:28:26 +0200 Subject: [PATCH] fix: detect bootloader when short chunks are received (#7318) --- packages/serial/src/ZWaveSerialPortBase.ts | 4 +- .../serial/src/parsers/BootloaderParsers.ts | 7 ++- packages/testing/src/MockController.ts | 18 +++++++- .../test/driver/bootloaderDetection.test.ts | 45 +++++++++++++++++++ .../src/lib/test/integrationTestSuite.ts | 6 +++ 5 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 packages/zwave-js/src/lib/test/driver/bootloaderDetection.test.ts diff --git a/packages/serial/src/ZWaveSerialPortBase.ts b/packages/serial/src/ZWaveSerialPortBase.ts index 803b6e4465e9..0f445df97f77 100644 --- a/packages/serial/src/ZWaveSerialPortBase.ts +++ b/packages/serial/src/ZWaveSerialPortBase.ts @@ -158,7 +158,9 @@ export class ZWaveSerialPortBase extends PassThrough { if (this.mode == undefined) { // If we haven't figured out the startup mode yet, // inspect the chunk to see if it contains the bootloader preamble - const str = (data as Buffer).toString("ascii").trim(); + const str = (data as Buffer).toString("ascii") + // like .trim(), but including null bytes + .replaceAll(/^[\s\0]+|[\s\0]+$/g, ""); this.mode = str.startsWith(bootloaderMenuPreamble) ? ZWaveSerialMode.Bootloader : ZWaveSerialMode.SerialAPI; diff --git a/packages/serial/src/parsers/BootloaderParsers.ts b/packages/serial/src/parsers/BootloaderParsers.ts index 18836aa1f0a5..c97d2be2efe2 100644 --- a/packages/serial/src/parsers/BootloaderParsers.ts +++ b/packages/serial/src/parsers/BootloaderParsers.ts @@ -79,8 +79,9 @@ export class BootloaderScreenParser extends Transform { const screen = this.receiveBuffer.slice(0, nulCharIndex).trim(); this.receiveBuffer = this.receiveBuffer.slice(nulCharIndex + 1); - this.logger?.bootloaderScreen(screen); + if (screen === "") continue; + this.logger?.bootloaderScreen(screen); this.push(screen); } @@ -107,7 +108,9 @@ export class BootloaderScreenParser extends Transform { } } -export const bootloaderMenuPreamble = "Gecko Bootloader"; +// Sometimes the first chunk of the bootloader screen is relatively short, +// so we consider the following enough to detect the bootloader menu: +export const bootloaderMenuPreamble = "Gecko Boo"; const preambleRegex = /^Gecko Bootloader v(?\d+\.\d+\.\d+)/; const menuSuffix = "BL >"; const optionsRegex = /^(?\d+)\. (?