|
5 | 5 | import hashlib |
6 | 6 | import json |
7 | 7 | import logging |
| 8 | +import struct |
8 | 9 | import sys |
9 | 10 | import zipfile |
10 | 11 | from tempfile import NamedTemporaryFile |
|
34 | 35 | from ..ble.pybricks import ( |
35 | 36 | FW_REV_UUID, |
36 | 37 | PNP_ID_UUID, |
| 38 | + PYBRICKS_COMMAND_EVENT_UUID, |
37 | 39 | PYBRICKS_SERVICE_UUID, |
| 40 | + SW_REV_UUID, |
| 41 | + Command, |
38 | 42 | unpack_pnp_id, |
39 | 43 | ) |
40 | 44 | from ..compile import compile_file |
@@ -66,7 +70,7 @@ def match_hub(hub_kind: HubKind, adv: AdvertisementData) -> bool: |
66 | 70 |
|
67 | 71 | Args: |
68 | 72 | hub_kind: The hub type ID to match. |
69 | | - adv: The advertisemet data to check. |
| 73 | + adv: The advertisement data to check. |
70 | 74 |
|
71 | 75 | Returns: |
72 | 76 | ``True`` if *adv* matches the criteria, otherwise ``False``. |
@@ -217,11 +221,36 @@ async def reboot_pybricks_to_bootloader(hub_kind: HubKind, device: BLEDevice) -> |
217 | 221 |
|
218 | 222 | print("Rebooting in update mode...") |
219 | 223 |
|
220 | | - # HACK: there isn't a proper way to get the MPY ABI version from hub |
221 | | - # so we use heuristics on the firmware version |
222 | | - abi = 6 if Version(fw_ver) >= Version("3.2.0b2") else 5 |
223 | | - |
224 | | - await download_and_run(client, REBOOT_SCRIPT, abi) |
| 224 | + profile_ver = await client.read_gatt_char(SW_REV_UUID) |
| 225 | + |
| 226 | + if Version(profile_ver.decode()) >= Version("1.2.0"): |
| 227 | + try: |
| 228 | + await client.write_gatt_char( |
| 229 | + PYBRICKS_COMMAND_EVENT_UUID, |
| 230 | + struct.pack( |
| 231 | + "<B", Command.PBIO_PYBRICKS_COMMAND_REBOOT_TO_UPDATE_MODE |
| 232 | + ), |
| 233 | + response=True, |
| 234 | + ) |
| 235 | + # This causes the hub to become disconnected before completing |
| 236 | + # the write request, so we expect an exception here. |
| 237 | + except Exception: |
| 238 | + # REVISIT: Should probably check for more specific exception. |
| 239 | + # However, OK for now since code will just timeout later while |
| 240 | + # scanning for bootloader. |
| 241 | + pass |
| 242 | + else: |
| 243 | + raise RuntimeError("hub did not reset") |
| 244 | + |
| 245 | + else: |
| 246 | + # older protocol doesn't support this command, so we have to |
| 247 | + # download and run a program |
| 248 | + |
| 249 | + # HACK: there isn't a proper way to get the MPY ABI version from hub |
| 250 | + # so we use heuristics on the firmware version |
| 251 | + abi = 6 if Version(fw_ver) >= Version("3.2.0b2") else 5 |
| 252 | + |
| 253 | + await download_and_run(client, REBOOT_SCRIPT, abi) |
225 | 254 |
|
226 | 255 |
|
227 | 256 | async def flash_ble(hub_kind: HubKind, firmware: bytes, metadata: dict): |
|
0 commit comments