diff --git a/adafruit_esp32spi/adafruit_esp32spi.py b/adafruit_esp32spi/adafruit_esp32spi.py old mode 100644 new mode 100755 index e5f109a..e8b8224 --- a/adafruit_esp32spi/adafruit_esp32spi.py +++ b/adafruit_esp32spi/adafruit_esp32spi.py @@ -251,7 +251,10 @@ def _read_bytes(self, spi, buffer, start=0, end=None): def _wait_spi_char(self, spi, desired): """Read a byte with a time-out, and if we get it, check that its what we expect""" times = time.monotonic() - while (time.monotonic() - times) < 0.1: + # while (time.monotonic() - times) < 0.1: + + # local edit 20190717 + while (time.monotonic() - times) < 1: r = self._read_byte(spi) if r == _ERR_CMD: raise RuntimeError("Error response to command") @@ -577,8 +580,11 @@ def socket_available(self, socket_num): self._socknum_ll[0][0] = socket_num resp = self._send_command_get_response(_AVAIL_DATA_TCP_CMD, self._socknum_ll) reply = struct.unpack(' 2: reason = line[2].rstrip() + + print("status: ", status) + print("reason: ", reason) + while True: line = sock.readline() if not line or line == b"\r\n": + print("we're done with request") break #print("**line: ", line) diff --git a/adafruit_esp32spi/adafruit_esp32spi_socket.py b/adafruit_esp32spi/adafruit_esp32spi_socket.py old mode 100644 new mode 100755 index ccf5b4f..ee3f62d --- a/adafruit_esp32spi/adafruit_esp32spi_socket.py +++ b/adafruit_esp32spi/adafruit_esp32spi_socket.py @@ -67,11 +67,13 @@ def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None): self._buffer = b'' self._socknum = _the_interface.get_socket() self.settimeout(0) + print("socket created") def connect(self, address, conntype=None): """Connect the socket to the 'address' (which can be 32bit packed IP or a hostname string). 'conntype' is an extra that may indicate SSL or not, depending on the underlying interface""" + print("connecting...") host, port = address if conntype is None: conntype = _the_interface.TCP_MODE @@ -86,16 +88,27 @@ def write(self, data): # pylint: disable=no-self-use def readline(self): """Attempt to return as many bytes as we can up to but not including '\r\n'""" - #print("Socket readline") + # print("Socket readline") stamp = time.monotonic() + # print("buffer: ", self._buffer) while b'\r\n' not in self._buffer: # there's no line already in there, read some more - avail = min(_the_interface.socket_available(self._socknum), MAX_PACKET) - if avail: - self._buffer += _the_interface.socket_read(self._socknum, avail) - elif self._timeout > 0 and time.monotonic() - stamp > self._timeout: - self.close() # Make sure to close socket so that we don't exhaust sockets. - raise RuntimeError("Didn't receive full response, failing out") + try: + # BUG:20190718 memory allocation failed here sometimes due to + # internal buffering (see function description) + avail = min(_the_interface.socket_available(self._socknum), MAX_PACKET) + if avail != 0: + print("avail: ", avail) + if avail: + self._buffer += _the_interface.socket_read(self._socknum, avail) + # 20190718 + gc.collect() + elif self._timeout > 0 and time.monotonic() - stamp > self._timeout: + self.close() # Make sure to close socket so that we don't exhaust sockets. + raise RuntimeError("Didn't receive full response, failing out") + except MemoryError as e: + print("MemoryError while reading from socket (readline)") + break firstline, self._buffer = self._buffer.split(b'\r\n', 1) gc.collect() return firstline @@ -103,14 +116,25 @@ def readline(self): def read(self, size=0): """Read up to 'size' bytes from the socket, this may be buffered internally! If 'size' isnt specified, return everything in the buffer.""" - #print("Socket read", size) + # print("Socket read: ", size) if size == 0: # read as much as we can at the moment while True: - avail = min(_the_interface.socket_available(self._socknum), MAX_PACKET) - if avail: - self._buffer += _the_interface.socket_read(self._socknum, avail) - else: + try: + avail = min(_the_interface.socket_available(self._socknum), MAX_PACKET) + if avail: + + # BUG:20190718 memory allocation failed here sometimes due to + # internal buffering (see function description) + self._buffer += _the_interface.socket_read(self._socknum, avail) + + # 20190718 + gc.collect() + else: + break + except MemoryError as e: + print("MemoryError while reading from socket (read)") break + gc.collect() ret = self._buffer self._buffer = b'' @@ -119,21 +143,49 @@ def read(self, size=0): stamp = time.monotonic() to_read = size - len(self._buffer) + + # print("size: ", size) + # print("buffer length: ", len(self._buffer)) + + # if this is too short, could end too early and size of file written will not match + # the content-length from server... + # + # read_timeout = 1 + # read_timeout = self._timeout + read_timeout = 15 + received = [] while to_read > 0: - #print("Bytes to read:", to_read) - avail = min(_the_interface.socket_available(self._socknum), MAX_PACKET) + # print("Bytes to read:", to_read) + available_bytes = _the_interface.socket_available(self._socknum) + + # if available_bytes > 0: + # print("available bytes on sock: ", available_bytes) + + # if available_bytes > MAX_PACKET: + # print("Warning: available bytes is > MAX_PACKET: ", MAX_PACKET) + + avail = min(available_bytes, MAX_PACKET) + if avail: + # print("avail: ", avail) stamp = time.monotonic() recv = _the_interface.socket_read(self._socknum, min(to_read, avail)) received.append(recv) to_read -= len(recv) gc.collect() - if self._timeout > 0 and time.monotonic() - stamp > self._timeout: + # else: + # print("nothing left to read! waiting to timeout... ", (time.monotonic() - stamp)) + #if self._timeout > 0 and time.monotonic() - stamp > self._timeout: + if read_timeout > 0 and time.monotonic() - stamp > read_timeout: + #print("socket.read timeout ", self._timeout) + print("socket.read timeout ", read_timeout) break #print(received) self._buffer += b''.join(received) + # print("len(self._buffer) ", len(self._buffer)) + ret = None if len(self._buffer) == size: ret = self._buffer @@ -141,11 +193,16 @@ def read(self, size=0): else: ret = self._buffer[:size] self._buffer = self._buffer[size:] + + # print("size: ", size) + # print("len(ret) ", len(ret)) + gc.collect() return ret def settimeout(self, value): """Set the read timeout for sockets, if value is 0 it will block""" + print("setting timeout: ", value) self._timeout = value def close(self):