import errno import logging import typing from binascii import hexlify, unhexlify from struct import unpack import usb.core as ucore from usb.core import USBError from .blobs import init_hardcoded, init_hardcoded_clean_slate from .util import assert_status supported_devices = [ (0x138a, 0x0090), (0x138a, 0x0097), (0x06cb, 0x009a), ] class CancelledException(Exception): pass class Usb: def __init__(self): self.trace_enabled = False self.dev: typing.Optional[ucore.Device] = None self.cancel = False def open(self, vendor=None, product=None): if vendor is not None and product is not None: dev = ucore.find(idVendor=vendor, idProduct=product) else: def match(d): return (d.idVendor, d.idProduct) in supported_devices dev = ucore.find(custom_match=match) self.open_dev(dev) def open_devpath(self, busnum: int, address: int): def match(d): return d.bus == busnum and d.address == address dev = ucore.find(custom_match=match) self.open_dev(dev) def open_dev(self, dev: ucore.Device): if dev is None: raise Exception('No matching devices found') self.dev = dev self.dev.default_timeout = 15000 def close(self): if self.dev is not None: try: self.dev.reset() self.dev = None except: pass def usb_dev(self): return self.dev def send_init(self): # self.dev.set_configuration() # TODO analyse responses, detect hardware type assert_status(self.cmd(unhexlify('01'))) # RomInfo.get() assert_status(self.cmd(unhexlify('19'))) # 43 -- get partition header(?) (02 -- fwext partition) # c28c745a in response is a FwextBuildtime = 0x5A748CC2 rsp = self.cmd(unhexlify('4302')) # get_fw_info() assert_status(self.cmd(init_hardcoded)) (err, ), rsp = unpack('cmd> %s' % hexlify(out).decode()) self.dev.write(1, out) resp = self.dev.read(129, 100 * 1024) resp = bytes(resp) self.trace('