diff --git a/adafruit_esp32spi/adafruit_esp32spi.py b/adafruit_esp32spi/adafruit_esp32spi.py index 347ea3b..7861c15 100755 --- a/adafruit_esp32spi/adafruit_esp32spi.py +++ b/adafruit_esp32spi/adafruit_esp32spi.py @@ -83,6 +83,7 @@ _GET_HOST_BY_NAME_CMD = const(0x35) _START_SCAN_NETWORKS = const(0x36) _GET_FW_VERSION_CMD = const(0x37) +_SEND_UDP_DATA_CMD = const(0x39) _GET_TIME = const(0x3B) _GET_IDX_BSSID_CMD = const(0x3C) _GET_IDX_CHAN_CMD = const(0x3D) @@ -90,6 +91,7 @@ _SEND_DATA_TCP_CMD = const(0x44) _GET_DATABUF_TCP_CMD = const(0x45) +_INSERT_DATABUF_TCP_CMD = const(0x46) _SET_ENT_IDENT_CMD = const(0x4A) _SET_ENT_UNAME_CMD = const(0x4B) _SET_ENT_PASSWD_CMD = const(0x4C) @@ -689,15 +691,19 @@ def socket_connected(self, socket_num): """Test if a socket is connected to the destination, returns boolean true/false""" return self.socket_status(socket_num) == SOCKET_ESTABLISHED - def socket_write(self, socket_num, buffer): + def socket_write(self, socket_num, buffer, conn_mode=TCP_MODE): """Write the bytearray buffer to a socket""" if self._debug: print("Writing:", buffer) self._socknum_ll[0][0] = socket_num sent = 0 - for chunk in range((len(buffer) // 64) + 1): + total_chunks = (len(buffer) // 64) + 1 + send_command = _SEND_DATA_TCP_CMD + if conn_mode == self.UDP_MODE: # UDP requires a different command to write + send_command = _INSERT_DATABUF_TCP_CMD + for chunk in range(total_chunks): resp = self._send_command_get_response( - _SEND_DATA_TCP_CMD, + send_command, ( self._socknum_ll[0], memoryview(buffer)[(chunk * 64) : ((chunk + 1) * 64)], @@ -706,6 +712,18 @@ def socket_write(self, socket_num, buffer): ) sent += resp[0][0] + if conn_mode == self.UDP_MODE: + # UDP verifies chunks on write, not bytes + if sent != total_chunks: + raise RuntimeError( + "Failed to write %d chunks (sent %d)" % (total_chunks, sent) + ) + # UDP needs to finalize with this command, does the actual sending + resp = self._send_command_get_response(_SEND_UDP_DATA_CMD, self._socknum_ll) + if resp[0][0] != 1: + raise RuntimeError("Failed to send UDP data") + return + if sent != len(buffer): raise RuntimeError( "Failed to send %d bytes (sent %d)" % (len(buffer), sent) @@ -749,6 +767,12 @@ def socket_connect(self, socket_num, dest, port, conn_mode=TCP_MODE): print("*** Socket connect mode", conn_mode) self.socket_open(socket_num, dest, port, conn_mode=conn_mode) + if conn_mode == self.UDP_MODE: + # UDP doesn't actually establish a connection + # but the socket for writing is created via start_server + self.start_server(port, socket_num, conn_mode) + return True + times = time.monotonic() while (time.monotonic() - times) < 3: # wait 3 seconds if self.socket_connected(socket_num):