def change_homescreen(): filename = getOpenFileName( parent=self, title=_("Choose Homescreen"), config=config, ) if not filename: return # user cancelled if filename.endswith('.toif'): img = open(filename, 'rb').read() if img[:8] != b'TOIf\x90\x00\x90\x00': handler.show_error( 'File is not a TOIF file with size of 144x144') return else: from PIL import Image # FIXME im = Image.open(filename) if im.size != (128, 64): handler.show_error('Image must be 128 x 64 pixels') return im = im.convert('1') pix = im.load() img = bytearray(1024) for j in range(64): for i in range(128): if pix[i, j]: o = (i + j * 128) img[o // 8] |= (1 << (7 - o % 8)) img = bytes(img) invoke_client('change_homescreen', img)
def start_upgrade(self, client): # ask for a filename (must have already downloaded it) dev = client.dev fileName = getOpenFileName( parent=self, title="Select upgraded firmware file", filter="*.dfu", config=self.window.config, ) if not fileName: return from ckcc.utils import dfu_parse from ckcc.sigheader import FW_HEADER_SIZE, FW_HEADER_OFFSET, FW_HEADER_MAGIC from ckcc.protocol import CCProtocolPacker from hashlib import sha256 import struct try: with open(fileName, 'rb') as fd: # unwrap firmware from the DFU offset, size, *ignored = dfu_parse(fd) fd.seek(offset) firmware = fd.read(size) hpos = FW_HEADER_OFFSET hdr = bytes(firmware[hpos:hpos + FW_HEADER_SIZE]) # needed later too magic = struct.unpack_from("<I", hdr)[0] if magic != FW_HEADER_MAGIC: raise ValueError("Bad magic") except Exception as exc: mw.show_error( "Does not appear to be a Coldcard firmware file.\n\n%s" % exc) return # TODO: # - detect if they are trying to downgrade; aint gonna work # - warn them about the reboot? # - length checks # - add progress local bar mw.show_message( "Ready to Upgrade.\n\nBe patient. Unit will reboot itself when complete." ) def doit(): dlen, _ = dev.upload_file(firmware, verify=True) assert dlen == len(firmware) # append the firmware header a second time result = dev.send_recv( CCProtocolPacker.upload(size, size + FW_HEADER_SIZE, hdr)) # make it reboot into bootlaoder which might install it dev.send_recv(CCProtocolPacker.reboot()) self.thread.add(doit) self.close()