Add multi-erase, beautify

This commit is contained in:
Bjoern Kerler 2022-06-28 13:53:44 +02:00
parent 3762ab9c9e
commit ad93c98404
No known key found for this signature in database
GPG key ID: 52E823BB96A55380
5 changed files with 210 additions and 204 deletions

9
edl
View file

@ -115,7 +115,7 @@ Options:
--skip=partnames Skip reading partition with names "partname1,partname2,etc." --skip=partnames Skip reading partition with names "partname1,partname2,etc."
--genxml Generate rawprogram[lun].xml --genxml Generate rawprogram[lun].xml
--devicemodel=value Set device model --devicemodel=value Set device model
--portname=portname Set serial port name (/dev/ttyUSB0 for Linux/MAC; \\.\COM1 for Windows) --portname=portname Set serial port name (/dev/ttyUSB0 for Linux/MAC; \\\\.\\COM1 for Windows)
--serial Use serial port (port autodetection) --serial Use serial port (port autodetection)
--slot Set active slot for setactiveslot [a or b] --slot Set active slot for setactiveslot [a or b]
--resetmode=mode Resetmode for reset (poweroff, reset, edl, etc.) --resetmode=mode Resetmode for reset (poweroff, reset, edl, etc.)
@ -155,6 +155,7 @@ def parse_cmd(rargs):
return cmd return cmd
return "" return ""
def console_cmd(cmd): def console_cmd(cmd):
read = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, read = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, close_fds=True) stderr=subprocess.STDOUT, close_fds=True)
@ -215,7 +216,7 @@ class main(metaclass=LogBase):
mode = resp["mode"] mode = resp["mode"]
self.info(f"Mode detected: {mode}") self.info(f"Mode detected: {mode}")
return resp return resp
return {"mode":"error"} return {"mode": "error"}
def exit(self): def exit(self):
self.cdc.close() self.cdc.close()
@ -275,7 +276,7 @@ class main(metaclass=LogBase):
else: else:
self.portname = "" self.portname = ""
if self.serial: if self.serial:
self.cdc = serial_class(loglevel=self.__logger.level,portconfig=portconfig) self.cdc = serial_class(loglevel=self.__logger.level, portconfig=portconfig)
else: else:
self.cdc = usb_class(portconfig=portconfig, loglevel=self.__logger.level) self.cdc = usb_class(portconfig=portconfig, loglevel=self.__logger.level)
@ -290,7 +291,6 @@ class main(metaclass=LogBase):
self.sahara.programmer = loader self.sahara.programmer = loader
self.info("Waiting for the device") self.info("Waiting for the device")
resp = None
self.cdc.timeout = 1500 self.cdc.timeout = 1500
conninfo = self.doconnect(loop) conninfo = self.doconnect(loop)
mode = conninfo["mode"] mode = conninfo["mode"]
@ -381,6 +381,7 @@ class main(metaclass=LogBase):
if fh.connect(sahara): if fh.connect(sahara):
fh.handle_firehose(cmd, options) fh.handle_firehose(cmd, options)
if __name__ == '__main__': if __name__ == '__main__':
base = main() base = main()
base.run() base.run()

View file

@ -16,16 +16,18 @@ from edlclient.Library.gpt import gpt
from edlclient.Library.sparse import QCSparse from edlclient.Library.sparse import QCSparse
from edlclient.Library.utils import progress from edlclient.Library.utils import progress
class response: class response:
resp=False resp = False
data=b"" data = b""
error="" error = ""
log=None log = None
def __init__(self, resp=False, data=b"", error:str="", log:dict=""):
self.resp=resp def __init__(self, resp=False, data=b"", error: str = "", log: dict = ""):
self.data=data self.resp = resp
self.error=error self.data = data
self.log=log self.error = error
self.log = log
try: try:
@ -66,8 +68,8 @@ class nand_partition:
name, offset, length, attr1, attr2, attr3, which_flash = unpack("16sIIBBBB", name, offset, length, attr1, attr2, attr3, which_flash = unpack("16sIIBBBB",
data[i * 0x1C:(i * 0x1C) + 0x1C]) data[i * 0x1C:(i * 0x1C) + 0x1C])
np = partf() np = partf()
if name[:2]==b"0:": if name[:2] == b"0:":
name=name[2:] name = name[2:]
np.name = name.rstrip(b"\x00").decode('utf-8').lower() np.name = name.rstrip(b"\x00").decode('utf-8').lower()
if self.parent.cfg.block_size == 0: if self.parent.cfg.block_size == 0:
np.sector = offset np.sector = offset
@ -80,7 +82,7 @@ class nand_partition:
np.attr3 = attr3 np.attr3 = attr3
np.which_flash = which_flash np.which_flash = which_flash
self.partentries[np.name] = np self.partentries[np.name] = np
if self.parent.cfg.block_size != 0 and self.parent.cfg.total_blocks!=0: if self.parent.cfg.block_size != 0 and self.parent.cfg.total_blocks != 0:
self.totalsectors = (self.parent.cfg.block_size // self.parent.cfg.SECTOR_SIZE_IN_BYTES) * \ self.totalsectors = (self.parent.cfg.block_size // self.parent.cfg.SECTOR_SIZE_IN_BYTES) * \
self.parent.cfg.total_blocks self.parent.cfg.total_blocks
else: else:
@ -252,7 +254,7 @@ class firehose(metaclass=LogBase):
rdata += tmp rdata += tmp
except Exception as err: except Exception as err:
self.error(err) self.error(err)
return response(resp=False,error=str(err)) return response(resp=False, error=str(err))
try: try:
if b"raw hex token" in rdata: if b"raw hex token" in rdata:
rdata = rdata rdata = rdata
@ -260,7 +262,7 @@ class firehose(metaclass=LogBase):
resp = self.xml.getresponse(rdata) resp = self.xml.getresponse(rdata)
status = self.getstatus(resp) status = self.getstatus(resp)
if "rawmode" in resp: if "rawmode" in resp:
if resp["rawmode"]=="false": if resp["rawmode"] == "false":
if status: if status:
log = self.xml.getlog(rdata) log = self.xml.getlog(rdata)
return response(resp=status, data=resp, log=log) return response(resp=status, data=resp, log=log)
@ -280,9 +282,9 @@ class firehose(metaclass=LogBase):
if status: if status:
return response(resp=True, data=resp) return response(resp=True, data=resp)
else: else:
error="" error = ""
if b"<log value" in rdata: if b"<log value" in rdata:
error=self.xml.getlog(rdata) error = self.xml.getlog(rdata)
return response(resp=False, error=error, data=resp) return response(resp=False, error=error, data=resp)
except Exception as err: except Exception as err:
self.debug(str(err)) self.debug(str(err))
@ -294,14 +296,14 @@ class firehose(metaclass=LogBase):
", Error: " + str(err)) ", Error: " + str(err))
elif isinstance(rdata, str): elif isinstance(rdata, str):
self.debug("Error on getting xml response:" + rdata) self.debug("Error on getting xml response:" + rdata)
return response(resp=False,error=rdata) return response(resp=False, error=rdata)
else: else:
return response(resp=True,data=rdata) return response(resp=True, data=rdata)
def cmd_reset(self, mode="reset"): def cmd_reset(self, mode="reset"):
if mode is None: if mode is None:
mode = "poweroff" mode = "poweroff"
data = "<?xml version=\"1.0\" ?><data><power value=\""+mode+"\"/></data>" data = "<?xml version=\"1.0\" ?><data><power value=\"" + mode + "\"/></data>"
val = self.xmlsend(data) val = self.xmlsend(data)
try: try:
v = None v = None
@ -319,7 +321,7 @@ class firehose(metaclass=LogBase):
self.info("Reset succeeded.") self.info("Reset succeeded.")
return True return True
else: else:
self.error("Reset failed: "+val.error) self.error("Reset failed: " + val.error)
return False return False
def cmd_xml(self, filename): def cmd_xml(self, filename):
@ -335,7 +337,8 @@ class firehose(metaclass=LogBase):
def cmd_nop(self): def cmd_nop(self):
data = "<?xml version=\"1.0\" ?><data><nop /></data>" data = "<?xml version=\"1.0\" ?><data><nop /></data>"
resp=self.xmlsend(data, True) resp = self.xmlsend(data, True)
self.debug(resp.hex())
info = b"" info = b""
tmp = None tmp = None
while tmp != b"": while tmp != b"":
@ -366,7 +369,7 @@ class firehose(metaclass=LogBase):
else: else:
return res return res
else: else:
self.error("GetSha256Digest failed: "+val.error) self.error("GetSha256Digest failed: " + val.error)
return False return False
def cmd_setbootablestoragedrive(self, partition_number): def cmd_setbootablestoragedrive(self, partition_number):
@ -379,9 +382,9 @@ class firehose(metaclass=LogBase):
self.error("Setbootablestoragedrive failed: " + val.error) self.error("Setbootablestoragedrive failed: " + val.error)
return False return False
def cmd_send(self, content, response=True): def cmd_send(self, content, responsexml=True):
data = f"<?xml version=\"1.0\" ?><data>\n<{content} /></data>" data = f"<?xml version=\"1.0\" ?><data>\n<{content} /></data>"
if response: if responsexml:
val = self.xmlsend(data) val = self.xmlsend(data)
if val.resp: if val.resp:
return val.data return val.data
@ -630,12 +633,12 @@ class firehose(metaclass=LogBase):
progbar.show_progress(prefix="Read", pos=0, total=total, display=display) progbar.show_progress(prefix="Read", pos=0, total=total, display=display)
while bytestoread > 0: while bytestoread > 0:
if self.cdc.is_serial: if self.cdc.is_serial:
maxsize=self.cfg.MaxPayloadSizeFromTargetInBytes maxsize = self.cfg.MaxPayloadSizeFromTargetInBytes
else: else:
maxsize=5*1024*1024 maxsize = 5 * 1024 * 1024
size=min(maxsize, bytestoread) size = min(maxsize, bytestoread)
data = usb_read(size) data = usb_read(size)
if len(data)>0: if len(data) > 0:
wr.write(data) wr.write(data)
bytestoread -= len(data) bytestoread -= len(data)
show_progress(prefix="Read", pos=total - bytestoread, total=total, display=display) show_progress(prefix="Read", pos=total - bytestoread, total=total, display=display)
@ -698,22 +701,22 @@ class firehose(metaclass=LogBase):
self.error(f"Error:") self.error(f"Error:")
for line in info: for line in info:
self.error(line) self.error(line)
return response(resp=False,data=resData, error=info) return response(resp=False, data=resData, error=info)
elif "rawmode" in rsp: elif "rawmode" in rsp:
if rsp["rawmode"] == "false": if rsp["rawmode"] == "false":
return response(resp=True,data=resData) return response(resp=True, data=resData)
else: else:
if len(rsp) > 1: if len(rsp) > 1:
if b"Failed to open the UFS Device" in rsp[2]: if b"Failed to open the UFS Device" in rsp[2]:
self.error(f"Error:{rsp[2]}") self.error(f"Error:{rsp[2]}")
self.lasterror = rsp[2] self.lasterror = rsp[2]
return response(resp=False,data=resData,error=rsp[2]) return response(resp=False, data=resData, error=rsp[2])
if rsp["value"]!="ACK": if rsp["value"] != "ACK":
self.lasterror = rsp[2] self.lasterror = rsp[2]
if display and prog != 100: if display and prog != 100:
progbar.show_progress(prefix="Read", pos=total, total=total, display=display) progbar.show_progress(prefix="Read", pos=total, total=total, display=display)
resp=rsp["value"]=="ACK" resp = rsp["value"] == "ACK"
return response(resp=resp,data=resData,error=rsp[2]) # Do not remove, needed for oneplus return response(resp=resp, data=resData, error=rsp[2]) # Do not remove, needed for oneplus
def get_gpt(self, lun, gpt_num_part_entries, gpt_part_entry_size, gpt_part_entry_start_lba): def get_gpt(self, lun, gpt_num_part_entries, gpt_part_entry_size, gpt_part_entry_start_lba):
try: try:
@ -723,7 +726,7 @@ class firehose(metaclass=LogBase):
self.skipresponse = True self.skipresponse = True
resp = self.cmd_read_buffer(lun, 0, 2, False) resp = self.cmd_read_buffer(lun, 0, 2, False)
if not resp.resp : if not resp.resp:
for line in resp.error: for line in resp.error:
self.error(line) self.error(line)
return None, None return None, None
@ -734,11 +737,11 @@ class firehose(metaclass=LogBase):
self.info("Scanning for partition table ...") self.info("Scanning for partition table ...")
progbar = progress(1) progbar = progress(1)
if self.nandpart.partitiontblsector is None: if self.nandpart.partitiontblsector is None:
sector=0x280 sector = 0x280
progbar.show_progress(prefix="Scanning", pos=sector, total=1024, display=True) progbar.show_progress(prefix="Scanning", pos=sector, total=1024, display=True)
resp = self.cmd_read_buffer(0, sector, 1, False) resp = self.cmd_read_buffer(0, sector, 1, False)
if resp.resp: if resp.resp:
if resp.data[0:8] in [b"\xac\x9f\x56\xfe\x7a\x12\x7f\xcd",b"\xAA\x73\xEE\x55\xDB\xBD\x5E\xE3"]: if resp.data[0:8] in [b"\xac\x9f\x56\xfe\x7a\x12\x7f\xcd", b"\xAA\x73\xEE\x55\xDB\xBD\x5E\xE3"]:
progbar.show_progress(prefix="Scanning", pos=1024, total=1024, display=True) progbar.show_progress(prefix="Scanning", pos=1024, total=1024, display=True)
self.nandpart.partitiontblsector = sector self.nandpart.partitiontblsector = sector
self.info(f"Found partition table at sector {sector} :)") self.info(f"Found partition table at sector {sector} :)")
@ -849,10 +852,10 @@ class firehose(metaclass=LogBase):
''' '''
rsp = self.xmlsend(connectcmd) rsp = self.xmlsend(connectcmd)
if not rsp.resp: if not rsp.resp:
if rsp.error=="": if rsp.error == "":
try: try:
if "MemoryName" in rsp.data: if "MemoryName" in rsp.data:
self.cfg.MemoryName = rsp.data["MemoryName"] self.cfg.MemoryName = rsp.data["MemoryName"]
except TypeError: except TypeError:
self.warning("!DEBUG! rsp.data: '%s'" % (rsp.data,)) self.warning("!DEBUG! rsp.data: '%s'" % (rsp.data,))
return self.configure(lvl + 1) return self.configure(lvl + 1)
@ -861,7 +864,8 @@ class firehose(metaclass=LogBase):
if "MaxPayloadSizeToTargetInBytes" in rsp.data: if "MaxPayloadSizeToTargetInBytes" in rsp.data:
self.cfg.MaxPayloadSizeToTargetInBytes = int(rsp.data["MaxPayloadSizeToTargetInBytes"]) self.cfg.MaxPayloadSizeToTargetInBytes = int(rsp.data["MaxPayloadSizeToTargetInBytes"])
if "MaxPayloadSizeToTargetInBytesSupported" in rsp.data: if "MaxPayloadSizeToTargetInBytesSupported" in rsp.data:
self.cfg.MaxPayloadSizeToTargetInBytesSupported = int(rsp.data["MaxPayloadSizeToTargetInBytesSupported"]) self.cfg.MaxPayloadSizeToTargetInBytesSupported = int(
rsp.data["MaxPayloadSizeToTargetInBytesSupported"])
if "TargetName" in rsp.data: if "TargetName" in rsp.data:
self.cfg.TargetName = rsp.data["TargetName"] self.cfg.TargetName = rsp.data["TargetName"]
return self.configure(lvl + 1) return self.configure(lvl + 1)
@ -924,7 +928,7 @@ class firehose(metaclass=LogBase):
self.warning(line) self.warning(line)
else: else:
info = self.cdc.read(timeout=1) info = self.cdc.read(timeout=1)
if isinstance(rsp.resp,dict): if isinstance(rsp.resp, dict):
field = rsp.resp field = rsp.resp
if "MemoryName" not in field: if "MemoryName" not in field:
# print(rsp[1]) # print(rsp[1])
@ -945,7 +949,8 @@ class firehose(metaclass=LogBase):
else: else:
self.cfg.MaxPayloadSizeToTargetInBytes = 1048576 self.cfg.MaxPayloadSizeToTargetInBytes = 1048576
if "MaxPayloadSizeToTargetInBytesSupported" in field: if "MaxPayloadSizeToTargetInBytesSupported" in field:
self.cfg.MaxPayloadSizeToTargetInBytesSupported = int(field["MaxPayloadSizeToTargetInBytesSupported"]) self.cfg.MaxPayloadSizeToTargetInBytesSupported = int(
field["MaxPayloadSizeToTargetInBytesSupported"])
else: else:
self.cfg.MaxPayloadSizeToTargetInBytesSupported = 1048576 self.cfg.MaxPayloadSizeToTargetInBytesSupported = 1048576
if "MaxXMLSizeInBytes" in field: if "MaxXMLSizeInBytes" in field:
@ -992,11 +997,11 @@ class firehose(metaclass=LogBase):
"Memory type UFS doesn't seem to match (Failed to init). Trying to use eMMC instead.") "Memory type UFS doesn't seem to match (Failed to init). Trying to use eMMC instead.")
self.cfg.MemoryName = "eMMC" self.cfg.MemoryName = "eMMC"
return self.configure(0) return self.configure(0)
elif "Attribute \'SECTOR_SIZE_IN_BYTES\'=4096 must be equal to disk sector size 512" in line\ elif "Attribute \'SECTOR_SIZE_IN_BYTES\'=4096 must be equal to disk sector size 512" in line \
or "different from device sector size (512)" in line: or "different from device sector size (512)" in line:
self.cfg.SECTOR_SIZE_IN_BYTES = 512 self.cfg.SECTOR_SIZE_IN_BYTES = 512
return self.configure(0) return self.configure(0)
elif "Attribute \'SECTOR_SIZE_IN_BYTES\'=512 must be equal to disk sector size 4096" in line\ elif "Attribute \'SECTOR_SIZE_IN_BYTES\'=512 must be equal to disk sector size 4096" in line \
or "different from device sector size (4096)" in line: or "different from device sector size (4096)" in line:
self.cfg.SECTOR_SIZE_IN_BYTES = 4096 self.cfg.SECTOR_SIZE_IN_BYTES = 4096
return self.configure(0) return self.configure(0)
@ -1011,8 +1016,8 @@ class firehose(metaclass=LogBase):
int(self.args["--gpt-part-entry-size"]), int(self.args["--gpt-part-entry-size"]),
int(self.args["--gpt-part-entry-start-lba"])) int(self.args["--gpt-part-entry-start-lba"]))
self.lunsizes[lun] = guid_gpt.totalsectors self.lunsizes[lun] = guid_gpt.totalsectors
except Exception as e: except Exception as err:
self.error(e) self.error(err)
return -1 return -1
else: else:
return self.lunsizes[lun] return self.lunsizes[lun]
@ -1090,7 +1095,7 @@ class firehose(metaclass=LogBase):
if info == [] or (len(info) > 0 and 'ERROR' in info[0]): if info == [] or (len(info) > 0 and 'ERROR' in info[0]):
if len(info) > 0: if len(info) > 0:
self.debug(info[0]) self.debug(info[0])
if len(info)>0: if len(info) > 0:
supfunc = False supfunc = False
for line in info: for line in info:
self.info(line) self.info(line)
@ -1110,11 +1115,11 @@ class firehose(metaclass=LogBase):
if "supported functions" in line.lower(): if "supported functions" in line.lower():
supfunc = True supfunc = True
if "program" in line.lower(): if "program" in line.lower():
idx=line.find("Functions: ") idx = line.find("Functions: ")
if idx!=-1: if idx != -1:
v=line[idx+11:].split(" ") v = line[idx + 11:].split(" ")
for val in v: for val in v:
if val!="": if val != "":
self.supported_functions.append(val) self.supported_functions.append(val)
supfunc = False supfunc = False
try: try:
@ -1154,7 +1159,7 @@ class firehose(metaclass=LogBase):
def parse_storage(self): def parse_storage(self):
storageinfo = self.cmd_getstorageinfo() storageinfo = self.cmd_getstorageinfo()
if storageinfo is None or storageinfo.resp and len(storageinfo.data)==0: if storageinfo is None or storageinfo.resp and len(storageinfo.data) == 0:
return False return False
info = storageinfo.data info = storageinfo.data
if "UFS Inquiry Command Output" in info: if "UFS Inquiry Command Output" in info:
@ -1193,18 +1198,18 @@ class firehose(metaclass=LogBase):
def cmd_getstorageinfo(self): def cmd_getstorageinfo(self):
data = "<?xml version=\"1.0\" ?><data><getstorageinfo physical_partition_number=\"0\"/></data>" data = "<?xml version=\"1.0\" ?><data><getstorageinfo physical_partition_number=\"0\"/></data>"
val = self.xmlsend(data) val = self.xmlsend(data)
if val.data=='' and val.log=='' and val.resp: if val.data == '' and val.log == '' and val.resp:
return None return None
if isinstance(val.data,dict): if isinstance(val.data, dict):
if "bNumberLu" in val.data: if "bNumberLu" in val.data:
self.cfg.maxlun = int(val.data["bNumberLu"]) self.cfg.maxlun = int(val.data["bNumberLu"])
if val.resp: if val.resp:
if val.log is not None: if val.log is not None:
res={} res = {}
for value in val.log: for value in val.log:
v=value.split("=") v = value.split("=")
if len(v)>1: if len(v) > 1:
res[v[0]]=v[1] res[v[0]] = v[1]
else: else:
if "\"storage_info\"" in value: if "\"storage_info\"" in value:
try: try:
@ -1229,23 +1234,23 @@ class firehose(metaclass=LogBase):
if "prod_name" in si: if "prod_name" in si:
self.cfg.prod_name = si["prod_name"] self.cfg.prod_name = si["prod_name"]
else: else:
v=value.split(":") v = value.split(":")
if len(v)>1: if len(v) > 1:
res[v[0]]=v[1].lstrip(" ") res[v[0]] = v[1].lstrip(" ")
return response(resp=val.resp, data=res) return response(resp=val.resp, data=res)
return response(resp=val.resp, data=val.data) return response(resp=val.resp, data=val.data)
else: else:
if val.error: if val.error:
for v in val.error: for v in val.error:
if "Failed to open the SDCC Device" in v: if "Failed to open the SDCC Device" in v:
self.cfg.MemoryName="ufs" self.cfg.MemoryName = "ufs"
self.configure(0) self.configure(0)
return self.cmd_getstorageinfo() return self.cmd_getstorageinfo()
self.warning("GetStorageInfo command isn't supported.") self.warning("GetStorageInfo command isn't supported.")
return None return None
def cmd_setactiveslot(self, slot:str): def cmd_setactiveslot(self, slot: str):
if slot.lower() not in ["a","b"]: if slot.lower() not in ["a", "b"]:
self.error("Only slots a or b are accepted. Aborting.") self.error("Only slots a or b are accepted. Aborting.")
return False return False
partslots = {} partslots = {}
@ -1275,8 +1280,8 @@ class firehose(metaclass=LogBase):
byte_offset_patch = poffset % self.cfg.SECTOR_SIZE_IN_BYTES byte_offset_patch = poffset % self.cfg.SECTOR_SIZE_IN_BYTES
headeroffset = gp.header.current_lba * gp.sectorsize headeroffset = gp.header.current_lba * gp.sectorsize
start_sector_hdr = headeroffset // self.cfg.SECTOR_SIZE_IN_BYTES start_sector_hdr = headeroffset // self.cfg.SECTOR_SIZE_IN_BYTES
header = wdata[start_sector_hdr:start_sector_hdr+gp.header.header_size] header = wdata[start_sector_hdr:start_sector_hdr + gp.header.header_size]
self.cmd_patch(lun,start_sector_patch,byte_offset_patch,pdata,len(pdata),True) self.cmd_patch(lun, start_sector_patch, byte_offset_patch, pdata, len(pdata), True)
self.cmd_patch(lun, headeroffset, 0, header, len(pdata), True) self.cmd_patch(lun, headeroffset, 0, header, len(pdata), True)
return True return True
return False return False
@ -1348,8 +1353,8 @@ class firehose(metaclass=LogBase):
f"SizeInBytes=\"{str(maxsize)}\" value64=\"{content}\" /></data>\n" f"SizeInBytes=\"{str(maxsize)}\" value64=\"{content}\" /></data>\n"
try: try:
self.cdc.write(xdata[:self.cfg.MaxXMLSizeInBytes]) self.cdc.write(xdata[:self.cfg.MaxXMLSizeInBytes])
except Exception as e: # pylint: disable=broad-except except Exception as err: # pylint: disable=broad-except
self.debug(str(e)) self.debug(str(err))
pass pass
addrinfo = self.cdc.read(timeout=None) addrinfo = self.cdc.read(timeout=None)
if b"SizeInBytes" in addrinfo or b"Invalid parameters" in addrinfo: if b"SizeInBytes" in addrinfo or b"Invalid parameters" in addrinfo:

View file

@ -785,6 +785,8 @@ class firehose_client(metaclass=LogBase):
return False return False
luns = self.getluns(options) luns = self.getluns(options)
partitionname = options["<partitionname>"] partitionname = options["<partitionname>"]
partitions = partitionname.split(",")
error = False
for lun in luns: for lun in luns:
data, guid_gpt = self.firehose.get_gpt(lun, int(options["--gpt-num-part-entries"]), data, guid_gpt = self.firehose.get_gpt(lun, int(options["--gpt-num-part-entries"]),
int(options["--gpt-part-entry-size"]), int(options["--gpt-part-entry-size"]),
@ -793,20 +795,21 @@ class firehose_client(metaclass=LogBase):
break break
if self.firehose.modules is not None: if self.firehose.modules is not None:
self.firehose.modules.writeprepare() self.firehose.modules.writeprepare()
for partitionname in partitions:
if partitionname in guid_gpt.partentries: if partitionname in guid_gpt.partentries:
partition = guid_gpt.partentries[partitionname] partition = guid_gpt.partentries[partitionname]
self.firehose.cmd_erase(lun, partition.sector, partition.sectors) self.firehose.cmd_erase(lun, partition.sector, partition.sectors)
self.printer( self.printer(
f"Erased {partitionname} starting at sector {str(partition.sector)} " + f"Erased {partitionname} starting at sector {str(partition.sector)} " +
f"with sector count {str(partition.sectors)}.") f"with sector count {str(partition.sectors)}.")
return True else:
else: self.printer(
self.printer( f"Couldn't erase partition {partitionname}. Either wrong memorytype given or no gpt partition.")
f"Couldn't erase partition {partitionname}. Either wrong memorytype given or no gpt partition.") error = True
return False continue
self.error(f"Error: Couldn't detect partition: {partitionname}") if error:
return False return False
return True
elif cmd == "ep": elif cmd == "ep":
if not self.check_param(["<partitionname>", "<sectors>"]): if not self.check_param(["<partitionname>", "<sectors>"]):
return False return False

View file

@ -220,11 +220,11 @@ def main(argv):
if len(argv) < 3: if len(argv) < 3:
print("Usage: fhloaderparse [FHLoaderDir] [OutputDir]") print("Usage: fhloaderparse [FHLoaderDir] [OutputDir]")
exit(0) exit(0)
else:
path = argv[1] path = argv[1]
outputdir = argv[2] outputdir = argv[2]
if not os.path.exists(outputdir): if not os.path.exists(outputdir):
os.mkdir(outputdir) os.mkdir(outputdir)
# First hash all loaders in Loader directory # First hash all loaders in Loader directory
hashes = {} hashes = {}

View file

@ -12,6 +12,7 @@ from enum import Enum
from struct import unpack, pack from struct import unpack, pack
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
import os, sys import os, sys
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parent_dir = os.path.dirname(os.path.dirname(current_dir)) parent_dir = os.path.dirname(os.path.dirname(current_dir))
sys.path.insert(0, parent_dir) sys.path.insert(0, parent_dir)
@ -342,7 +343,7 @@ class qcdiag(metaclass=LogBase):
def prettyprint(self, data): def prettyprint(self, data):
recv = "" recv = ""
plain = "" plain = ""
if len(data)==0: if len(data) == 0:
return "" return ""
for i in range(len(data)): for i in range(len(data)):
inf = "%02X " % data[i] inf = "%02X " % data[i]
@ -378,9 +379,9 @@ class qcdiag(metaclass=LogBase):
else: else:
return "Command accepted" return "Command accepted"
def connect(self, serial:bool = False): def connect(self, serial: bool = False):
if serial: if serial:
self.cdc = serial_class(loglevel=self.__logger.level,portconfig=self.portconfig) self.cdc = serial_class(loglevel=self.__logger.level, portconfig=self.portconfig)
else: else:
self.cdc = usb_class(portconfig=self.portconfig, loglevel=self.__logger.level) self.cdc = usb_class(portconfig=self.portconfig, loglevel=self.__logger.level)
self.hdlc = None self.hdlc = None
@ -414,13 +415,12 @@ class qcdiag(metaclass=LogBase):
def enter_saharamode(self): def enter_saharamode(self):
self.hdlc.receive_reply(timeout=0) self.hdlc.receive_reply(timeout=0)
res = self.send(b"\x4b\x65\x01\x00") res = self.send(b"\x4b\x65\x01\x00")
if res[0]==0x4b: if res[0] == 0x4b:
print("Done, switched to edl") print("Done, switched to edl")
else: else:
print("Error switching to edl. Try again.") print("Error switching to edl. Try again.")
self.disconnect() self.disconnect()
def send_sp(self, sp="FFFFFFFFFFFFFFFFFFFE"): def send_sp(self, sp="FFFFFFFFFFFFFFFFFFFE"):
if type(sp) == str: if type(sp) == str:
sp = unhexlify(sp) sp = unhexlify(sp)
@ -504,13 +504,13 @@ class qcdiag(metaclass=LogBase):
print(nvitem) print(nvitem)
def print_nvitemsub(self, item, index): def print_nvitemsub(self, item, index):
res, nvitem = self.read_nvitemsub(item,index) res, nvitem = self.read_nvitemsub(item, index)
info = self.DecodeNVItems(nvitem) info = self.DecodeNVItems(nvitem)
if res != False: if res != False:
if nvitem.name != "": if nvitem.name != "":
ItemNumber = f"{hex(item),hex(index)} ({nvitem.name}): " ItemNumber = f"{hex(item), hex(index)} ({nvitem.name}): "
else: else:
ItemNumber = hex(item)+","+hex(index) + ": " ItemNumber = hex(item) + "," + hex(index) + ": "
returnanswer = "NVItem " + ItemNumber + info returnanswer = "NVItem " + ItemNumber + info
print(returnanswer) print(returnanswer)
if nvitem.status == 0: if nvitem.status == 0:
@ -549,7 +549,7 @@ class qcdiag(metaclass=LogBase):
write_handle.write(errors) write_handle.write(errors)
print("Done.") print("Done.")
def unpackdata(self,data): def unpackdata(self, data):
rlen = len(data) rlen = len(data)
idx = rlen - 1 idx = rlen - 1
for i in range(0, rlen): for i in range(0, rlen):
@ -572,8 +572,8 @@ class qcdiag(metaclass=LogBase):
name = "" name = ""
if item in self.nvlist: if item in self.nvlist:
name = self.nvlist[item] name = self.nvlist[item]
data=self.unpackdata(res["rawdata"]) data = self.unpackdata(res["rawdata"])
res = nvitem(res["item"],0, data, res["status"], name) res = nvitem(res["item"], 0, data, res["status"], name)
return [True, res] return [True, res]
elif data[0] == 0x14: elif data[0] == 0x14:
return [False, f"Error 0x14 trying to read nvitem {hex(item)}."] return [False, f"Error 0x14 trying to read nvitem {hex(item)}."]
@ -594,7 +594,7 @@ class qcdiag(metaclass=LogBase):
name = "" name = ""
if item in self.nvlist: if item in self.nvlist:
name = self.nvlist[item] name = self.nvlist[item]
data=self.unpackdata(res["rawdata"]) data = self.unpackdata(res["rawdata"])
res = nvitem(res["item"], index, data, res["status"], name) res = nvitem(res["item"], index, data, res["status"], name)
return [True, res] return [True, res]
elif data[0] == 0x14: elif data[0] == 0x14:
@ -603,27 +603,27 @@ class qcdiag(metaclass=LogBase):
return [False, f"Error {hex(data[0])} trying to read nvitem {hex(item)}."] return [False, f"Error {hex(data[0])} trying to read nvitem {hex(item)}."]
return [False, f"Empty request for nvitem {hex(item)}"] return [False, f"Empty request for nvitem {hex(item)}"]
def convertimei(self,imei): def convertimei(self, imei):
data=imei[0]+"A" data = imei[0] + "A"
for i in range(1,len(imei),2): for i in range(1, len(imei), 2):
data+=imei[i+1] data += imei[i + 1]
data+=imei[i] data += imei[i]
return unhexlify("08"+data) return unhexlify("08" + data)
def write_imei(self,imeis): def write_imei(self, imeis):
if "," in imeis: if "," in imeis:
imeis=imeis.split(",") imeis = imeis.split(",")
else: else:
imeis=[imeis] imeis = [imeis]
index=0 index = 0
for imei in imeis: for imei in imeis:
data=self.convertimei(imei) data = self.convertimei(imei)
if index==0: if index == 0:
if not self.write_nvitem(550,data): if not self.write_nvitem(550, data):
self.write_nvitemsub(550,index,data) self.write_nvitemsub(550, index, data)
else: else:
self.write_nvitemsub(550,index,data) self.write_nvitemsub(550, index, data)
index+=1 index += 1
def write_nvitem(self, item, data): def write_nvitem(self, item, data):
rawdata = bytes(data) rawdata = bytes(data)
@ -656,12 +656,13 @@ class qcdiag(metaclass=LogBase):
res = self.send(nvrequest) res = self.send(nvrequest)
if len(res) > 0: if len(res) > 0:
if res[0] == 0x4B: if res[0] == 0x4B:
res, nvitem = self.read_nvitemsub(item,index) res, nvitem = self.read_nvitemsub(item, index)
if res == False: if res == False:
print(f"Error while writing nvitem {hex(item)} index {hex(index)} data, %s" % data) print(f"Error while writing nvitem {hex(item)} index {hex(index)} data, %s" % data)
else: else:
if nvitem.data != data: if nvitem.data != data:
print(f"Error while writing nvitem {hex(item)} index {hex(index)} data, verified data doesn't match") print(
f"Error while writing nvitem {hex(item)} index {hex(index)} data, verified data doesn't match")
else: else:
print(f"Successfully wrote nvitem {hex(item)} index {hex(index)}.") print(f"Successfully wrote nvitem {hex(item)} index {hex(index)}.")
return True return True
@ -882,12 +883,12 @@ class qcdiag(metaclass=LogBase):
if len(resp) > 0: if len(resp) > 0:
[dirp, seqno, diag_errno, entry_type, mode, size, atime, mtime, ctime] = unpack("<Iiiiiiiii", [dirp, seqno, diag_errno, entry_type, mode, size, atime, mtime, ctime] = unpack("<Iiiiiiiii",
resp[4:4 + (9 * 4)]) resp[4:4 + (9 * 4)])
if entry_type==1: if entry_type == 1:
entry_name = resp[4 + (9 * 4):-1] entry_name = resp[4 + (9 * 4):-1]
if len(entry_name)<50: if len(entry_name) < 50:
entry_name+=(50-len(entry_name))*b" " entry_name += (50 - len(entry_name)) * b" "
info += f"{path}{entry_name.decode('utf-8')} mode:{hex(mode)}, size:{hex(size)}, atime:{hex(atime)}, mtime:{hex(mtime)}, ctime:{hex(ctime)}\n" info += f"{path}{entry_name.decode('utf-8')} mode:{hex(mode)}, size:{hex(size)}, atime:{hex(atime)}, mtime:{hex(mtime)}, ctime:{hex(ctime)}\n"
elif entry_type==0: elif entry_type == 0:
break break
if self.efs_closedir(efsmethod, dirp) != 0: if self.efs_closedir(efsmethod, dirp) != 0:
print("Error on listing directory") print("Error on listing directory")
@ -1179,37 +1180,37 @@ class DiagTools(metaclass=LogBase):
if connected: if connected:
cmd = args.cmd cmd = args.cmd
if cmd=="sp": if cmd == "sp":
diag.send_sp(args.spval) diag.send_sp(args.spval)
elif cmd=="spc": elif cmd == "spc":
diag.send_spc(args.spcval) diag.send_spc(args.spcval)
elif cmd=="cmd": elif cmd == "cmd":
if args.cmdval=="": if args.cmdval == "":
print("cmd needed as hex string, example: 00") print("cmd needed as hex string, example: 00")
else: else:
print(diag.send_cmd(args.cmdval)) print(diag.send_cmd(args.cmdval))
elif cmd=="info": elif cmd == "info":
print(diag.cmd_info()) print(diag.cmd_info())
elif cmd=="download": elif cmd == "download":
diag.enter_downloadmode() diag.enter_downloadmode()
elif cmd=="sahara": elif cmd == "sahara":
diag.enter_saharamode() diag.enter_saharamode()
elif cmd=="crash": elif cmd == "crash":
diag.enforce_crash() diag.enforce_crash()
elif cmd=="efslistdir": elif cmd == "efslistdir":
print(diag.efslistdir(args.path)) print(diag.efslistdir(args.path))
elif cmd=="efsreadfile": elif cmd == "efsreadfile":
if args.src=="" or args.dst=="": if args.src == "" or args.dst == "":
print("Usage: -efsreadfile -src srcfile -dst dstfile") print("Usage: -efsreadfile -src srcfile -dst dstfile")
sys.exit() sys.exit()
print(diag.efsreadfile(args.src,args.dst)) print(diag.efsreadfile(args.src, args.dst))
elif cmd=="nvread": elif cmd == "nvread":
if "0x" in args.nvitem: if "0x" in args.nvitem:
nvitem = int(args.nvitem, 16) nvitem = int(args.nvitem, 16)
else: else:
nvitem = int(args.nvitem) nvitem = int(args.nvitem)
diag.print_nvitem(nvitem) diag.print_nvitem(nvitem)
elif cmd=="nvreadsub": elif cmd == "nvreadsub":
if args.nvitem is None or args.nvindex is None: if args.nvitem is None or args.nvindex is None:
print("Usage: nvreadsub [nvitem] [nvindex]") print("Usage: nvreadsub [nvitem] [nvindex]")
exit(1) exit(1)
@ -1222,8 +1223,8 @@ class DiagTools(metaclass=LogBase):
nvindex = int(args.nvindex, 16) nvindex = int(args.nvindex, 16)
else: else:
nvindex = int(args.nvindex) nvindex = int(args.nvindex)
diag.print_nvitemsub(nvitem,nvindex) diag.print_nvitemsub(nvitem, nvindex)
elif cmd=="nvwrite": elif cmd == "nvwrite":
if args.data is None: if args.data is None:
print("NvWrite requires data to write") print("NvWrite requires data to write")
sys.exit() sys.exit()
@ -1233,7 +1234,7 @@ class DiagTools(metaclass=LogBase):
nvitem = int(args.nvitem) nvitem = int(args.nvitem)
data = unhexlify(args.data) data = unhexlify(args.data)
diag.write_nvitem(nvitem, data) diag.write_nvitem(nvitem, data)
elif cmd=="nvwritesub": elif cmd == "nvwritesub":
if args.nvitem is None or args.nvindex is None or args.data is None: if args.nvitem is None or args.nvindex is None or args.data is None:
print("NvWriteSub requires item, index and data to write") print("NvWriteSub requires item, index and data to write")
sys.exit() sys.exit()
@ -1247,11 +1248,11 @@ class DiagTools(metaclass=LogBase):
nvindex = int(args.nvindex) nvindex = int(args.nvindex)
data = unhexlify(args.data) data = unhexlify(args.data)
diag.write_nvitemsub(nvitem, nvindex, data) diag.write_nvitemsub(nvitem, nvindex, data)
elif cmd=="nvbackup": elif cmd == "nvbackup":
diag.backup_nvitems(args.filename, "error.log") diag.backup_nvitems(args.filename, "error.log")
elif cmd=="writeimei": elif cmd == "writeimei":
diag.write_imei(args.imei) diag.write_imei(args.imei)
elif cmd=="efsread": elif cmd == "efsread":
diag.efsread(args.filename) diag.efsread(args.filename)
else: else:
print("A command is required. Use -cmd \"data\" for sending requests.") print("A command is required. Use -cmd \"data\" for sending requests.")
@ -1259,8 +1260,8 @@ class DiagTools(metaclass=LogBase):
print("Valid commands are:") print("Valid commands are:")
print("-------------------") print("-------------------")
print("info cmd sp spc nvread nvreadsub" + print("info cmd sp spc nvread nvreadsub" +
" nvwrite writeimei nvwritesub nvbackup efsread efsreadfile" + " nvwrite writeimei nvwritesub nvbackup efsread efsreadfile" +
" efslistdir download sahara crash") " efslistdir download sahara crash")
print() print()
diag.disconnect() diag.disconnect()
sys.exit() sys.exit()
@ -1275,54 +1276,53 @@ def main():
parser = argparse.ArgumentParser(description=info) parser = argparse.ArgumentParser(description=info)
print("\n" + info + "\n---------------------------------------\n") print("\n" + info + "\n---------------------------------------\n")
subparser = parser.add_subparsers(dest="cmd", help="Valid commands are:\ninfo cmd sp spc nvread nvreadsub" + subparser = parser.add_subparsers(dest="cmd", help="Valid commands are:\ninfo cmd sp spc nvread nvreadsub" +
" nvwrite writeimei nvwritesub nvbackup efsread efsreadfile\n" + " nvwrite writeimei nvwritesub nvbackup efsread efsreadfile\n" +
" efslistdir download sahara crash") " efslistdir download sahara crash")
parser_info = subparser.add_parser("info", help="[Option] Get diag info") parser_info = subparser.add_parser("info", help="[Option] Get diag info")
parser_info.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_info.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_info.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_info.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_info.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_info.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_info.add_argument("-portname", metavar="<portname>", parser_info.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_info.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_info.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_info.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_info.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_cmd = subparser.add_parser("cmd", help="Send command") parser_cmd = subparser.add_parser("cmd", help="Send command")
parser_cmd.add_argument("cmdval", help="cmd to send (hexstring), default: 00", parser_cmd.add_argument("cmdval", help="cmd to send (hexstring), default: 00",
default="", const="00", nargs="?") default="", const="00", nargs="?")
parser_cmd.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_cmd.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_cmd.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_cmd.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_cmd.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_cmd.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_cmd.add_argument("-portname", metavar="<portname>", parser_cmd.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_cmd.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_cmd.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_cmd.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_cmd.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_sp = subparser.add_parser("sp", help="Send Security password") parser_sp = subparser.add_parser("sp", help="Send Security password")
parser_sp.add_argument("spval", help="Security password to send, default: FFFFFFFFFFFFFFFE", parser_sp.add_argument("spval", help="Security password to send, default: FFFFFFFFFFFFFFFE",
default="FFFFFFFFFFFFFFFE", nargs="?") default="FFFFFFFFFFFFFFFE", nargs="?")
parser_sp.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_sp.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_sp.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_sp.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_sp.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_sp.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_sp.add_argument("-portname", metavar="<portname>", parser_sp.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_sp.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_sp.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_sp.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_sp.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_spc = subparser.add_parser("spc", help="Send Security Code") parser_spc = subparser.add_parser("spc", help="Send Security Code")
parser_spc.add_argument("spcval", help="Security code to send, default: 303030303030", parser_spc.add_argument("spcval", help="Security code to send, default: 303030303030",
default="303030303030", nargs="?") default="303030303030", nargs="?")
parser_spc.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_spc.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_spc.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_spc.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_spc.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_spc.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_spc.add_argument("-portname", metavar="<portname>", parser_spc.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_spc.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_spc.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_spc.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_spc.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_nvread = subparser.add_parser("nvread", help="Read nvitem") parser_nvread = subparser.add_parser("nvread", help="Read nvitem")
@ -1330,10 +1330,10 @@ def main():
parser_nvread.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_nvread.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_nvread.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_nvread.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_nvread.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_nvread.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_nvread.add_argument("-portname", metavar="<portname>", parser_nvread.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_nvread.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_nvread.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_nvread.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_nvread.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_nvreadsub = subparser.add_parser("nvreadsub", help="Read nvitem using subsystem") parser_nvreadsub = subparser.add_parser("nvreadsub", help="Read nvitem using subsystem")
@ -1342,10 +1342,10 @@ def main():
parser_nvreadsub.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_nvreadsub.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_nvreadsub.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_nvreadsub.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_nvreadsub.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_nvreadsub.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_nvreadsub.add_argument("-portname", metavar="<portname>", parser_nvreadsub.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_nvreadsub.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_nvreadsub.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_nvreadsub.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_nvreadsub.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_nvwrite = subparser.add_parser("nvwrite", help="Write nvitem") parser_nvwrite = subparser.add_parser("nvwrite", help="Write nvitem")
@ -1354,10 +1354,10 @@ def main():
parser_nvwrite.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_nvwrite.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_nvwrite.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_nvwrite.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_nvwrite.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_nvwrite.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_nvwrite.add_argument("-portname", metavar="<portname>", parser_nvwrite.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_nvwrite.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_nvwrite.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_nvwrite.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_nvwrite.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_nvwritesub = subparser.add_parser("nvwritesub", help="Write nvitem using subsystem") parser_nvwritesub = subparser.add_parser("nvwritesub", help="Write nvitem using subsystem")
@ -1367,10 +1367,10 @@ def main():
parser_nvwritesub.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_nvwritesub.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_nvwritesub.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_nvwritesub.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_nvwritesub.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_nvwritesub.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_nvwritesub.add_argument("-portname", metavar="<portname>", parser_nvwritesub.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_nvwritesub.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_nvwritesub.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_nvwritesub.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_nvwritesub.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_writeimei = subparser.add_parser("writeimei", help="Write imei") parser_writeimei = subparser.add_parser("writeimei", help="Write imei")
@ -1378,22 +1378,21 @@ def main():
parser_writeimei.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_writeimei.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_writeimei.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_writeimei.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_writeimei.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_writeimei.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_writeimei.add_argument("-portname", metavar="<portname>", parser_writeimei.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_writeimei.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_writeimei.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_writeimei.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_writeimei.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_nvbackup = subparser.add_parser("nvbackup", help="Make nvitem backup as json") parser_nvbackup = subparser.add_parser("nvbackup", help="Make nvitem backup as json")
parser_nvbackup.add_argument("filename", help="[Option] Filename to write to", default="") parser_nvbackup.add_argument("filename", help="[Option] Filename to write to", default="")
parser_nvbackup.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_nvbackup.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_nvbackup.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_nvbackup.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_nvbackup.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_nvbackup.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_nvbackup.add_argument("-portname", metavar="<portname>", parser_nvbackup.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_nvbackup.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_nvbackup.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_nvbackup.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_nvbackup.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_efsread = subparser.add_parser("efsread", help="Read efs") parser_efsread = subparser.add_parser("efsread", help="Read efs")
@ -1401,10 +1400,10 @@ def main():
parser_efsread.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_efsread.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_efsread.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_efsread.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_efsread.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_efsread.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_efsread.add_argument("-portname", metavar="<portname>", parser_efsread.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_efsread.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_efsread.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_efsread.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_efsread.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_efsreadfile = subparser.add_parser("efsreadfile", help="Read efs file") parser_efsreadfile = subparser.add_parser("efsreadfile", help="Read efs file")
@ -1413,10 +1412,10 @@ def main():
parser_efsreadfile.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_efsreadfile.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_efsreadfile.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_efsreadfile.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_efsreadfile.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_efsreadfile.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_efsreadfile.add_argument("-portname", metavar="<portname>", parser_efsreadfile.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_efsreadfile.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_efsreadfile.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_efsreadfile.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_efsreadfile.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_efslistdir = subparser.add_parser("efslistdir", help="List efs directory") parser_efslistdir = subparser.add_parser("efslistdir", help="List efs directory")
@ -1424,43 +1423,42 @@ def main():
parser_efslistdir.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_efslistdir.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_efslistdir.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_efslistdir.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_efslistdir.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_efslistdir.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_efslistdir.add_argument("-portname", metavar="<portname>", parser_efslistdir.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_efslistdir.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_efslistdir.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_efslistdir.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_efslistdir.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_download = subparser.add_parser("download", help="[Option] Switch to sahara mode") parser_download = subparser.add_parser("download", help="[Option] Switch to sahara mode")
parser_download.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_download.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_download.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_download.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_download.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_download.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_download.add_argument("-portname", metavar="<portname>", parser_download.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_download.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_download.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_download.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_download.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_sahara = subparser.add_parser("sahara", help="[Option] Switch to sahara mode") parser_sahara = subparser.add_parser("sahara", help="[Option] Switch to sahara mode")
parser_sahara.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_sahara.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_sahara.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_sahara.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_sahara.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_sahara.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_sahara.add_argument("-portname", metavar="<portname>", parser_sahara.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_sahara.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_sahara.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_sahara.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_sahara.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
parser_crash = subparser.add_parser("crash", help="[Option] Enforce crash") parser_crash = subparser.add_parser("crash", help="[Option] Enforce crash")
parser_crash.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="") parser_crash.add_argument("-vid", metavar="<vid>", help="[Option] Specify vid", default="")
parser_crash.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="") parser_crash.add_argument("-pid", metavar="<pid>", help="[Option] Specify pid", default="")
parser_crash.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)", parser_crash.add_argument("-interface", metavar="<pid>", help="[Option] Specify interface number, default=0)",
default="0") default="0")
parser_crash.add_argument("-portname", metavar="<portname>", parser_crash.add_argument("-portname", metavar="<portname>",
help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")") help="[Option] Specify serial port (\"/dev/ttyUSB0\",\"COM1\")")
parser_crash.add_argument("-serial",help="[Option] Use serial port (autodetect)", action="store_true") parser_crash.add_argument("-serial", help="[Option] Use serial port (autodetect)", action="store_true")
parser_crash.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true") parser_crash.add_argument("-debugmode", help="[Option] Enable verbose logging", action="store_true")
args = parser.parse_args() args = parser.parse_args()
dg = DiagTools() dg = DiagTools()
dg.run(args) dg.run(args)
@ -1468,4 +1466,3 @@ def main():
if __name__ == "__main__": if __name__ == "__main__":
main() main()