Skip to content

Commit 044efb6

Browse files
committed
ble/sagas: Don't read NUS for new firmware.
This hasn't been used for a long time in Pybricks Code. We're only keeping it in the firmware because Pybricks Code raises an error otherwise. Disabling it saves about +400 bytes on Move Hub and Technic Hub and helps simplify the firmware. By removing it we don't run untested code if someone connects to the advertised NUS service.
1 parent a4aade5 commit 044efb6

File tree

1 file changed

+53
-47
lines changed

1 file changed

+53
-47
lines changed

src/ble/sagas.ts

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
// Copyright (c) 2020-2025 The Pybricks Authors
2+
// Copyright (c) 2020-2026 The Pybricks Authors
33
//
44
// Manages connection to a Bluetooth Low Energy device running Pybricks firmware.
55

@@ -400,59 +400,65 @@ function* handleBleConnectPybricks(): Generator {
400400
);
401401
}
402402

403-
const uartService = yield* call(() =>
404-
server.getPrimaryService(nordicUartServiceUUID).catch((err) => {
405-
if (err instanceof DOMException && err.name === 'NotFoundError') {
406-
return undefined;
407-
}
408-
409-
throw err;
410-
}),
411-
);
403+
// Nordic UART service is removed starting with Pybricks Profile v1.5.0
404+
if (!semver.satisfies(softwareRevision, '^1.5.0')) {
405+
const uartService = yield* call(() =>
406+
server.getPrimaryService(nordicUartServiceUUID).catch((err) => {
407+
if (err instanceof DOMException && err.name === 'NotFoundError') {
408+
return undefined;
409+
}
412410

413-
if (!uartService) {
414-
yield* put(
415-
alertsShowAlert('ble', 'missingService', {
416-
serviceName: 'Nordic UART',
417-
hubName: device.name || 'Pybricks Hub',
411+
throw err;
418412
}),
419413
);
420-
yield* put(bleDidFailToConnectPybricks());
421-
return;
422-
}
423-
424-
const uartRxChar = yield* call(() =>
425-
uartService.getCharacteristic(nordicUartRxCharUUID),
426-
);
427414

428-
const uartTxChar = yield* call(() =>
429-
uartService.getCharacteristic(nordicUartTxCharUUID),
430-
);
431-
432-
const uartTxChannel = eventChannel<DataView>((emitter) => {
433-
const listener = (): void => {
434-
if (!uartTxChar.value) {
435-
return;
436-
}
437-
emitter(uartTxChar.value);
438-
};
439-
uartTxChar.addEventListener('characteristicvaluechanged', listener);
440-
return (): void =>
441-
uartTxChar.removeEventListener('characteristicvaluechanged', listener);
442-
});
415+
if (!uartService) {
416+
yield* put(
417+
alertsShowAlert('ble', 'missingService', {
418+
serviceName: 'Nordic UART',
419+
hubName: device.name || 'Pybricks Hub',
420+
}),
421+
);
422+
yield* put(bleDidFailToConnectPybricks());
423+
return;
424+
}
443425

444-
defer.push(() => uartTxChannel.close());
445-
tasks.push(yield* takeEvery(uartTxChannel, handleUartValueChanged));
426+
const uartRxChar = yield* call(() =>
427+
uartService.getCharacteristic(nordicUartRxCharUUID),
428+
);
446429

447-
// REVISIT: possible Pybricks firmware bug (or chromium bug on Linux)
448-
// where 'characteristicvaluechanged' is not called after disconnecting
449-
// and reconnecting unless we stop notifications before we start them
450-
// again. Wireshark shows that no enable notification descriptor write
451-
// is performed but notifications are received.
452-
yield* call(() => uartTxChar.stopNotifications());
453-
yield* call(() => uartTxChar.startNotifications());
430+
const uartTxChar = yield* call(() =>
431+
uartService.getCharacteristic(nordicUartTxCharUUID),
432+
);
454433

455-
tasks.push(yield* takeEvery(writeUart, handleWriteUart, uartRxChar));
434+
const uartTxChannel = eventChannel<DataView>((emitter) => {
435+
const listener = (): void => {
436+
if (!uartTxChar.value) {
437+
return;
438+
}
439+
emitter(uartTxChar.value);
440+
};
441+
uartTxChar.addEventListener('characteristicvaluechanged', listener);
442+
return (): void =>
443+
uartTxChar.removeEventListener(
444+
'characteristicvaluechanged',
445+
listener,
446+
);
447+
});
448+
449+
defer.push(() => uartTxChannel.close());
450+
tasks.push(yield* takeEvery(uartTxChannel, handleUartValueChanged));
451+
452+
// REVISIT: possible Pybricks firmware bug (or chromium bug on Linux)
453+
// where 'characteristicvaluechanged' is not called after disconnecting
454+
// and reconnecting unless we stop notifications before we start them
455+
// again. Wireshark shows that no enable notification descriptor write
456+
// is performed but notifications are received.
457+
yield* call(() => uartTxChar.stopNotifications());
458+
yield* call(() => uartTxChar.startNotifications());
459+
460+
tasks.push(yield* takeEvery(writeUart, handleWriteUart, uartRxChar));
461+
}
456462

457463
yield* put(bleDidConnectPybricks(device.id, device.name || ''));
458464

0 commit comments

Comments
 (0)