|
1 | 1 | // SPDX-License-Identifier: MIT |
2 | | -// Copyright (c) 2020-2025 The Pybricks Authors |
| 2 | +// Copyright (c) 2020-2026 The Pybricks Authors |
3 | 3 | // |
4 | 4 | // Manages connection to a Bluetooth Low Energy device running Pybricks firmware. |
5 | 5 |
|
@@ -400,59 +400,65 @@ function* handleBleConnectPybricks(): Generator { |
400 | 400 | ); |
401 | 401 | } |
402 | 402 |
|
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 | + } |
412 | 410 |
|
413 | | - if (!uartService) { |
414 | | - yield* put( |
415 | | - alertsShowAlert('ble', 'missingService', { |
416 | | - serviceName: 'Nordic UART', |
417 | | - hubName: device.name || 'Pybricks Hub', |
| 411 | + throw err; |
418 | 412 | }), |
419 | 413 | ); |
420 | | - yield* put(bleDidFailToConnectPybricks()); |
421 | | - return; |
422 | | - } |
423 | | - |
424 | | - const uartRxChar = yield* call(() => |
425 | | - uartService.getCharacteristic(nordicUartRxCharUUID), |
426 | | - ); |
427 | 414 |
|
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 | + } |
443 | 425 |
|
444 | | - defer.push(() => uartTxChannel.close()); |
445 | | - tasks.push(yield* takeEvery(uartTxChannel, handleUartValueChanged)); |
| 426 | + const uartRxChar = yield* call(() => |
| 427 | + uartService.getCharacteristic(nordicUartRxCharUUID), |
| 428 | + ); |
446 | 429 |
|
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 | + ); |
454 | 433 |
|
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 | + } |
456 | 462 |
|
457 | 463 | yield* put(bleDidConnectPybricks(device.id, device.name || '')); |
458 | 464 |
|
|
0 commit comments