diff --git a/adafruit_esp32spi/adafruit_esp32spi.py b/adafruit_esp32spi/adafruit_esp32spi.py index 4c7b1b0..fa30cad 100755 --- a/adafruit_esp32spi/adafruit_esp32spi.py +++ b/adafruit_esp32spi/adafruit_esp32spi.py @@ -66,6 +66,7 @@ _START_SCAN_NETWORKS = const(0x36) _GET_FW_VERSION_CMD = const(0x37) _SEND_UDP_DATA_CMD = const(0x39) +_GET_REMOTE_DATA_CMD = const(0x3A) _GET_TIME = const(0x3B) _GET_IDX_BSSID_CMD = const(0x3C) _GET_IDX_CHAN_CMD = const(0x3D) @@ -316,7 +317,7 @@ def _send_command_get_response( *, reply_params=1, sent_param_len_16=False, - recv_param_len_16=False + recv_param_len_16=False, ): """Send a high level SPI command, wait and return the response""" self._send_command(cmd, params, param_len_16=sent_param_len_16) @@ -896,6 +897,16 @@ def get_time(self): ) raise RuntimeError("Must be connected to WiFi before obtaining NTP.") + def get_remote_data(self, socknum): + """Obtain remote IP + :param int socknum: the socket number. + """ + self._socknum_ll[0][0] = socknum + resp = self._send_command_get_response( + _GET_REMOTE_DATA_CMD, self._socknum_ll, reply_params=2 + ) + return {"ip_addr": resp[0], "port": resp[1]} + def set_certificate(self, client_certificate): """Sets client certificate. Must be called BEFORE a network connection is established. diff --git a/adafruit_esp32spi/adafruit_esp32spi_socket.py b/adafruit_esp32spi/adafruit_esp32spi_socket.py index 99d73f0..e491d50 100644 --- a/adafruit_esp32spi/adafruit_esp32spi_socket.py +++ b/adafruit_esp32spi/adafruit_esp32spi_socket.py @@ -52,7 +52,14 @@ class socket: # pylint: disable=too-many-arguments def __init__( - self, family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None, socknum=None + self, + family=AF_INET, + type=SOCK_STREAM, + proto=0, + fileno=None, + socknum=None, + remote_ip=None, + remote_port=None, ): if family != AF_INET: raise RuntimeError("Only AF_INET family supported") @@ -60,6 +67,8 @@ def __init__( raise RuntimeError("Only SOCK_STREAM type supported") self._buffer = b"" self._socknum = socknum if socknum else _the_interface.get_socket() + self._remote_ip = remote_ip + self._remote_port = remote_port self.settimeout(0) # pylint: enable=too-many-arguments @@ -193,6 +202,16 @@ def socknum(self): """The socket number""" return self._socknum + @property + def remote_ip(self): + """The remote ip""" + return self._remote_ip + + @property + def remote_port(self): + """The remote port""" + return self._remote_port + def close(self): """Close the socket, after reading whatever remains""" _the_interface.socket_close(self._socknum) diff --git a/adafruit_esp32spi/adafruit_esp32spi_wsgiserver.py b/adafruit_esp32spi/adafruit_esp32spi_wsgiserver.py index c869575..d87cb27 100644 --- a/adafruit_esp32spi/adafruit_esp32spi_wsgiserver.py +++ b/adafruit_esp32spi/adafruit_esp32spi_wsgiserver.py @@ -114,6 +114,14 @@ def finish_response(self, result): print("closing") self._client_sock.close() + def check_remote_ip(self): + """ + Functionality to control what IP is connecting to the server. + """ + socknum = self._client_sock.socknum + remote_ip = _the_interface.get_remote_data(socknum) + return _the_interface.pretty_ip(remote_ip) + def client_available(self): """ returns a client socket connection if available. @@ -178,6 +186,7 @@ def _get_environ(self, client): env["wsgi.multiprocess"] = False env["wsgi.run_once"] = False + env["REMOTE_ADDR"] = self._client_sock.remote_ip env["REQUEST_METHOD"] = method env["SCRIPT_NAME"] = "" env["SERVER_NAME"] = _the_interface.pretty_ip(_the_interface.ip_address)