diff --git a/edlclient/Library/firehose.py b/edlclient/Library/firehose.py
index 4bad1a1..38cbfb7 100755
--- a/edlclient/Library/firehose.py
+++ b/edlclient/Library/firehose.py
@@ -15,6 +15,21 @@ from edlclient.Library.utils import *
from edlclient.Library.gpt import gpt
from edlclient.Library.sparse import QCSparse
from edlclient.Library.utils import progress
+from queue import Queue
+from threading import Thread
+
+rq = Queue()
+
+def writedata(filename, rq):
+ pos = 0
+ with open(filename, "wb") as wf:
+ while True:
+ data = rq.get()
+ if data is None:
+ break
+ pos += len(data)
+ wf.write(data)
+ rq.task_done()
class response:
@@ -606,6 +621,7 @@ class firehose(metaclass=LogBase):
return True
def cmd_read(self, physical_partition_number, start_sector, num_partition_sectors, filename, display=True):
+ global rq
self.lasterror = b""
progbar = progress(self.cfg.SECTOR_SIZE_IN_BYTES)
if display:
@@ -613,52 +629,56 @@ class firehose(metaclass=LogBase):
f"\nReading from physical partition {str(physical_partition_number)}, " +
f"sector {str(start_sector)}, sectors {str(num_partition_sectors)}")
- with open(file=filename, mode="wb", buffering=self.cfg.MaxPayloadSizeFromTargetInBytes) as wr:
- data = f"\n"
+ data = f"\n"
- rsp = self.xmlsend(data, self.skipresponse)
- self.cdc.xmlread = False
- time.sleep(0.01)
- if not rsp.resp:
- if display:
- self.error(rsp.error)
- return b""
- else:
- bytestoread = self.cfg.SECTOR_SIZE_IN_BYTES * num_partition_sectors
- total = bytestoread
- show_progress = progbar.show_progress
- usb_read = self.cdc.read
- progbar.show_progress(prefix="Read", pos=0, total=total, display=display)
- while bytestoread > 0:
- if self.cdc.is_serial:
- maxsize = self.cfg.MaxPayloadSizeFromTargetInBytes
- else:
- maxsize = 5 * 1024 * 1024
- size = min(maxsize, bytestoread)
- data = usb_read(size)
- if len(data) > 0:
- wr.write(data)
- bytestoread -= len(data)
- show_progress(prefix="Read", pos=total - bytestoread, total=total, display=display)
- self.cdc.xmlread = True
- wd = self.wait_for_data()
- info = self.xml.getlog(wd)
- rsp = self.xml.getresponse(wd)
- if "value" in rsp:
- if rsp["value"] != "ACK":
+ rsp = self.xmlsend(data, self.skipresponse)
+ self.cdc.xmlread = False
+ time.sleep(0.01)
+ if not rsp.resp:
+ if display:
+ self.error(rsp.error)
+ return b""
+ else:
+ bytestoread = self.cfg.SECTOR_SIZE_IN_BYTES * num_partition_sectors
+ total = bytestoread
+ show_progress = progbar.show_progress
+ usb_read = self.cdc.read
+ progbar.show_progress(prefix="Read", pos=0, total=total, display=display)
+ worker = Thread(target=writedata, args=(filename, rq), daemon=True)
+ worker.start()
+ while bytestoread > 0:
+ if self.cdc.is_serial:
+ maxsize = self.cfg.MaxPayloadSizeFromTargetInBytes
+ else:
+ maxsize = 5 * 1024 * 1024
+ size = min(maxsize, bytestoread)
+ data = usb_read(size)
+ if len(data) > 0:
+ rq.put(data)
+ bytestoread -= len(data)
+ show_progress(prefix="Read", pos=total - bytestoread, total=total, display=display)
+ rq.put(None)
+ worker.join(60)
+ self.cdc.xmlread = True
+ wd = self.wait_for_data()
+ info = self.xml.getlog(wd)
+ rsp = self.xml.getresponse(wd)
+ if "value" in rsp:
+ if rsp["value"] != "ACK":
+ if bytestoread!=0:
self.error(f"Error:")
for line in info:
self.error(line)
self.lasterror += bytes(line + "\n", "utf-8")
- return False
- else:
- if display:
- self.error(f"Error:{rsp[2]}")
- return False
- return True
+ return False
+ else:
+ if display:
+ self.error(f"Error:{rsp[2]}")
+ return False
+ return True
def cmd_read_buffer(self, physical_partition_number, start_sector, num_partition_sectors, display=True):
self.lasterror = b""