2929* Author(s): ladyada
3030"""
3131
32+ # pylint: disable=no-name-in-module
3233
3334import time
3435import gc
3536from micropython import const
37+ from adafruit_esp32spi import adafruit_esp32spi
3638
3739_the_interface = None # pylint: disable=invalid-name
3840def set_interface (iface ):
@@ -42,6 +44,7 @@ def set_interface(iface):
4244
4345SOCK_STREAM = const (1 )
4446AF_INET = const (2 )
47+ NO_SOCKET_AVAIL = const (255 )
4548
4649MAX_PACKET = const (4000 )
4750
@@ -59,14 +62,16 @@ def getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0):
5962class socket :
6063 """A simplified implementation of the Python 'socket' class, for connecting
6164 through an interface to a remote device"""
62- def __init__ (self , family = AF_INET , type = SOCK_STREAM , proto = 0 , fileno = None ):
65+ # pylint: disable=too-many-arguments
66+ def __init__ (self , family = AF_INET , type = SOCK_STREAM , proto = 0 , fileno = None , socknum = None ):
6367 if family != AF_INET :
6468 raise RuntimeError ("Only AF_INET family supported" )
6569 if type != SOCK_STREAM :
6670 raise RuntimeError ("Only SOCK_STREAM type supported" )
6771 self ._buffer = b''
68- self ._socknum = _the_interface .get_socket ()
72+ self ._socknum = socknum if socknum else _the_interface .get_socket ()
6973 self .settimeout (0 )
74+ # pylint: enable=too-many-arguments
7075
7176 def connect (self , address , conntype = None ):
7277 """Connect the socket to the 'address' (which can be 32bit packed IP or
@@ -90,7 +95,7 @@ def readline(self):
9095 stamp = time .monotonic ()
9196 while b'\r \n ' not in self ._buffer :
9297 # there's no line already in there, read some more
93- avail = min ( _the_interface . socket_available ( self ._socknum ), MAX_PACKET )
98+ avail = self .available ( )
9499 if avail :
95100 self ._buffer += _the_interface .socket_read (self ._socknum , avail )
96101 elif self ._timeout > 0 and time .monotonic () - stamp > self ._timeout :
@@ -106,7 +111,7 @@ def read(self, size=0):
106111 #print("Socket read", size)
107112 if size == 0 : # read as much as we can at the moment
108113 while True :
109- avail = min ( _the_interface . socket_available ( self ._socknum ), MAX_PACKET )
114+ avail = self .available ( )
110115 if avail :
111116 self ._buffer += _the_interface .socket_read (self ._socknum , avail )
112117 else :
@@ -122,7 +127,7 @@ def read(self, size=0):
122127 received = []
123128 while to_read > 0 :
124129 #print("Bytes to read:", to_read)
125- avail = min ( _the_interface . socket_available ( self ._socknum ), MAX_PACKET )
130+ avail = self .available ( )
126131 if avail :
127132 stamp = time .monotonic ()
128133 recv = _the_interface .socket_read (self ._socknum , min (to_read , avail ))
@@ -148,6 +153,38 @@ def settimeout(self, value):
148153 """Set the read timeout for sockets, if value is 0 it will block"""
149154 self ._timeout = value
150155
156+ def available (self ):
157+ """Returns how many bytes of data are available to be read (up to the MAX_PACKET length)"""
158+ if self .socknum != NO_SOCKET_AVAIL :
159+ return min (_the_interface .socket_available (self ._socknum ), MAX_PACKET )
160+ return 0
161+
162+ def connected (self ):
163+ """Whether or not we are connected to the socket"""
164+ if self .socknum == NO_SOCKET_AVAIL :
165+ return False
166+ elif self .available ():
167+ return True
168+ else :
169+ status = _the_interface .socket_status (self .socknum )
170+ result = status not in (adafruit_esp32spi .SOCKET_LISTEN ,
171+ adafruit_esp32spi .SOCKET_CLOSED ,
172+ adafruit_esp32spi .SOCKET_FIN_WAIT_1 ,
173+ adafruit_esp32spi .SOCKET_FIN_WAIT_2 ,
174+ adafruit_esp32spi .SOCKET_TIME_WAIT ,
175+ adafruit_esp32spi .SOCKET_SYN_SENT ,
176+ adafruit_esp32spi .SOCKET_SYN_RCVD ,
177+ adafruit_esp32spi .SOCKET_CLOSE_WAIT )
178+ if not result :
179+ self .close ()
180+ self ._socknum = NO_SOCKET_AVAIL
181+ return result
182+
183+ @property
184+ def socknum (self ):
185+ """The socket number"""
186+ return self ._socknum
187+
151188 def close (self ):
152189 """Close the socket, after reading whatever remains"""
153190 _the_interface .socket_close (self ._socknum )
0 commit comments