Skip to content

Commit d13efef

Browse files
authored
Merge branch 'adafruit:main' into NTP_fix_infinite_loop
2 parents c7f9f9f + 1b8ff4e commit d13efef

6 files changed

+768
-93
lines changed

adafruit_wiznet5k/adafruit_wiznet5k.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ def __init__(
187187

188188
# attempt to initialize the module
189189
self._ch_base_msb = 0
190-
assert self._w5xxx_init() == 1, "Failed to initialize WIZnet module."
190+
if self._w5xxx_init() != 1:
191+
raise RuntimeError("Failed to initialize WIZnet module.")
191192
# Set MAC address
192193
self.mac_address = mac
193194
self.src_port = 0
@@ -214,7 +215,8 @@ def __init__(
214215
ret = self.set_dhcp(hostname, dhcp_timeout)
215216
if ret != 0:
216217
self._dhcp_client = None
217-
assert ret == 0, "Failed to configure DHCP Server!"
218+
if ret != 0:
219+
raise RuntimeError("Failed to configure DHCP Server!")
218220

219221
def set_dhcp(
220222
self, hostname: Optional[str] = None, response_timeout: float = 30
@@ -272,7 +274,8 @@ def get_host_by_name(self, hostname: str) -> bytes:
272274
ret = _dns_client.gethostbyname(hostname)
273275
if self._debug:
274276
print("* Resolved IP: ", ret)
275-
assert ret != -1, "Failed to resolve hostname!"
277+
if ret == -1:
278+
raise RuntimeError("Failed to resolve hostname!")
276279
return ret
277280

278281
@property
@@ -626,7 +629,8 @@ def socket_available(self, socket_num: int, sock_type: int = SNMR_TCP) -> int:
626629
socket_num, sock_type
627630
)
628631
)
629-
assert socket_num <= self.max_sockets, "Provided socket exceeds max_sockets."
632+
if socket_num > self.max_sockets:
633+
raise ValueError("Provided socket exceeds max_sockets.")
630634

631635
res = self._get_rx_rcv_size(socket_num)
632636

@@ -679,7 +683,8 @@ def socket_connect(
679683
:param int conn_mode: The connection mode. Use SNMR_TCP for TCP or SNMR_UDP for UDP,
680684
defaults to SNMR_TCP.
681685
"""
682-
assert self.link_status, "Ethernet cable disconnected!"
686+
if not self.link_status:
687+
raise ConnectionError("Ethernet cable disconnected!")
683688
if self._debug:
684689
print(
685690
"* w5k socket connect, protocol={}, port={}, ip={}".format(
@@ -689,7 +694,7 @@ def socket_connect(
689694
# initialize a socket and set the mode
690695
res = self.socket_open(socket_num, conn_mode=conn_mode)
691696
if res == 1:
692-
raise RuntimeError("Failed to initialize a connection with the socket.")
697+
raise ConnectionError("Failed to initialize a connection with the socket.")
693698

694699
# set socket destination IP and port
695700
self._write_sndipr(socket_num, dest)
@@ -703,7 +708,7 @@ def socket_connect(
703708
if self._debug:
704709
print("SN_SR:", self.socket_status(socket_num)[0])
705710
if self.socket_status(socket_num)[0] == SNSR_SOCK_CLOSED:
706-
raise RuntimeError("Failed to establish connection.")
711+
raise ConnectionError("Failed to establish connection.")
707712
elif conn_mode == SNMR_UDP:
708713
self.udp_datasize[socket_num] = 0
709714
return 1
@@ -747,7 +752,8 @@ def socket_listen(
747752
:param int conn_mode: Connection mode SNMR_TCP for TCP or SNMR_UDP for
748753
UDP, defaults to SNMR_TCP.
749754
"""
750-
assert self.link_status, "Ethernet cable disconnected!"
755+
if not self.link_status:
756+
raise ConnectionError("Ethernet cable disconnected!")
751757
if self._debug:
752758
print(
753759
"* Listening on port={}, ip={}".format(
@@ -807,7 +813,8 @@ def socket_open(self, socket_num: int, conn_mode: int = SNMR_TCP) -> int:
807813
UDP, defaults to SNMR_TCP.
808814
:return int: 1 if the socket was opened, 0 if not.
809815
"""
810-
assert self.link_status, "Ethernet cable disconnected!"
816+
if not self.link_status:
817+
raise ConnectionError("Ethernet cable disconnected!")
811818
if self._debug:
812819
print("*** Opening socket %d" % socket_num)
813820
status = self._read_snsr(socket_num)[0]
@@ -839,10 +846,8 @@ def socket_open(self, socket_num: int, conn_mode: int = SNMR_TCP) -> int:
839846
# open socket
840847
self._write_sncr(socket_num, CMD_SOCK_OPEN)
841848
self._read_sncr(socket_num)
842-
assert (
843-
self._read_snsr((socket_num))[0] == 0x13
844-
or self._read_snsr((socket_num))[0] == 0x22
845-
), "Could not open socket in TCP or UDP mode."
849+
if self._read_snsr((socket_num))[0] not in [0x13, 0x22]:
850+
raise RuntimeError("Could not open socket in TCP or UDP mode.")
846851
return 0
847852
return 1
848853

@@ -868,7 +873,7 @@ def socket_disconnect(self, socket_num: int) -> None:
868873
self._write_sncr(socket_num, CMD_SOCK_DISCON)
869874
self._read_sncr(socket_num)
870875

871-
def socket_read(
876+
def socket_read( # pylint: disable=too-many-branches
872877
self, socket_num: int, length: int
873878
) -> Tuple[int, Union[int, bytearray]]:
874879
"""
@@ -882,8 +887,11 @@ def socket_read(
882887
was unsuccessful then both items equal an error code, 0 for no data waiting and -1
883888
for no connection to the socket.
884889
"""
885-
assert self.link_status, "Ethernet cable disconnected!"
886-
assert socket_num <= self.max_sockets, "Provided socket exceeds max_sockets."
890+
891+
if not self.link_status:
892+
raise ConnectionError("Ethernet cable disconnected!")
893+
if socket_num > self.max_sockets:
894+
raise ValueError("Provided socket exceeds max_sockets.")
887895

888896
# Check if there is data available on the socket
889897
ret = self._get_rx_rcv_size(socket_num)
@@ -976,7 +984,8 @@ def socket_write(
976984
977985
:return int: The number of bytes written to the buffer.
978986
"""
979-
assert self.link_status, "Ethernet cable disconnected!"
987+
if not self.link_status:
988+
raise ConnectionError("Ethernet cable disconnected!")
980989
assert socket_num <= self.max_sockets, "Provided socket exceeds max_sockets."
981990
status = 0
982991
ret = 0

adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py

Lines changed: 82 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
DHCP_HLENETHERNET = const(0x06)
6666
DHCP_HOPS = const(0x00)
6767

68-
MAGIC_COOKIE = const(0x63825363)
68+
MAGIC_COOKIE = b"c\x82Sc" # Four bytes 99.130.83.99
6969
MAX_DHCP_OPT = const(0x10)
7070

7171
# Default DHCP Server port
@@ -179,7 +179,7 @@ def send_dhcp_message(
179179
# Transaction ID (xid)
180180
self._initial_xid = htonl(self._transaction_id)
181181
self._initial_xid = self._initial_xid.to_bytes(4, "big")
182-
_BUFF[4:7] = self._initial_xid
182+
_BUFF[4:8] = self._initial_xid
183183

184184
# seconds elapsed
185185
_BUFF[8] = (int(time_elapsed) & 0xFF00) >> 8
@@ -195,18 +195,15 @@ def send_dhcp_message(
195195
# as they're already set to 0.0.0.0
196196
# Except when renewing, then fill in ciaddr
197197
if renew:
198-
_BUFF[12:15] = bytes(self.local_ip)
198+
_BUFF[12:16] = bytes(self.local_ip)
199199

200200
# chaddr
201201
_BUFF[28:34] = self._mac_address
202202

203203
# NOTE: 192 octets of 0's, BOOTP legacy
204204

205205
# Magic Cookie
206-
_BUFF[236] = (MAGIC_COOKIE >> 24) & 0xFF
207-
_BUFF[237] = (MAGIC_COOKIE >> 16) & 0xFF
208-
_BUFF[238] = (MAGIC_COOKIE >> 8) & 0xFF
209-
_BUFF[239] = MAGIC_COOKIE & 0xFF
206+
_BUFF[236:240] = MAGIC_COOKIE
210207

211208
# Option - DHCP Message Type
212209
_BUFF[240] = 53
@@ -262,10 +259,10 @@ def send_dhcp_message(
262259
# pylint: disable=too-many-branches, too-many-statements
263260
def parse_dhcp_response(
264261
self,
265-
) -> Union[Tuple[int, bytes], Tuple[int, int]]:
262+
) -> Tuple[int, bytearray]:
266263
"""Parse DHCP response from DHCP server.
267264
268-
:return Union[Tuple[int, bytes], Tuple[int, int]]: DHCP packet type.
265+
:return Tuple[int, bytearray]: DHCP packet type and ID.
269266
"""
270267
# store packet in buffer
271268
_BUFF = self._sock.recv()
@@ -274,22 +271,23 @@ def parse_dhcp_response(
274271

275272
# -- Parse Packet, FIXED -- #
276273
# Validate OP
277-
assert (
278-
_BUFF[0] == DHCP_BOOT_REPLY
279-
), "Malformed Packet - \
274+
if _BUFF[0] != DHCP_BOOT_REPLY:
275+
raise RuntimeError(
276+
"Malformed Packet - \
280277
DHCP message OP is not expected BOOT Reply."
278+
)
281279

282280
xid = _BUFF[4:8]
283-
if bytes(xid) < self._initial_xid:
284-
print("f")
285-
return 0, 0
281+
if bytes(xid) != self._initial_xid:
282+
raise ValueError("DHCP response ID mismatch.")
286283

287284
self.local_ip = tuple(_BUFF[16:20])
288-
if _BUFF[28:34] == 0:
289-
return 0, 0
285+
# Check that there is a server ID.
286+
if _BUFF[28:34] == b"\x00\x00\x00\x00\x00\x00":
287+
raise ValueError("No DHCP server ID in the response.")
290288

291-
if int.from_bytes(_BUFF[235:240], "big") != MAGIC_COOKIE:
292-
return 0, 0
289+
if _BUFF[236:240] != MAGIC_COOKIE:
290+
raise ValueError("No DHCP Magic Cookie in the response.")
293291

294292
# -- Parse Packet, VARIABLE -- #
295293
ptr = 240
@@ -322,8 +320,8 @@ def parse_dhcp_response(
322320
ptr += 1
323321
opt_len = _BUFF[ptr]
324322
ptr += 1
325-
self.gateway_ip = tuple(_BUFF[ptr : ptr + opt_len])
326-
ptr += opt_len
323+
self.gateway_ip = tuple(_BUFF[ptr : ptr + 4])
324+
ptr += opt_len # still increment even though we only read 1 addr.
327325
elif _BUFF[ptr] == DNS_SERVERS:
328326
ptr += 1
329327
opt_len = _BUFF[ptr]
@@ -426,65 +424,79 @@ def _dhcp_state_machine(self) -> None:
426424
if self._sock.available():
427425
if self._debug:
428426
print("* DHCP: Parsing OFFER")
429-
msg_type, xid = self.parse_dhcp_response()
430-
if msg_type == DHCP_OFFER:
431-
# Check if transaction ID matches, otherwise it may be an offer
432-
# for another device
433-
if htonl(self._transaction_id) == int.from_bytes(xid, "big"):
434-
if self._debug:
435-
print(
436-
"* DHCP: Send request to {}".format(self.dhcp_server_ip)
427+
try:
428+
msg_type, xid = self.parse_dhcp_response()
429+
except ValueError as error:
430+
if self._debug:
431+
print(error)
432+
else:
433+
if msg_type == DHCP_OFFER:
434+
# Check if transaction ID matches, otherwise it may be an offer
435+
# for another device
436+
if htonl(self._transaction_id) == int.from_bytes(xid, "big"):
437+
if self._debug:
438+
print(
439+
"* DHCP: Send request to {}".format(
440+
self.dhcp_server_ip
441+
)
442+
)
443+
self._transaction_id = (
444+
self._transaction_id + 1
445+
) & 0x7FFFFFFF
446+
self.send_dhcp_message(
447+
DHCP_REQUEST, (time.monotonic() - self._start_time)
437448
)
438-
self._transaction_id = (self._transaction_id + 1) & 0x7FFFFFFF
439-
self.send_dhcp_message(
440-
DHCP_REQUEST, (time.monotonic() - self._start_time)
441-
)
442-
self._dhcp_state = STATE_DHCP_REQUEST
449+
self._dhcp_state = STATE_DHCP_REQUEST
450+
else:
451+
if self._debug:
452+
print("* DHCP: Received OFFER with non-matching xid")
443453
else:
444454
if self._debug:
445-
print("* DHCP: Received OFFER with non-matching xid")
446-
else:
447-
if self._debug:
448-
print("* DHCP: Received DHCP Message is not OFFER")
455+
print("* DHCP: Received DHCP Message is not OFFER")
449456

450457
elif self._dhcp_state == STATE_DHCP_REQUEST:
451458
if self._sock.available():
452459
if self._debug:
453460
print("* DHCP: Parsing ACK")
454-
msg_type, xid = self.parse_dhcp_response()
455-
# Check if transaction ID matches, otherwise it may be
456-
# for another device
457-
if htonl(self._transaction_id) == int.from_bytes(xid, "big"):
458-
if msg_type == DHCP_ACK:
459-
if self._debug:
460-
print("* DHCP: Successful lease")
461-
self._sock.close()
462-
self._sock = None
463-
self._dhcp_state = STATE_DHCP_LEASED
464-
self._last_lease_time = self._start_time
465-
if self._lease_time == 0:
466-
self._lease_time = DEFAULT_LEASE_TIME
467-
if self._t1 == 0:
468-
# T1 is 50% of _lease_time
469-
self._t1 = self._lease_time >> 1
470-
if self._t2 == 0:
471-
# T2 is 87.5% of _lease_time
472-
self._t2 = self._lease_time - (self._lease_time >> 3)
473-
self._renew_in_sec = self._t1
474-
self._rebind_in_sec = self._t2
475-
self._eth.ifconfig = (
476-
self.local_ip,
477-
self.subnet_mask,
478-
self.gateway_ip,
479-
self.dns_server_ip,
480-
)
481-
gc.collect()
461+
try:
462+
msg_type, xid = self.parse_dhcp_response()
463+
except ValueError as error:
464+
if self._debug:
465+
print(error)
466+
else:
467+
# Check if transaction ID matches, otherwise it may be
468+
# for another device
469+
if htonl(self._transaction_id) == int.from_bytes(xid, "big"):
470+
if msg_type == DHCP_ACK:
471+
if self._debug:
472+
print("* DHCP: Successful lease")
473+
self._sock.close()
474+
self._sock = None
475+
self._dhcp_state = STATE_DHCP_LEASED
476+
self._last_lease_time = self._start_time
477+
if self._lease_time == 0:
478+
self._lease_time = DEFAULT_LEASE_TIME
479+
if self._t1 == 0:
480+
# T1 is 50% of _lease_time
481+
self._t1 = self._lease_time >> 1
482+
if self._t2 == 0:
483+
# T2 is 87.5% of _lease_time
484+
self._t2 = self._lease_time - (self._lease_time >> 3)
485+
self._renew_in_sec = self._t1
486+
self._rebind_in_sec = self._t2
487+
self._eth.ifconfig = (
488+
self.local_ip,
489+
self.subnet_mask,
490+
self.gateway_ip,
491+
self.dns_server_ip,
492+
)
493+
gc.collect()
494+
else:
495+
if self._debug:
496+
print("* DHCP: Received DHCP Message is not ACK")
482497
else:
483498
if self._debug:
484-
print("* DHCP: Received DHCP Message is not ACK")
485-
else:
486-
if self._debug:
487-
print("* DHCP: Received non-matching xid")
499+
print("* DHCP: Received non-matching xid")
488500

489501
elif self._dhcp_state == STATE_DHCP_WAIT:
490502
if time.monotonic() > (self._start_time + DHCP_WAIT_TIME):

0 commit comments

Comments
 (0)