9
9
10
10
A socket compatible interface with the Wiznet5k module.
11
11
12
- * Author(s): ladyada, Brent Rubell, Patrick Van Oosterwijck
12
+ * Author(s): ladyada, Brent Rubell, Patrick Van Oosterwijck, Adam Cummick
13
13
14
14
"""
15
15
import gc
@@ -108,11 +108,31 @@ def __init__(
108
108
if self ._socknum == SOCKET_INVALID :
109
109
raise RuntimeError ("Failed to allocate socket." )
110
110
111
+ def __enter__ (self ):
112
+ return self
113
+
114
+ def __exit__ (self , exc_type , exc_val , exc_tb ):
115
+ self .disconnect ()
116
+ stamp = time .monotonic ()
117
+ while self .status == adafruit_wiznet5k .SNSR_SOCK_FIN_WAIT :
118
+ if time .monotonic () - stamp > 1000 :
119
+ raise RuntimeError ("Failed to disconnect socket" )
120
+ self .close ()
121
+ stamp = time .monotonic ()
122
+ while self .status != adafruit_wiznet5k .SNSR_SOCK_CLOSED :
123
+ if time .monotonic () - stamp > 1000 :
124
+ raise RuntimeError ("Failed to close socket" )
125
+
111
126
@property
112
127
def socknum (self ):
113
128
"""Returns the socket object's socket number."""
114
129
return self ._socknum
115
130
131
+ @property
132
+ def status (self ):
133
+ """Returns the status of the socket"""
134
+ return _the_interface .socket_status (self .socknum )[0 ]
135
+
116
136
@property
117
137
def connected (self ):
118
138
"""Returns whether or not we are connected to the socket."""
@@ -147,10 +167,16 @@ def inet_aton(self, ip_string):
147
167
return self ._buffer
148
168
149
169
def bind (self , address ):
150
- """Bind the socket to the listen port, we ignore the host.
151
- :param tuple address: local socket as a (host, port) tuple, host is ignored.
170
+ """Bind the socket to the listen port, if host is specified the interface
171
+ will be reconfigured to that IP.
172
+ :param tuple address: local socket as a (host, port) tuple.
152
173
"""
153
- _ , self ._listen_port = address
174
+ if address [0 ] is not None :
175
+ ip_address = _the_interface .unpretty_ip (address [0 ])
176
+ current_ip , subnet_mask , gw_addr , dns = _the_interface .ifconfig
177
+ if ip_address != current_ip :
178
+ _the_interface .ifconfig = (ip_address , subnet_mask , gw_addr , dns )
179
+ self ._listen_port = address [1 ]
154
180
155
181
def listen (self , backlog = None ):
156
182
"""Listen on the port specified by bind.
@@ -160,6 +186,35 @@ def listen(self, backlog=None):
160
186
_the_interface .socket_listen (self .socknum , self ._listen_port )
161
187
self ._buffer = b""
162
188
189
+ def accept (self ):
190
+ """Accept a connection. The socket must be bound to an address and listening for
191
+ connections. The return value is a pair (conn, address) where conn is a new
192
+ socket object usable to send and receive data on the connection, and address is
193
+ the address bound to the socket on the other end of the connection.
194
+ """
195
+ stamp = time .monotonic ()
196
+ while self .status not in (
197
+ adafruit_wiznet5k .SNSR_SOCK_SYNRECV ,
198
+ adafruit_wiznet5k .SNSR_SOCK_ESTABLISHED ,
199
+ ):
200
+ if self ._timeout > 0 and time .monotonic () - stamp > self ._timeout :
201
+ return None
202
+ if self .status == adafruit_wiznet5k .SNSR_SOCK_CLOSED :
203
+ self .close ()
204
+ self .listen ()
205
+
206
+ new_listen_socknum , addr = _the_interface .socket_accept (self .socknum )
207
+ current_socknum = self .socknum
208
+ # Create a new socket object and swap socket nums so we can continue listening
209
+ client_sock = socket ()
210
+ client_sock ._socknum = current_socknum # pylint: disable=protected-access
211
+ self ._socknum = new_listen_socknum # pylint: disable=protected-access
212
+ self .bind ((None , self ._listen_port ))
213
+ self .listen ()
214
+ while self .status != adafruit_wiznet5k .SNSR_SOCK_LISTEN :
215
+ raise RuntimeError ("Failed to open new listening socket" )
216
+ return client_sock , addr
217
+
163
218
def connect (self , address , conntype = None ):
164
219
"""Connect to a remote socket at address. (The format of address depends
165
220
on the address family — see above.)
0 commit comments