Skip to content

Commit

Permalink
Merge pull request Nitrokey#180 from Nitrokey/spsdk-1.6
Browse files Browse the repository at this point in the history
Update spsdk to 1.6.0
  • Loading branch information
robin-nitrokey committed Feb 7, 2022
2 parents e3c3834 + 2b426c4 commit 0710d71
Show file tree
Hide file tree
Showing 17 changed files with 51 additions and 202 deletions.
2 changes: 1 addition & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ disallow_untyped_defs = True
ignore_errors = True

# libraries without annotations
[mypy-cbor.*,cffi.*,click.*,cryptography.*,ecdsa.*,intelhex.*,nacl.*,nkdfu.*,serial.*,urllib3.*,usb.*,usb1.*]
[mypy-cbor.*,cffi.*,click.*,ecdsa.*,intelhex.*,nacl.*,nkdfu.*,ruamel.*,serial.*,urllib3.*,usb.*,usb1.*]
ignore_missing_imports = True
36 changes: 15 additions & 21 deletions pynitrokey/cli/nk3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
# http://opensource.org/licenses/MIT>, at your option. This file may not be
# copied, modified, or distributed except according to those terms.

import itertools
import logging
import os.path
import platform
import time
from concurrent.futures import ThreadPoolExecutor
from typing import List, Optional, TypeVar

import click
Expand Down Expand Up @@ -512,25 +510,21 @@ def _print_update_warning() -> None:

def _perform_update(device: Nitrokey3Bootloader, image: bytes) -> None:
logger.debug("Starting firmware update")

with ThreadPoolExecutor() as executor:
indicators = itertools.cycle(["/", "-", "\\", "|"])
future = executor.submit(device.update, image)
while not future.done():
print(
f"\r[{next(indicators)}] Performing firmware update "
"(may take several minutes) ... ",
end="",
)
time.sleep(0.1)
print("done")

if future.result():
logger.debug("Firmware update finished successfully")
device.reboot()
else:
(code, message) = device.status
local_critical(f"Firmware update failed with status code {code}: {message}")
with ProgressBar(
desc="Performing firmware update", unit="B", unit_scale=True
) as bar:
result = device.update(image, callback=bar.update_sum)
logger.debug(f"Firmware update finished with status {device.status}")

# TODO: consider repeating firmware update for better diagnostics on failure, see:
# https://github.com/NXPmicro/spsdk/issues/29#issuecomment-1030130023

if result:
logger.debug("Firmware update finished successfully")
device.reboot()
else:
(code, message) = device.status
local_critical(f"Firmware update failed with status code {code}: {message}")


@nk3.command()
Expand Down
15 changes: 15 additions & 0 deletions pynitrokey/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,26 @@ class ProgressBar:
def __init__(self, **kwargs) -> None:
self.bar: Optional[tqdm] = None
self.kwargs = kwargs
self.sum = 0

def __enter__(self) -> "ProgressBar":
return self

def __exit__(self, exc_type, exc_val, exc_tb) -> None:
self.close()

def update(self, n: int, total: int) -> None:
if not self.bar:
self.bar = tqdm(total=total, **self.kwargs)
self.bar.update(n)
self.sum += n

def update_sum(self, n: int, total: int) -> None:
if not self.bar:
self.bar = tqdm(total=total, **self.kwargs)
if n > self.sum:
self.bar.update(n - self.sum)
self.sum = n

def close(self) -> None:
if self.bar:
Expand Down
23 changes: 18 additions & 5 deletions pynitrokey/nk3/bootloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
import logging
import platform
import sys
from typing import List, Optional, Tuple
from typing import Callable, List, Optional, Tuple

from spsdk.mboot import McuBoot, StatusCode
from spsdk.mboot.interfaces import RawHid
from spsdk.mboot.properties import PropertyTag
from spsdk.sbfile.images import BootImageV21
from spsdk.sbfile.sb2.images import BootImageV21
from spsdk.utils.usbfilter import USBDeviceFilter

from .base import Nitrokey3Base
Expand Down Expand Up @@ -75,7 +75,7 @@ def reboot(self) -> None:
raise Exception("Failed to reboot Nitrokey 3 bootloader")

def uuid(self) -> Optional[int]:
uuid = self.device.get_property(PropertyTag.UNIQUE_DEVICE_IDENT)
uuid = self.device.get_property(PropertyTag.UNIQUE_DEVICE_IDENT) # type: ignore[arg-type]
if not uuid:
raise ValueError("Missing response for UUID property query")
if len(uuid) != UUID_LEN:
Expand All @@ -87,8 +87,17 @@ def uuid(self) -> Optional[int]:
right_endian = wrong_endian.to_bytes(16, byteorder="little")
return int.from_bytes(right_endian, byteorder="big")

def update(self, image: bytes) -> bool:
return self.device.receive_sb_file(image)
def update(
self,
image: bytes,
callback: Optional[Callable[[int, int], None]] = None,
check_errors: bool = False,
) -> bool:
return self.device.receive_sb_file(
image,
progress_callback=callback,
check_errors=check_errors,
)

@staticmethod
def list() -> List["Nitrokey3Bootloader"]:
Expand All @@ -99,6 +108,8 @@ def list() -> List["Nitrokey3Bootloader"]:
)
devices = []
for device in RawHid.enumerate(device_filter):
# TODO: remove assert if https://github.com/NXPmicro/spsdk/issues/32 is fixed
assert isinstance(device, RawHid)
try:
devices.append(Nitrokey3Bootloader(device))
except ValueError:
Expand All @@ -119,6 +130,8 @@ def open(path: str) -> Optional["Nitrokey3Bootloader"]:
return None

try:
# TODO: remove assert if https://github.com/NXPmicro/spsdk/issues/32 is fixed
assert isinstance(devices[0], RawHid)
return Nitrokey3Bootloader(devices[0])
except ValueError:
logger.warn(
Expand Down
12 changes: 0 additions & 12 deletions pynitrokey/stubs/spsdk/__init__.py

This file was deleted.

28 changes: 0 additions & 28 deletions pynitrokey/stubs/spsdk/mboot/__init__.pyi

This file was deleted.

13 changes: 0 additions & 13 deletions pynitrokey/stubs/spsdk/mboot/exceptions.pyi

This file was deleted.

21 changes: 0 additions & 21 deletions pynitrokey/stubs/spsdk/mboot/interfaces.pyi

This file was deleted.

14 changes: 0 additions & 14 deletions pynitrokey/stubs/spsdk/mboot/properties.pyi

This file was deleted.

8 changes: 0 additions & 8 deletions pynitrokey/stubs/spsdk/sbfile/__init__.pyi

This file was deleted.

13 changes: 0 additions & 13 deletions pynitrokey/stubs/spsdk/sbfile/headers.pyi

This file was deleted.

20 changes: 0 additions & 20 deletions pynitrokey/stubs/spsdk/sbfile/images.pyi

This file was deleted.

13 changes: 0 additions & 13 deletions pynitrokey/stubs/spsdk/sbfile/misc.pyi

This file was deleted.

8 changes: 0 additions & 8 deletions pynitrokey/stubs/spsdk/utils/__init__.pyi

This file was deleted.

12 changes: 0 additions & 12 deletions pynitrokey/stubs/spsdk/utils/crypto.pyi

This file was deleted.

11 changes: 0 additions & 11 deletions pynitrokey/stubs/spsdk/utils/usbfilter.pyi

This file was deleted.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ dependencies = [
"cbor",
"cffi",
"click >=7.0",
"cryptography >=3.4",
"cryptography >=3.4.4",
"ecdsa",
"fido2 >=0.9.3",
"intelhex",
"nkdfu",
"python-dateutil",
"pyusb",
"requests",
"spsdk >=1.5.0",
"spsdk >=1.6.0",
"tqdm",
"urllib3",
]
Expand Down

0 comments on commit 0710d71

Please sign in to comment.