29
29
* Author(s): ladyada
30
30
"""
31
31
32
+ # pylint: disable=no-name-in-module
32
33
33
34
import time
34
35
import gc
35
36
from micropython import const
37
+ from adafruit_esp32spi import adafruit_esp32spi
36
38
37
39
_the_interface = None # pylint: disable=invalid-name
38
40
def set_interface (iface ):
@@ -42,6 +44,7 @@ def set_interface(iface):
42
44
43
45
SOCK_STREAM = const (1 )
44
46
AF_INET = const (2 )
47
+ NO_SOCKET_AVAIL = const (255 )
45
48
46
49
MAX_PACKET = const (4000 )
47
50
@@ -59,14 +62,16 @@ def getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0):
59
62
class socket :
60
63
"""A simplified implementation of the Python 'socket' class, for connecting
61
64
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 ):
63
67
if family != AF_INET :
64
68
raise RuntimeError ("Only AF_INET family supported" )
65
69
if type != SOCK_STREAM :
66
70
raise RuntimeError ("Only SOCK_STREAM type supported" )
67
71
self ._buffer = b''
68
- self ._socknum = _the_interface .get_socket ()
72
+ self ._socknum = socknum if socknum else _the_interface .get_socket ()
69
73
self .settimeout (0 )
74
+ # pylint: enable=too-many-arguments
70
75
71
76
def connect (self , address , conntype = None ):
72
77
"""Connect the socket to the 'address' (which can be 32bit packed IP or
@@ -90,7 +95,7 @@ def readline(self):
90
95
stamp = time .monotonic ()
91
96
while b'\r \n ' not in self ._buffer :
92
97
# 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 ( )
94
99
if avail :
95
100
self ._buffer += _the_interface .socket_read (self ._socknum , avail )
96
101
elif self ._timeout > 0 and time .monotonic () - stamp > self ._timeout :
@@ -106,7 +111,7 @@ def read(self, size=0):
106
111
#print("Socket read", size)
107
112
if size == 0 : # read as much as we can at the moment
108
113
while True :
109
- avail = min ( _the_interface . socket_available ( self ._socknum ), MAX_PACKET )
114
+ avail = self .available ( )
110
115
if avail :
111
116
self ._buffer += _the_interface .socket_read (self ._socknum , avail )
112
117
else :
@@ -122,7 +127,7 @@ def read(self, size=0):
122
127
received = []
123
128
while to_read > 0 :
124
129
#print("Bytes to read:", to_read)
125
- avail = min ( _the_interface . socket_available ( self ._socknum ), MAX_PACKET )
130
+ avail = self .available ( )
126
131
if avail :
127
132
stamp = time .monotonic ()
128
133
recv = _the_interface .socket_read (self ._socknum , min (to_read , avail ))
@@ -148,6 +153,38 @@ def settimeout(self, value):
148
153
"""Set the read timeout for sockets, if value is 0 it will block"""
149
154
self ._timeout = value
150
155
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
+
151
188
def close (self ):
152
189
"""Close the socket, after reading whatever remains"""
153
190
_the_interface .socket_close (self ._socknum )
0 commit comments