From 236ad56148e572170aafd8aae0c2292f140465da Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sun, 8 Sep 2024 21:49:11 +0000 Subject: [PATCH] firmware/sagas: reduce BLE firmware burst size Mac users have recently been reporting failed firmware updates due to the hub disconnecting during the update process. This is likely due to the Mac sending packets faster than the hub can handle. This changes the arbitrary BLE firmware burst size from 10 to 8 to reduce the chance of the hub getting overwhelmed. Fixes: https://github.com/pybricks/support/issues/1787 --- CHANGELOG.md | 5 +++++ src/firmware/sagas.test.ts | 22 +++++++++++----------- src/firmware/sagas.ts | 8 ++++---- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73fb78aa..31cd9593 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ ## [Unreleased] +### Fixed +- Fixed Bluetooth firmware updates sometimes failing on macOS. ([support#1787]) + +[[support#1787]]: https://github.com/pybricks/support/issues/1787 + ## [2.3.0-beta.1] - 2023-11-24 ### Changed diff --git a/src/firmware/sagas.test.ts b/src/firmware/sagas.test.ts index b335a58d..303c61c5 100644 --- a/src/firmware/sagas.test.ts +++ b/src/firmware/sagas.test.ts @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2021-2022 The Pybricks Authors +// Copyright (c) 2021-2024 The Pybricks Authors import { FirmwareMetadata, @@ -200,12 +200,12 @@ describe('flashFirmware', () => { break; } - if (count % 10 === 0) { + if (count % 8 === 0) { action = await saga.take(); expect(action).toEqual(checksumRequest(++id)); saga.put(didRequest(id)); - saga.put(checksumResponse(0)); + saga.put(checksumResponse(0xee)); } } @@ -366,7 +366,7 @@ describe('flashFirmware', () => { break; } - if (count % 10 === 0) { + if (count % 8 === 0) { action = await saga.take(); expect(action).toEqual(checksumRequest(++id)); @@ -1331,12 +1331,12 @@ describe('flashFirmware', () => { break; } - if (count % 10 === 0) { + if (count % 8 === 0) { action = await saga.take(); expect(action).toEqual(checksumRequest(++id)); saga.put(didRequest(id)); - saga.put(checksumResponse(0)); + saga.put(checksumResponse(0xeb)); } } @@ -1507,12 +1507,12 @@ describe('flashFirmware', () => { break; } - if (count % 10 === 0) { + if (count % 8 === 0) { action = await saga.take(); expect(action).toEqual(checksumRequest(++id)); saga.put(didRequest(id)); - saga.put(checksumResponse(0)); + saga.put(checksumResponse(0xeb)); } } @@ -1689,7 +1689,7 @@ describe('flashFirmware', () => { break; } - if (count % 10 === 0) { + if (count % 8 === 0) { action = await saga.take(); expect(action).toEqual(checksumRequest(++id)); @@ -2254,12 +2254,12 @@ describe('flashFirmware', () => { break; } - if (count % 10 === 0) { + if (count % 8 === 0) { action = await saga.take(); expect(action).toEqual(checksumRequest(++id)); saga.put(didRequest(id)); - saga.put(checksumResponse(0)); + saga.put(checksumResponse(0xeb)); } } diff --git a/src/firmware/sagas.ts b/src/firmware/sagas.ts index 539471c8..782976bf 100644 --- a/src/firmware/sagas.ts +++ b/src/firmware/sagas.ts @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2020-2022 The Pybricks Authors +// Copyright (c) 2020-2024 The Pybricks Authors import { FirmwareReader, @@ -529,11 +529,11 @@ function* handleFlashFirmware(action: ReturnType): Generat break; } - // Request checksum every 10 packets to prevent buffer overrun on + // Request checksum every 8 packets to prevent buffer overrun on // the hub because of sending too much data at once. The actual // number of packets that can be queued in the Bluetooth chip on // the hub is not known and could vary by device. - if (count % 10 === 0) { + if (count % 8 === 0) { const checksumAction = yield* put(checksumRequest(nextMessageId())); const { response } = yield* all({ @@ -543,7 +543,7 @@ function* handleFlashFirmware(action: ReturnType): Generat if (response.checksum !== runningChecksum) { // istanbul ignore next - if (process.env.NODE_ENV !== 'test') { + if (process.env.NODE_ENV === 'test') { console.error( `checksum: got ${hex(response.checksum, 2)} expected ${hex( runningChecksum,