def load_firmware(self, firmware_id=None, progress=None, verify=True): if firmware_id == None: fw_info = self.get_firmware_info() fw_file = firmware.get_firmware(fw_info.firmware_id) else: fw_file = firmware.get_firmware(firmware_id) if fw_file is None: raise IOError("Firmware image not found") # read firmware data f = open(fw_file, 'rb') firmware_data = f.read() f.close() # delete old firmware self.delete_file("firmware.bin") filehash = catbus_string_hash(firmware_data) # load firmware image self.put_file("firmware.bin", firmware_data, progress=progress) if verify: self.check_file("firmware.bin", firmware_data) # reboot to loader self.reboot_and_load_fw()
def scan_file_for_kv(self, filename): with open(filename, 'r') as f: data = f.read() hashes = {} # search for prefix index = data.find(KV_PREFIX) while index >= 0: # scan to end terminal_index = index + len(KV_PREFIX) while terminal_index < len(data): if data[terminal_index] not in KV_CHARS: break terminal_index += 1 kv_string = data[index + len(KV_PREFIX):terminal_index] define_string = KV_PREFIX + kv_string hashes[define_string] = catbus_string_hash(kv_string) index = data.find(KV_PREFIX, index + 1) return hashes
def check_file(self, filename, data): filehash = catbus_string_hash(data) if self._client.check_file(filename)['hash'] != filehash: raise IOError("Firmware image does not match!")
def cli_loadwifi(self, line): def progress(length): sys.stdout.write("\rWrite: %5d bytes" % (length)) sys.stdout.flush() filename = 'wifi_firmware.bin' with open(filename, 'rb') as f: data = f.read() data_bytes = [ord(c) for c in data] # verify first byte (quick sanity check) if data_bytes[0] != 0xE9: print "Invalid firmware image!" return # compute firmware length, minus the md5 at the end # md5 is always 16 bytes fw_len = len(data) - 16 # get md5 from file file_md5 = data[fw_len:] md5_digest = hashlib.md5(data[:fw_len]).digest() if file_md5 != md5_digest: print "Invalid firmware image!" return # preprocessing should already be done by build script, # but leaving this here for now in case we need it. # # we override bytes 2 and 3 in the ESP8266 image # data_bytes[2] = 0 # data_bytes[3] = 0 # # # convert back to string # data = ''.join(map(chr, data_bytes)) # # # need to pad to sector length # padding_len = 4096 - (len(data) % 4096) # data += (chr(0xff) * padding_len) # # fw_len = len(data) # # md5_digest = hashlib.md5(data).digest() # data += md5_digest # # with open('wifi_firmware_padded.bin', 'w') as f: # f.write(data) print "\nLoading firmware image" try: self.delete_file(filename) except IOError: # file not found pass time.sleep(2.0) # give a second while file system erases blocks # calculate crc of file data filehash = catbus_string_hash(data) try: self.put_file(filename, data, progress=progress) except Exception as e: print type(e), e raise print "\nVerifying firmware image..." self.check_file(filename, data) print "Setting firmware length..." self.set_key('wifi_fw_len', fw_len) print "Setting MD5..." self.set_key('wifi_md5', binascii.hexlify(md5_digest)) print "Starting wifi firmware flasher..." self.reboot() time.sleep(5.0) for i in xrange(20): try: self.echo('') except DeviceUnreachableException: time.sleep(1.0) self.echo('') print "Firmware load complete"