From caa0f0006103d2e9f1e3bec7885d44f855c37e5a Mon Sep 17 00:00:00 2001 From: Tom Thompson Date: Tue, 21 Dec 2021 19:51:40 -0600 Subject: [PATCH 1/2] Datagram handling fixes. - Properly delimit datagrams. Only one datagram in recv() et al result. - Address info correct in recvfrom() - If a datagram not completely consumed on recv() et al, then remainder is discarded. - Removed udp_remaining(). It was an API not tied to a socket, so meaningless. - UDP_SOCK method for keeping track of datagram processing replaced, since it was not tied to a socket. --- .../adafruit_wiznet5k/adafruit_wiznet5k.py | 38 +++++++++---------- .../adafruit_wiznet5k_socket.py | 6 ++- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/libraries/adafruit_wiznet5k/adafruit_wiznet5k.py b/libraries/adafruit_wiznet5k/adafruit_wiznet5k.py index 08a1f01..13cf217 100644 --- a/libraries/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/libraries/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -122,8 +122,6 @@ W5100_MAX_SOCK_NUM = const(0x04) SOCKET_INVALID = const(255) -# UDP socket struct. -UDP_SOCK = {"bytes_remaining": 0, "remote_ip": 0, "remote_port": 0} # Source ports in use SRC_PORTS = [0] * W5200_W5500_MAX_SOCK_NUM @@ -182,6 +180,10 @@ def __init__( self.mac_address = mac self.src_port = 0 self._dns = 0 + # udp related + self.udp_datasize = [0] * self.max_sockets + self.udp_from_ip = [b"\x00\x00\x00\x00"] * self.max_sockets + self.udp_from_port = [0] * self.max_sockets # First, wait link status is on # to avoid the code during DHCP, socket listen, connect ... - assert self.link_status, "Ethernet cable disconnected!" @@ -491,11 +493,6 @@ def write(self, addr, callback, data): bus_device.write(bytes([data[i]])) # pylint: disable=no-member # Socket-Register API - def udp_remaining(self): - """Returns amount of bytes remaining in a udp socket.""" - if self._debug: - print("* UDP Bytes Remaining: ", UDP_SOCK["bytes_remaining"]) - return UDP_SOCK["bytes_remaining"] def socket_available(self, socket_num, sock_type=SNMR_TCP): """Returns the amount of bytes to be read from the socket. @@ -516,16 +513,16 @@ def socket_available(self, socket_num, sock_type=SNMR_TCP): if sock_type == SNMR_TCP: return res if res > 0: - if UDP_SOCK["bytes_remaining"]: - return UDP_SOCK["bytes_remaining"] + if self.udp_datasize[socket_num]: + return self.udp_datasize[socket_num] # parse the udp rx packet # read the first 8 header bytes ret, self._pbuff = self.socket_read(socket_num, 8) if ret > 0: - UDP_SOCK["remote_ip"] = self._pbuff[:4] - UDP_SOCK["remote_port"] = (self._pbuff[4] << 8) + self._pbuff[5] - UDP_SOCK["bytes_remaining"] = (self._pbuff[6] << 8) + self._pbuff[7] - ret = UDP_SOCK["bytes_remaining"] + self.udp_from_ip[socket_num] = self._pbuff[:4] + self.udp_from_port[socket_num] = (self._pbuff[4] << 8) + self._pbuff[5] + self.udp_datasize[socket_num] = (self._pbuff[6] << 8) + self._pbuff[7] + ret = self.udp_datasize[socket_num] return ret return 0 @@ -569,7 +566,7 @@ def socket_connect(self, socket_num, dest, port, conn_mode=SNMR_TCP): if self.socket_status(socket_num)[0] == SNSR_SOCK_CLOSED: raise RuntimeError("Failed to establish connection.") elif conn_mode == SNMR_UDP: - UDP_SOCK["bytes_remaining"] = 0 + self.udp_datasize[socket_num] = 0 return 1 def _send_socket_cmd(self, socket, cmd): @@ -760,14 +757,15 @@ def socket_read(self, socket_num, length): return ret, resp def read_udp(self, socket_num, length): - """Read UDP socket's remaining bytes.""" - if UDP_SOCK["bytes_remaining"] > 0: - if UDP_SOCK["bytes_remaining"] <= length: - ret, resp = self.socket_read(socket_num, UDP_SOCK["bytes_remaining"]) + """Read UDP socket's current message bytes.""" + if self.udp_datasize[socket_num] > 0: + if self.udp_datasize[socket_num] <= length: + ret, resp = self.socket_read(socket_num, self.udp_datasize[socket_num]) else: ret, resp = self.socket_read(socket_num, length) - if ret > 0: - UDP_SOCK["bytes_remaining"] -= ret + # just consume the rest, it is lost to the higher layers + self.socket_read(socket_num, self.udp_datasize[socket_num] - length) + self.udp_datasize[socket_num] = 0 return ret, resp return -1 diff --git a/libraries/adafruit_wiznet5k/adafruit_wiznet5k_socket.py b/libraries/adafruit_wiznet5k/adafruit_wiznet5k_socket.py index b55c881..c48f14c 100644 --- a/libraries/adafruit_wiznet5k/adafruit_wiznet5k_socket.py +++ b/libraries/adafruit_wiznet5k/adafruit_wiznet5k_socket.py @@ -286,6 +286,7 @@ def recv(self, bufsize=0, flags=0): # pylint: disable=too-many-branches ] elif self._sock_type == SOCK_DGRAM: self._buffer += _the_interface.read_udp(self.socknum, avail)[1] + break else: break gc.collect() @@ -307,6 +308,7 @@ def recv(self, bufsize=0, flags=0): # pylint: disable=too-many-branches )[1] elif self._sock_type == SOCK_DGRAM: recv = _the_interface.read_udp(self.socknum, min(to_read, avail))[1] + to_read = len(recv) # only get this dgram recv = bytes(recv) received.append(recv) to_read -= len(recv) @@ -354,8 +356,8 @@ def recvfrom(self, bufsize=0, flags=0): return ( self.recv(bufsize), ( - _the_interface.remote_ip(self.socknum), - _the_interface.remote_port(self.socknum), + _the_interface.pretty_ip(_the_interface.udp_from_ip[self.socknum]), + _the_interface.udp_from_port[self.socknum], ), ) From bf4456ed42312642b19156f9aa3506bb53a13a21 Mon Sep 17 00:00:00 2001 From: Tom Thompson Date: Tue, 28 Dec 2021 21:35:46 -0600 Subject: [PATCH 2/2] Use tuple for _dns not integer --- libraries/adafruit_wiznet5k/adafruit_wiznet5k.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/adafruit_wiznet5k/adafruit_wiznet5k.py b/libraries/adafruit_wiznet5k/adafruit_wiznet5k.py index 13cf217..13eba05 100644 --- a/libraries/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/libraries/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -179,7 +179,7 @@ def __init__( # Set MAC address self.mac_address = mac self.src_port = 0 - self._dns = 0 + self._dns = (0,0,0,0) # udp related self.udp_datasize = [0] * self.max_sockets self.udp_from_ip = [b"\x00\x00\x00\x00"] * self.max_sockets