Beispiel #1
0
def cmd_flash(device, firmware, enable_insecure, log_cb, progress_cb, complete_cb, error_cb):
    if firmware[0:8] not in [b"VIALFW00", b"VIALFW01"]:
        return error_cb("Error: Invalid signature")

    fw_uid = firmware[8:16]
    fw_ts = struct.unpack("<Q", firmware[16:24])[0]
    log_cb("* Firmware build date: {} (UTC)".format(datetime.datetime.utcfromtimestamp(fw_ts)))

    fw_hash = firmware[32:64]
    fw_payload = firmware[64:]

    if hashlib.sha256(fw_payload).digest() != fw_hash:
        return error_cb("Error: Firmware failed integrity check\n\texpected={}\n\tgot={}".format(
            fw_hash.hex(),
            hashlib.sha256(fw_payload).hexdigest()
        ))

    # Check bootloader is correct version
    send_retries(device, pad_for_vibl(b"VC\x00"))
    ver = device.recv(8)[0]
    log_cb("* Bootloader version: {}".format(ver))
    if ver not in [0, 1]:
        return error_cb("Error: Unsupported bootloader version")

    send_retries(device, pad_for_vibl(b"VC\x01"))
    uid = device.recv(8)
    log_cb("* Vial ID: {}".format(uid.hex()))

    if uid == b"\xFF" * 8:
        log_cb("\n\n\n!!! WARNING !!!\nBootloader UID is not set, make sure to configure it"
               " before releasing production firmware\n!!! WARNING !!!\n\n")

    if uid != fw_uid:
        return error_cb("Error: Firmware package was built for different device\n\texpected={}\n\tgot={}".format(
            fw_uid.hex(),
            uid.hex()
        ))

    # OK all checks complete, we can flash now
    while len(fw_payload) % CHUNK != 0:
        fw_payload += b"\x00"

    # Flash
    log_cb("Flashing...")
    send_retries(device, pad_for_vibl(b"VC\x02" + struct.pack("<H", len(fw_payload) // CHUNK)))
    total = 0
    for part in chunks(fw_payload, CHUNK):
        if not send_retries(device, part):
            return error_cb("Error while sending data, firmware is corrupted")
        total += len(part)
        progress_cb(total / len(fw_payload))

    # Reboot
    log_cb("Rebooting...")
    # enable insecure mode on first boot in order to restore keymap/macros
    if enable_insecure:
        send_retries(device, pad_for_vibl(b"VC\x04"))
    send_retries(device, pad_for_vibl(b"VC\x03"))

    complete_cb("Done!")
Beispiel #2
0
 def get_uid(self):
     try:
         super().open()
     except OSError:
         return b""
     self.send(pad_for_vibl(b"VC\x01"))
     data = self.recv(8, timeout_ms=500)
     super().close()
     return data