Skip to content

Commit

Permalink
firmware/sagas: reduce BLE firmware burst size
Browse files Browse the repository at this point in the history
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: pybricks/support#1787
  • Loading branch information
dlech committed Sep 8, 2024
1 parent 6605c72 commit 236ad56
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 15 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 11 additions & 11 deletions src/firmware/sagas.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021-2022 The Pybricks Authors
// Copyright (c) 2021-2024 The Pybricks Authors

import {
FirmwareMetadata,
Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -366,7 +366,7 @@ describe('flashFirmware', () => {
break;
}

if (count % 10 === 0) {
if (count % 8 === 0) {
action = await saga.take();
expect(action).toEqual(checksumRequest(++id));

Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -1689,7 +1689,7 @@ describe('flashFirmware', () => {
break;
}

if (count % 10 === 0) {
if (count % 8 === 0) {
action = await saga.take();
expect(action).toEqual(checksumRequest(++id));

Expand Down Expand Up @@ -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));
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/firmware/sagas.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020-2022 The Pybricks Authors
// Copyright (c) 2020-2024 The Pybricks Authors

import {
FirmwareReader,
Expand Down Expand Up @@ -529,11 +529,11 @@ function* handleFlashFirmware(action: ReturnType<typeof flashFirmware>): 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({
Expand All @@ -543,7 +543,7 @@ function* handleFlashFirmware(action: ReturnType<typeof flashFirmware>): 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,
Expand Down

0 comments on commit 236ad56

Please sign in to comment.