From eae6025d30f4fdb93f901e9b8fde7fdde7ede7ea Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 3 Mar 2020 11:46:25 -0500 Subject: [PATCH 01/41] add some updates for Adafruit_Requests --- adafruit_wiznet5k/adafruit_wiznet5k.py | 3 +++ adafruit_wiznet5k/adafruit_wiznet5k_socket.py | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index 89b0606..0096056 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -149,6 +149,9 @@ class WIZNET5K: """ + TCP_MODE = const(0x21) + UDP_MODE = const(0x02) + # pylint: disable=too-many-arguments, too-many-public-methods def __init__(self, spi_bus, cs, reset=None, is_dhcp=True, mac=DEFAULT_MAC, debug=False): diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py index 7637c05..e7e580d 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py @@ -68,7 +68,7 @@ def getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0): """ if not isinstance(port, int): raise RuntimeError("Port must be an integer") - return [AF_INET, socktype, proto, '', (gethostbyname(host), port)] + return [(AF_INET, socktype, proto, '', (gethostbyname(host), port))] def gethostbyname(hostname): """Translate a host name to IPv4 address format. The IPv4 address @@ -219,10 +219,12 @@ def readline(self): """Attempt to return as many bytes as we can up to but not including \n""" stamp = time.monotonic() - while b'\n' not in self._buffer: + while b'\r\n' not in self._buffer: if self._sock_type == SOCK_STREAM: avail = self.available() - self._buffer += _the_interface.read(self.socknum, avail)[1] + if avail: + reading = _the_interface.socket_read(self.socknum, avail) + self._buffer += reading[1] elif self._sock_type == SOCK_DGRAM: avail = _the_interface.udp_remaining() self._buffer += _the_interface.read_udp(self.socknum, avail)[1] From af4a485a09f360203f30c3a974aff52ca3fffa96 Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 3 Mar 2020 12:01:51 -0500 Subject: [PATCH 02/41] return buffer and firstline properly --- adafruit_wiznet5k/adafruit_wiznet5k_socket.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py index e7e580d..8978650 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py @@ -185,6 +185,7 @@ def recv(self, bufsize=0): #pylint: disable=too-many-branches return ret stamp = time.monotonic() + # TODO: this needs to be repaired for requests to_read = bufsize - len(self._buffer) received = [] while to_read > 0: @@ -222,6 +223,7 @@ def readline(self): while b'\r\n' not in self._buffer: if self._sock_type == SOCK_STREAM: avail = self.available() + print("Avail: ", avail) if avail: reading = _the_interface.socket_read(self.socknum, avail) self._buffer += reading[1] @@ -231,11 +233,11 @@ def readline(self): elif self._timeout > 0 and time.monotonic() - stamp > self._timeout: self.close() raise RuntimeError("Didn't receive response, failing out...") - firstline = self._buffer.split(b'\n', 1) + #firstline = self._buffer.split(b'\n', 1) + firstline, self._buffer = self._buffer.split(b'\r\n', 1) gc.collect() - # clear tmp data buffer - self._buffer = b'' - return firstline[0] + #return firstline[0] + return firstline def disconnect(self): """Disconnects a TCP socket.""" From 3b0a686daf1dd2102d3d6ca19d8545013113d49a Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 3 Mar 2020 14:34:30 -0500 Subject: [PATCH 03/41] only add to buffer if bytes are avail on the socket --- adafruit_wiznet5k/adafruit_wiznet5k_socket.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py index 8978650..6371bfb 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py @@ -223,13 +223,13 @@ def readline(self): while b'\r\n' not in self._buffer: if self._sock_type == SOCK_STREAM: avail = self.available() - print("Avail: ", avail) if avail: reading = _the_interface.socket_read(self.socknum, avail) self._buffer += reading[1] elif self._sock_type == SOCK_DGRAM: avail = _the_interface.udp_remaining() - self._buffer += _the_interface.read_udp(self.socknum, avail)[1] + if avail: + self._buffer += _the_interface.read_udp(self.socknum, avail)[1] elif self._timeout > 0 and time.monotonic() - stamp > self._timeout: self.close() raise RuntimeError("Didn't receive response, failing out...") From 2da46167fb2f5b38dfe97c12d025482acf5904ff Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 3 Mar 2020 17:12:35 -0500 Subject: [PATCH 04/41] fix incorrect read within dns, add correct join in socket --- adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py | 2 +- adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 2 +- adafruit_wiznet5k/adafruit_wiznet5k_socket.py | 20 ++++++++----------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py index a4dafd4..18b5a5d 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py @@ -228,7 +228,7 @@ def parse_dhcp_response(self, response_timeout): return (255, 0) time.sleep(0.05) # store packet in buffer - _BUFF = self._sock.recv(packet_sz)[0] + _BUFF = self._sock.recv() # Check OP, if valid, let's parse the packet out! assert _BUFF[0] == DHCP_BOOT_REPLY, "Malformed Packet - \ diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index 347aaca..066aeca 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -114,7 +114,7 @@ def _parse_dns_response(self): return -1 time.sleep(0.05) # store packet in buffer - self._pkt_buf = self._sock.recv(packet_sz)[0] + self._pkt_buf = self._sock.recv() # Validate request identifier if not int.from_bytes(self._pkt_buf[0:2], 'l') == self._request_id: diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py index 6371bfb..8937f28 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py @@ -158,12 +158,12 @@ def send(self, data): _the_interface.socket_write(self.socknum, data) gc.collect() + def recv(self, bufsize=0): #pylint: disable=too-many-branches """Reads some bytes from the connected remote address. :param int bufsize: Maximum number of bytes to receive. - """ - assert _the_interface.link_status, "Ethernet cable disconnected!" + # print("Socket read", bufsize) if bufsize == 0: # read everything on the socket while True: @@ -173,9 +173,9 @@ def recv(self, bufsize=0): #pylint: disable=too-many-branches avail = _the_interface.udp_remaining() if avail: if self._sock_type == SOCK_STREAM: - self._buffer += _the_interface.socket_read(self.socknum, avail) + self._buffer += _the_interface.socket_read(self.socknum, avail)[1] elif self._sock_type == SOCK_DGRAM: - self._buffer += _the_interface.read_udp(self.socknum, avail) + self._buffer += _the_interface.read_udp(self.socknum, avail)[1] else: break gc.collect() @@ -185,7 +185,6 @@ def recv(self, bufsize=0): #pylint: disable=too-many-branches return ret stamp = time.monotonic() - # TODO: this needs to be repaired for requests to_read = bufsize - len(self._buffer) received = [] while to_read > 0: @@ -204,7 +203,7 @@ def recv(self, bufsize=0): #pylint: disable=too-many-branches gc.collect() if self._timeout > 0 and time.monotonic() - stamp > self._timeout: break - self._buffer = received + self._buffer += b''.join(received) ret = None if len(self._buffer) == bufsize: @@ -218,25 +217,22 @@ def recv(self, bufsize=0): #pylint: disable=too-many-branches def readline(self): """Attempt to return as many bytes as we can up to - but not including \n""" + but not including '\r\n'""" stamp = time.monotonic() while b'\r\n' not in self._buffer: if self._sock_type == SOCK_STREAM: avail = self.available() if avail: - reading = _the_interface.socket_read(self.socknum, avail) - self._buffer += reading[1] + self._buffer += _the_interface.socket_read(self.socknum, avail)[1] elif self._sock_type == SOCK_DGRAM: avail = _the_interface.udp_remaining() if avail: - self._buffer += _the_interface.read_udp(self.socknum, avail)[1] + self._buffer += _the_interface.read_udp(self.socknum, avail) elif self._timeout > 0 and time.monotonic() - stamp > self._timeout: self.close() raise RuntimeError("Didn't receive response, failing out...") - #firstline = self._buffer.split(b'\n', 1) firstline, self._buffer = self._buffer.split(b'\r\n', 1) gc.collect() - #return firstline[0] return firstline def disconnect(self): From b0a1cdc2ec095d805f247ee03d35cf1f8d7c8ca0 Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 3 Mar 2020 17:53:25 -0500 Subject: [PATCH 05/41] add query count --- adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index 066aeca..232eaf2 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -30,6 +30,7 @@ * Author(s): MCQN Ltd, Brent Rubell """ +import gc import time from random import getrandbits from micropython import const @@ -122,16 +123,24 @@ def _parse_dns_response(self): # Validate flags if not int.from_bytes(self._pkt_buf[2:4], 'l') == 0x8180: return -1 - # Validate Answer RRs (>=1) + # Number of questions + qr_count = int.from_bytes(self._pkt_buf[4:6], 'l') + if not qr_count >= 1: + return -1 + # Number of answers an_count = int.from_bytes(self._pkt_buf[6:8], 'l') if not an_count >= 1: return -1 + # ARCOUNT [8:10], unused + # RRCOUNT [10:12], unused + # iterate over ANCOUNT since answer may not be type A while an_count > 0: ans_type = int.from_bytes(self._pkt_buf[41:43], 'l') ans_class = int.from_bytes(self._pkt_buf[43:45], 'l') ans_len = int.from_bytes(self._pkt_buf[49:51], 'l') + #print(ans_type, ans_class, ans_len) if ans_type == TYPE_A and ans_class == CLASS_IN: if ans_len != 4: # invalid size ret.'d From 28d1c7bfa004731bf89e336e265295edd9c2b9b4 Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 3 Mar 2020 18:38:11 -0500 Subject: [PATCH 06/41] parse based on answer instead of fixed buff size lazy parsing --- adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index 232eaf2..2edd97e 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -133,22 +133,10 @@ def _parse_dns_response(self): return -1 # ARCOUNT [8:10], unused # RRCOUNT [10:12], unused - - - # iterate over ANCOUNT since answer may not be type A - while an_count > 0: - ans_type = int.from_bytes(self._pkt_buf[41:43], 'l') - ans_class = int.from_bytes(self._pkt_buf[43:45], 'l') - ans_len = int.from_bytes(self._pkt_buf[49:51], 'l') - #print(ans_type, ans_class, ans_len) - if ans_type == TYPE_A and ans_class == CLASS_IN: - if ans_len != 4: - # invalid size ret.'d - return -1 - # return the address - return self._pkt_buf[51:55] - # not the correct answer type or class - an_count += 1 + + for i in range(0, an_count): # iterate tru answers + idx = self._pkt_buf.find(b'\x00\x04') + return self._pkt_buf[idx+2:idx+6] def _build_dns_header(self): """Builds DNS header.""" From d17a9ff0a82caa4ade79d8e5ed8d355bd7f28d77 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 09:45:08 -0500 Subject: [PATCH 07/41] lintin --- adafruit_wiznet5k/adafruit_wiznet5k.py | 4 ++-- adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index 0096056..dd51ba7 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -138,7 +138,7 @@ 'remote_ip': 0, 'remote_port': 0} -class WIZNET5K: +class WIZNET5K: # pylint: disable=too-many-public-methods """Interface for WIZNET5K module. :param ~busio.SPI spi_bus: The SPI bus the Wiznet module is connected to. :param ~digitalio.DigitalInOut cs: Chip select pin. @@ -152,7 +152,7 @@ class WIZNET5K: TCP_MODE = const(0x21) UDP_MODE = const(0x02) - # pylint: disable=too-many-arguments, too-many-public-methods + # pylint: disable=too-many-arguments def __init__(self, spi_bus, cs, reset=None, is_dhcp=True, mac=DEFAULT_MAC, debug=False): self._debug = debug diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index 2edd97e..6736be6 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -131,13 +131,16 @@ def _parse_dns_response(self): an_count = int.from_bytes(self._pkt_buf[6:8], 'l') if not an_count >= 1: return -1 - # ARCOUNT [8:10], unused - # RRCOUNT [10:12], unused - for i in range(0, an_count): # iterate tru answers + while an_count > 0: idx = self._pkt_buf.find(b'\x00\x04') + # TODO: validate subsequent based off IDX + # answer record found, types OK + gc.collect() + an_count -= 1 return self._pkt_buf[idx+2:idx+6] + def _build_dns_header(self): """Builds DNS header.""" # generate a random, 16-bit, request identifier From be5eac4cb918beb5665685d822a6aa16d95e1b7a Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 09:51:48 -0500 Subject: [PATCH 08/41] rebuild docx! --- adafruit_wiznet5k/adafruit_wiznet5k_socket.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py index 8937f28..5532d66 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py @@ -216,8 +216,10 @@ def recv(self, bufsize=0): #pylint: disable=too-many-branches return ret def readline(self): - """Attempt to return as many bytes as we can up to - but not including '\r\n'""" + """Attempt to return as many bytes as we can up to \ + but not including '\r\n'. + + """ stamp = time.monotonic() while b'\r\n' not in self._buffer: if self._sock_type == SOCK_STREAM: From 29eb7b5a2af6930e362d53c49a54c901e08d7ff8 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 09:58:19 -0500 Subject: [PATCH 09/41] ESP32SPI_Simpletest-style-test --- examples/wiznet5k_simpletest.py | 60 +++++++++++++++------------------ 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/examples/wiznet5k_simpletest.py b/examples/wiznet5k_simpletest.py index 9c8bcee..b31ee0f 100644 --- a/examples/wiznet5k_simpletest.py +++ b/examples/wiznet5k_simpletest.py @@ -1,50 +1,44 @@ -import time - import board import busio import digitalio +import adafruit_requests as requests from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket +print("Wiznet5k WebClient Test") + +TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html" +JSON_URL = "http://api.coindesk.com/v1/bpi/currentprice/USD.json" + cs = digitalio.DigitalInOut(board.D10) spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) # Initialize ethernet interface with DHCP eth = WIZNET5K(spi_bus, cs) -print("DHCP Assigned IP: ", eth.pretty_ip(eth.ip_address)) - -socket.set_interface(eth) - -host = 'wifitest.adafruit.com' -port = 80 - -addr_info = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM) -sock = socket.socket(addr_info[0], addr_info[1], addr_info[2]) - -sock.connect(addr_info[4]) +# Initialize a requests object with a socket and ethernet interface +requests.set_socket(socket, eth) -print("Connected to ", sock.getpeername()) +print("Chip Version:", eth.chip) +print("MAC Address:", [hex(i) for i in eth.mac_address]) +print("My IP address is:", eth.pretty_ip(eth.ip_address)) +print("IP lookup adafruit.com: %s" %eth.pretty_ip(eth.get_host_by_name("adafruit.com"))) -# Make a HTTP Request -sock.send(b"GET /testwifi/index.html HTTP/1.1\n") -sock.send(b"Host: 104.236.193.178\n") -sock.send(b"Connection: close\n\n") -# Start transmission timer -start = time.monotonic() +#eth._debug = True +print("Fetching text from", TEXT_URL) +r = requests.get(TEXT_URL) +print('-'*40) +print(r.text) +print('-'*40) +r.close() -bytes_avail = 0 -while not bytes_avail: - bytes_avail = sock.available() - if bytes_avail > 0: - data = sock.recv(bytes_avail) - print(data[0]) - break - time.sleep(0.05) +print() +print("Fetching json from", JSON_URL) +r = requests.get(JSON_URL) +print('-'*40) +print(r.json()) +print('-'*40) +r.close() -end = time.monotonic() -print("Received: %d bytes"%bytes_avail) -end = end - start / 1000000.0 -rate = bytes_avail / end / 1000.0 -print("Rate = %0.5f kbytes/second"%rate) +print("Done!") \ No newline at end of file From bc82d38d1b91a00785121c7a897f5074778f9288 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 10:06:36 -0500 Subject: [PATCH 10/41] correct parse, TODO: guards --- adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index 6736be6..93c63d8 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -133,12 +133,14 @@ def _parse_dns_response(self): return -1 while an_count > 0: - idx = self._pkt_buf.find(b'\x00\x04') + idx = self._pkt_buf.find(b'\xc0\x0c') + print("Packet IDX: ", idx) + print(self._pkt_buf) # TODO: validate subsequent based off IDX # answer record found, types OK gc.collect() an_count -= 1 - return self._pkt_buf[idx+2:idx+6] + return self._pkt_buf[idx+12:idx+16] def _build_dns_header(self): From 32f18e0953c3c586bfe26c55bdd362484ae20399 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 10:47:43 -0500 Subject: [PATCH 11/41] lintin --- adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py | 3 +++ examples/wiznet5k_simpletest.py | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py index 18b5a5d..4454eee 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py @@ -29,6 +29,7 @@ * Author(s): Jordan Terrell, Brent Rubell """ +import gc import time from random import randrange from micropython import const @@ -267,6 +268,7 @@ def parse_dhcp_response(self, response_timeout): # DNS Server self.dns_server_ip = _BUFF[281:285] + gc.collect() return msg_type, xid def request_dhcp_lease(self): @@ -324,4 +326,5 @@ def request_dhcp_lease(self): self._last_check_lease_ms = time.monotonic() # close the socket, we're done with it self._sock.close() + gc.collect() return result diff --git a/examples/wiznet5k_simpletest.py b/examples/wiznet5k_simpletest.py index b31ee0f..ba34dec 100644 --- a/examples/wiznet5k_simpletest.py +++ b/examples/wiznet5k_simpletest.py @@ -24,7 +24,6 @@ print("My IP address is:", eth.pretty_ip(eth.ip_address)) print("IP lookup adafruit.com: %s" %eth.pretty_ip(eth.get_host_by_name("adafruit.com"))) - #eth._debug = True print("Fetching text from", TEXT_URL) r = requests.get(TEXT_URL) @@ -41,4 +40,4 @@ print('-'*40) r.close() -print("Done!") \ No newline at end of file +print("Done!") From 4ca248dca890e434025b378159d282d950b0568d Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 10:56:23 -0500 Subject: [PATCH 12/41] add checks for types --- adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 28 +++++++++++++--------- examples/wiznet5k_simpletest.py | 1 + 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index 93c63d8..c89a99d 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -100,6 +100,7 @@ def gethostbyname(self, hostname): self._sock.close() return addr + # pylint: disable=too-many-return-statements def _parse_dns_response(self): """Receives and parses DNS query response. Returns desired hostname address if obtained, -1 otherwise. @@ -114,7 +115,7 @@ def _parse_dns_response(self): # timed out! return -1 time.sleep(0.05) - # store packet in buffer + # recv paket into buf self._pkt_buf = self._sock.recv() # Validate request identifier @@ -132,16 +133,21 @@ def _parse_dns_response(self): if not an_count >= 1: return -1 - while an_count > 0: - idx = self._pkt_buf.find(b'\xc0\x0c') - print("Packet IDX: ", idx) - print(self._pkt_buf) - # TODO: validate subsequent based off IDX - # answer record found, types OK - gc.collect() - an_count -= 1 - return self._pkt_buf[idx+12:idx+16] - + # find answer response + idx = self._pkt_buf.find(b'\xc0\x0c') + # Validate Type A + if not int.from_bytes(self._pkt_buf[idx+2:idx+4], 'l') == TYPE_A: + return -1 + # Validate Class IN + if not int.from_bytes(self._pkt_buf[idx+4:idx+6], 'l') == CLASS_IN: + return -1 + # Ignore 2-byte TTL + # Validate addr is IPv4 + if not int.from_bytes(self._pkt_buf[idx+10:idx+12], 'l') == DATA_LEN: + return -1 + # Return address + gc.collect() + return self._pkt_buf[idx+12:idx+16] def _build_dns_header(self): """Builds DNS header.""" diff --git a/examples/wiznet5k_simpletest.py b/examples/wiznet5k_simpletest.py index ba34dec..53797de 100644 --- a/examples/wiznet5k_simpletest.py +++ b/examples/wiznet5k_simpletest.py @@ -24,6 +24,7 @@ print("My IP address is:", eth.pretty_ip(eth.ip_address)) print("IP lookup adafruit.com: %s" %eth.pretty_ip(eth.get_host_by_name("adafruit.com"))) + #eth._debug = True print("Fetching text from", TEXT_URL) r = requests.get(TEXT_URL) From ea7f98d6ff0c68814fba7aa9994f55f995f33cd8 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 11:08:11 -0500 Subject: [PATCH 13/41] modify readme for new example, spnx test buildin docs --- README.rst | 65 +++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/README.rst b/README.rst index df93390..df9b802 100644 --- a/README.rst +++ b/README.rst @@ -57,45 +57,50 @@ wifitest.adafruit.com. .. code-block:: python - import time - import board import busio import digitalio - from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET + import adafruit_requests as requests + from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket + print("Wiznet5k WebClient Test") + + TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html" + JSON_URL = "http://api.coindesk.com/v1/bpi/currentprice/USD.json" + cs = digitalio.DigitalInOut(board.D10) spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) # Initialize ethernet interface with DHCP - eth = WIZNET5K(spi_bus, cs, debug=True) - - print("DHCP Assigned IP: ", eth.pretty_ip(eth.ip_address)) - - socket.set_interface(eth) - - host = 'wifitest.adafruit.com' - port = 80 - - addr_info = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM) - sock = socket.socket(addr_info[0], addr_info[1], addr_info[2]) - - print("Connected to ", sock.getpeername()) - - # Make a HTTP Request - sock.send(b"GET /testwifi/index.html HTTP/1.1\n") - sock.send(b"Host: 104.236.193.178\n") - sock.send(b"Connection: close\n\n") - - bytes_avail = 0 - while not bytes_avail: - bytes_avail = sock.available() - if bytes_avail > 0: - data = sock.recv(bytes_avail) - print(data) - break - time.sleep(0.05) + eth = WIZNET5K(spi_bus, cs) + + # Initialize a requests object with a socket and ethernet interface + requests.set_socket(socket, eth) + + print("Chip Version:", eth.chip) + print("MAC Address:", [hex(i) for i in eth.mac_address]) + print("My IP address is:", eth.pretty_ip(eth.ip_address)) + print("IP lookup adafruit.com: %s" %eth.pretty_ip(eth.get_host_by_name("adafruit.com"))) + + + #eth._debug = True + print("Fetching text from", TEXT_URL) + r = requests.get(TEXT_URL) + print('-'*40) + print(r.text) + print('-'*40) + r.close() + + print() + print("Fetching json from", JSON_URL) + r = requests.get(JSON_URL) + print('-'*40) + print(r.json()) + print('-'*40) + r.close() + + print("Done!") Contributing ============ From 39385adf99366d3c534c0c80becb8e4579623aaf Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 12:06:03 -0500 Subject: [PATCH 14/41] throw assertionerror if dns was failed to resolve --- adafruit_wiznet5k/adafruit_wiznet5k.py | 1 + 1 file changed, 1 insertion(+) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index dd51ba7..e1d209e 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -229,6 +229,7 @@ def get_host_by_name(self, hostname): # Return IP assigned by DHCP _dns_client = dns.DNS(self, self._dns) ret = _dns_client.gethostbyname(hostname) + assert ret != -1, "Failed to resolve hostname from DNS server." self._src_port = 0 return ret From 5d96a2d3f1d9f0d1a422b0155d233da8d59e4821 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 12:13:05 -0500 Subject: [PATCH 15/41] add resolved ip for debugging --- adafruit_wiznet5k/adafruit_wiznet5k.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index e1d209e..a430d0e 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -229,7 +229,9 @@ def get_host_by_name(self, hostname): # Return IP assigned by DHCP _dns_client = dns.DNS(self, self._dns) ret = _dns_client.gethostbyname(hostname) - assert ret != -1, "Failed to resolve hostname from DNS server." + if self._debug: + print("* Resolved IP: ", ret) + assert ret != -1, "Failed to resolve hostname!" self._src_port = 0 return ret From 42a2faf3c88036944596e18d4bcbdbc6ebc5fb9d Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 12:18:39 -0500 Subject: [PATCH 16/41] debugging for DHCP server --- adafruit_wiznet5k/adafruit_wiznet5k.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index a430d0e..523101d 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -199,8 +199,6 @@ def set_dhcp(self, response_timeout=1): _dhcp_client = dhcp.DHCP(self, self.mac_address, response_timeout) ret = _dhcp_client.request_dhcp_lease() if ret == 1: - if self._debug: - print("* Found DHCP server - setting configuration...") _ip = (_dhcp_client.local_ip[0], _dhcp_client.local_ip[1], _dhcp_client.local_ip[2], _dhcp_client.local_ip[3]) @@ -213,7 +211,15 @@ def set_dhcp(self, response_timeout=1): self._dns = (_dhcp_client.dns_server_ip[0], _dhcp_client.dns_server_ip[1], _dhcp_client.dns_server_ip[2], _dhcp_client.dns_server_ip[3]) self.ifconfig = ((_ip, _subnet_mask, _gw_addr, self._dns)) + if self._debug: + print("* Found DHCP Server:") + print("IP: {}\nSubnet Mask: {}\nGW Addr: {}\nDNS Server: {}".format(_ip, + _subnet_mask, + _gw_addr, + self._dns)) return 0 + if self._debug: + print("* Failed to find DHCP server!") self._src_port = 0 return 1 From 6dc07aebb12df7ccf17433b0faf482f838eb74ca Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 12:24:57 -0500 Subject: [PATCH 17/41] add debug iface to DNS --- adafruit_wiznet5k/adafruit_wiznet5k.py | 2 +- adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index 523101d..1f28364 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -233,7 +233,7 @@ def get_host_by_name(self, hostname): hostname = bytes(hostname, 'utf-8') self._src_port = int(time.monotonic()) # Return IP assigned by DHCP - _dns_client = dns.DNS(self, self._dns) + _dns_client = dns.DNS(self, self._dns, debug=self._debug) ret = _dns_client.gethostbyname(hostname) if self._debug: print("* Resolved IP: ", ret) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index c89a99d..d4cff9b 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -62,7 +62,8 @@ class DNS: :param iface: Network interface """ - def __init__(self, iface, dns_address): + def __init__(self, iface, dns_address, debug=False): + self._debug = debug self._iface = iface socket.set_interface(iface) self._sock = socket.socket(type=socket.SOCK_DGRAM) @@ -88,6 +89,8 @@ def gethostbyname(self, hostname): # Send DNS request packet self._sock.connect((self._dns_server, DNS_PORT)) + if self._debug: + print("* DNS: Sending request packet...") self._sock.send(self._pkt_buf) # wait and retry 3 times for a response @@ -95,12 +98,13 @@ def gethostbyname(self, hostname): addr = -1 while (retries < 3) and (addr == -1): addr = self._parse_dns_response() + if addr == -1 and self._debug: + print("* DNS: Failed to resolve DNS response, retrying...") retries += 1 self._sock.close() return addr - # pylint: disable=too-many-return-statements def _parse_dns_response(self): """Receives and parses DNS query response. Returns desired hostname address if obtained, -1 otherwise. From 4580e6d0f338e8193c2053e3103cf67cd7b6d1ed Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 12:36:37 -0500 Subject: [PATCH 18/41] add way more verbose debugging within dns --- adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 42 +++++++++++++++++----- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index d4cff9b..075070b 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -99,13 +99,13 @@ def gethostbyname(self, hostname): while (retries < 3) and (addr == -1): addr = self._parse_dns_response() if addr == -1 and self._debug: - print("* DNS: Failed to resolve DNS response, retrying...") + print("* DNS ERROR: Failed to resolve DNS response, retrying...") retries += 1 self._sock.close() return addr - def _parse_dns_response(self): + def _parse_dns_response(self): # pylint: disable=too-many-return-statements, too-many-branches """Receives and parses DNS query response. Returns desired hostname address if obtained, -1 otherwise. @@ -116,38 +116,62 @@ def _parse_dns_response(self): while packet_sz <= 0: packet_sz = self._sock.available() if (time.monotonic() - start_time) > 1.0: - # timed out! + if self._debug: + print("* DNS ERROR: Did not receive DNS response!") return -1 time.sleep(0.05) - # recv paket into buf + # recv packet into buf self._pkt_buf = self._sock.recv() + if self._debug: + print("DNS Packet Received: ", self._pkt_buf) + # Validate request identifier - if not int.from_bytes(self._pkt_buf[0:2], 'l') == self._request_id: + xid = int.from_bytes(self._pkt_buf[0:2], 'l') + if not xid == self._request_id: + if self._debug: + print("* DNS ERROR: Received request identifer {} \ + does not match expected {}".format(xid, self._request_id)) return -1 # Validate flags - if not int.from_bytes(self._pkt_buf[2:4], 'l') == 0x8180: + flags = int.from_bytes(self._pkt_buf[2:4], 'l') + if not flags == 0x8180: + if self._debug: + print("* DNS ERROR: Invalid flags, ", flags) return -1 # Number of questions qr_count = int.from_bytes(self._pkt_buf[4:6], 'l') if not qr_count >= 1: + if self._debug: + print("* DNS ERROR: Question count >=1, ", qr_count) return -1 # Number of answers an_count = int.from_bytes(self._pkt_buf[6:8], 'l') + if self._debug: + print("* DNS Answer Count: ", an_count) if not an_count >= 1: return -1 # find answer response idx = self._pkt_buf.find(b'\xc0\x0c') # Validate Type A - if not int.from_bytes(self._pkt_buf[idx+2:idx+4], 'l') == TYPE_A: + ans_type = int.from_bytes(self._pkt_buf[idx+2:idx+4], 'l') + if not ans_type == TYPE_A: + if self._debug: + print("* DNS ERROR: Incorrect Answer Type: ", ans_type) return -1 # Validate Class IN - if not int.from_bytes(self._pkt_buf[idx+4:idx+6], 'l') == CLASS_IN: + class_type = int.from_bytes(self._pkt_buf[idx+4:idx+6], 'l') + if not class_type == CLASS_IN: + if self._debug: + print("* DNS ERROR: Incorrect Class Type: ", class_type) return -1 # Ignore 2-byte TTL # Validate addr is IPv4 - if not int.from_bytes(self._pkt_buf[idx+10:idx+12], 'l') == DATA_LEN: + data_length = int.from_bytes(self._pkt_buf[idx+10:idx+12], 'l') + if not data_length == DATA_LEN: + if self._debug: + print("* DNS ERROR: Unexpected Data Length: ", data_length) return -1 # Return address gc.collect() From d65fc58f50a30c77df8d8e0c746f7f77863d6ac8 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 13:21:17 -0500 Subject: [PATCH 19/41] trying a different approach for parsing out the query name and validating query types, TODO: same approach for ans. response --- adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 33 ++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index 075070b..79803a0 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -105,7 +105,7 @@ def gethostbyname(self, hostname): self._sock.close() return addr - def _parse_dns_response(self): # pylint: disable=too-many-return-statements, too-many-branches + def _parse_dns_response(self): # pylint: disable=too-many-return-statements, too-many-branches, too-many-statements, too-many-locals """Receives and parses DNS query response. Returns desired hostname address if obtained, -1 otherwise. @@ -152,7 +152,36 @@ def _parse_dns_response(self): # pylint: disable=too-many-return-statements, too if not an_count >= 1: return -1 - # find answer response + # Parse query + ptr = 12 + name_len = 1 + while name_len > 0: + # read the length of the name + name_len = self._pkt_buf[ptr] + if name_len == 0x00: + # we reached the end of this name + ptr += 1 # inc. pointer by 0x00 + break + # advance pointer + ptr += name_len + 1 + + # Validate Query is Type A + q_type = int.from_bytes(self._pkt_buf[ptr:ptr+2], 'l') + if not q_type == TYPE_A: + if self._debug: + print("* DNS ERROR: Incorrect Query Type: ", q_type) + return -1 + ptr += 2 + + # Validate Query is Type A + q_class = int.from_bytes(self._pkt_buf[ptr:ptr+2], 'l') + if not q_class == TYPE_A: + if self._debug: + print("* DNS ERROR: Incorrect Query Class: ", q_class) + return -1 + ptr += 2 + + # find answer response, TODO: Remove in favor of stream-like approach above idx = self._pkt_buf.find(b'\xc0\x0c') # Validate Type A ans_type = int.from_bytes(self._pkt_buf[idx+2:idx+4], 'l') From 2043d7d4bfdada35bad9666833425093c08307f1 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 13:39:47 -0500 Subject: [PATCH 20/41] Better parsing for answer --- adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 41 ++++++++++++++-------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index 79803a0..e93a1c0 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -181,30 +181,43 @@ def _parse_dns_response(self): # pylint: disable=too-many-return-statements, too return -1 ptr += 2 - # find answer response, TODO: Remove in favor of stream-like approach above - idx = self._pkt_buf.find(b'\xc0\x0c') - # Validate Type A - ans_type = int.from_bytes(self._pkt_buf[idx+2:idx+4], 'l') + # Let's take the first type-a answer + if self._pkt_buf[ptr] != 0xc0: + return -1 + ptr += 1 + + if self._pkt_buf[ptr] != 0xc: + return -1 + ptr += 1 + + # Validate Answer Type A + ans_type = int.from_bytes(self._pkt_buf[ptr:ptr+2], 'l') if not ans_type == TYPE_A: if self._debug: print("* DNS ERROR: Incorrect Answer Type: ", ans_type) return -1 - # Validate Class IN - class_type = int.from_bytes(self._pkt_buf[idx+4:idx+6], 'l') - if not class_type == CLASS_IN: + ptr += 2 + + # Validate Answer Class IN + ans_class = int.from_bytes(self._pkt_buf[ptr:ptr+2], 'l') + if not ans_class == TYPE_A: if self._debug: - print("* DNS ERROR: Incorrect Class Type: ", class_type) + print("* DNS ERROR: Incorrect Answer Class: ", ans_class) return -1 - # Ignore 2-byte TTL + ptr += 2 + + # skip over TTL + ptr += 4 + # Validate addr is IPv4 - data_length = int.from_bytes(self._pkt_buf[idx+10:idx+12], 'l') - if not data_length == DATA_LEN: + data_len = int.from_bytes(self._pkt_buf[ptr:ptr+2], 'l') + if not data_len == DATA_LEN: if self._debug: - print("* DNS ERROR: Unexpected Data Length: ", data_length) + print("* DNS ERROR: Unexpected Data Length: ", data_len) return -1 + ptr += 2 # Return address - gc.collect() - return self._pkt_buf[idx+12:idx+16] + return self._pkt_buf[ptr:ptr+4] def _build_dns_header(self): """Builds DNS header.""" From 08bb7c9a303f85581ca4785c15fbe9ee9bf93030 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 13:42:08 -0500 Subject: [PATCH 21/41] remove gc --- adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 1 - 1 file changed, 1 deletion(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index e93a1c0..a448548 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -30,7 +30,6 @@ * Author(s): MCQN Ltd, Brent Rubell """ -import gc import time from random import getrandbits from micropython import const From cb352dde56ce078e0b59a7a689f3816d51eb7235 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 13:53:40 -0500 Subject: [PATCH 22/41] add ip to socket begin --- adafruit_wiznet5k/adafruit_wiznet5k.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index 1f28364..3ac655b 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -556,7 +556,8 @@ def socket_open(self, socket_num, dest, port, conn_mode=SNMR_TCP): print("*** Opening socket %d"%socket_num) if self._read_snsr(socket_num)[0] == SNSR_SOCK_CLOSED: if self._debug: - print("w5k socket begin, protocol={}, port={}".format(conn_mode, port)) + print("w5k socket begin, protocol={}, port={}, ip={}".format(conn_mode, port, + self.pretty_ip(dest))) time.sleep(0.00025) self._write_snmr(socket_num, conn_mode) From 9ec9ed094dda4914930561415fa38fd764d90845 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 14:13:02 -0500 Subject: [PATCH 23/41] add debug to dhcp --- adafruit_wiznet5k/adafruit_wiznet5k.py | 2 +- adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index 3ac655b..38c6f00 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -196,7 +196,7 @@ def set_dhcp(self, response_timeout=1): print("* Initializing DHCP") self._src_port = 68 # Return IP assigned by DHCP - _dhcp_client = dhcp.DHCP(self, self.mac_address, response_timeout) + _dhcp_client = dhcp.DHCP(self, self.mac_address, response_timeout, debug=self._debug) ret = _dhcp_client.request_dhcp_lease() if ret == 1: _ip = (_dhcp_client.local_ip[0], _dhcp_client.local_ip[1], diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py index 4454eee..00e9494 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py @@ -89,7 +89,8 @@ class DHCP: """ # pylint: disable=too-many-arguments, too-many-instance-attributes, invalid-name - def __init__(self, eth, mac_address, timeout=1, timeout_response=1): + def __init__(self, eth, mac_address, timeout=1, timeout_response=1, debug=False): + self._debug = debug self._timeout = timeout self._response_timeout = timeout_response self._mac_address = mac_address @@ -230,6 +231,8 @@ def parse_dhcp_response(self, response_timeout): time.sleep(0.05) # store packet in buffer _BUFF = self._sock.recv() + if self._debug: + print("DHCP Response: ", _BUFF) # Check OP, if valid, let's parse the packet out! assert _BUFF[0] == DHCP_BOOT_REPLY, "Malformed Packet - \ From ec4932978a8edb4faa94e6d160fdf51c81221896 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 18:14:12 -0500 Subject: [PATCH 24/41] add old params --- adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py | 157 ++++++++++++++++---- 1 file changed, 125 insertions(+), 32 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py index 00e9494..028cc4a 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py @@ -75,6 +75,18 @@ DEFAULT_LEASE_TIME = const(900) BROADCAST_SERVER_ADDR = '255.255.255.255' +# DHCP Response Options +MSG_TYPE = 53 +SUBNET_MASK = 1 +ROUTERS_ON_SUBNET = 3 +DNS_SERVERS = 6 +DHCP_SERVER_ID = 54 +T1_VAL = 58 +T2_VAL = 59 +LEASE_TIME = 51 +OPT_END = 255 + + # pylint: enable=bad-whitespace _BUFF = bytearray(317) @@ -231,6 +243,7 @@ def parse_dhcp_response(self, response_timeout): time.sleep(0.05) # store packet in buffer _BUFF = self._sock.recv() + # _BUFF = b'\x02\x01\x06\x00\x00\x00\x05\x0e\x00\x00\x80\x00\x00\x00\x00\x00\n\x00\x010\x00\x00\x00\x00\x00\x00\x00\x00\xde\xad\xbe\xef\xfe\xed\xed\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x82Sc5\x01\x056\x04\n\x00\x01\x013\x04\x00\x00\xa8\xc0\x01\x04\xff\xff\xff\x00\x03\x04\n\x00\x01\x01\x06\x04\n\x00\x01\x01\x0f\x10fios-router.home:\x04\x00\x00T`;\x04\x00\x00\x93\xa8\xff' if self._debug: print("DHCP Response: ", _BUFF) @@ -238,38 +251,110 @@ def parse_dhcp_response(self, response_timeout): assert _BUFF[0] == DHCP_BOOT_REPLY, "Malformed Packet - \ DHCP message OP is not expected BOOT Reply." - # Client Hardware Address (CHADDR) - chaddr = bytearray(6) - for mac, _ in enumerate(chaddr): - chaddr[mac] = _BUFF[28+mac] - - if chaddr != 0: - xid = _BUFF[4:8] - if bytes(xid) < self._initial_xid: - return 0, 0 - - # Your IP Address (YIADDR) - self.local_ip = _BUFF[16:20] - - # Gateway IP Address (GIADDR) - self.gateway_ip = _BUFF[20:24] - - # NOTE: Next 192 octets are 0's for BOOTP legacy - - # DHCP Message Type - msg_type = _BUFF[242] - # DHCP Server ID - self.dhcp_server_ip = _BUFF[245:249] - # Lease Time, in seconds - self._lease_time = int.from_bytes(_BUFF[251:255], 'l') - # T1 value - self._t1 = int.from_bytes(_BUFF[257:261], 'l') - # T2 value - self._t2 = int.from_bytes(_BUFF[263:267], 'l') - # Subnet Mask - self.subnet_mask = _BUFF[269:273] - # DNS Server - self.dns_server_ip = _BUFF[281:285] + # Parse out FIXED portion of DHCP packet + op = _BUFF[0] + htype = _BUFF[1] + hlen = _BUFF[2] + hops = _BUFF[3] + xid = _BUFF[4:8] + if bytes(_BUFF[4:8]) < self._initial_xid: + print("yes") + #return 0, 0 + + + secs = _BUFF[8:10] + flags = _BUFF[10:12] + ciaddr = _BUFF[12:16] + + self.local_ip = _BUFF[16:20] + self.gateway_ip = _BUFF[24:28] + yiaddr = _BUFF[16:20] + siaddr = _BUFF[20:24] + giaddr = _BUFF[24:28] + if _BUFF[28:34] == 0: + print("no") + #return 0, 0 + + if int.from_bytes(_BUFF[235:240], 'l') != MAGIC_COOKIE: + print("NO!") + #return 0, 0 + + + # Parse out VARIABLE options + print('Remaining Option Len: ', len(_BUFF[240:])) + print(_BUFF[240:]) + ptr = 240 + buff_remaining = len(_BUFF[240:]) + while buff_remaining > 0: + print("reading..", ptr) + print('byte: ', _BUFF[ptr]) + if _BUFF[ptr] == MSG_TYPE: + ptr += 1 + opt_len = _BUFF[ptr] + ptr += opt_len + msg_type = _BUFF[ptr] + ptr += 1 + print("MSG TYPE: ", msg_type) + elif _BUFF[ptr] == SUBNET_MASK: + ptr += 1 + opt_len = _BUFF[ptr] + ptr += 1 + self.subnet_mask = _BUFF[ptr:ptr+opt_len] + ptr += opt_len + print("SUBNET MASK: ", self.subnet_mask) + elif _BUFF[ptr] == DHCP_SERVER_ID: + ptr += 1 + opt_len = _BUFF[ptr] + ptr += 1 + self.dhcp_server_ip = _BUFF[ptr:ptr+opt_len] + ptr += opt_len + print("DHCP SERVER ID: ", self.dhcp_server_ip) + elif _BUFF[ptr] == LEASE_TIME: + ptr += 1 + opt_len = _BUFF[ptr] + ptr += 1 + self._lease_time = int.from_bytes(_BUFF[ptr:ptr+opt_len], 'l') + ptr += opt_len + print("Lease Time: ", self._lease_time) + elif _BUFF[ptr] == ROUTERS_ON_SUBNET: + ptr += 1 + opt_len = _BUFF[ptr] + ptr += 1 + gateway_ip = _BUFF[ptr:ptr+opt_len] + ptr += opt_len + print("gateway_ip: ", gateway_ip) + elif _BUFF[ptr] == DNS_SERVERS: + ptr += 2 # move past length + # NOTE: we're only using the first DNS server + opt_len = _BUFF[ptr] + self.dns_server_ip = _BUFF[ptr:ptr+4] + ptr += opt_len # still increment even though we only read 1 addr. + print("dns_server: ", self.dns_server_ip) + elif _BUFF[ptr] == T1_VAL: + ptr += 1 + opt_len = _BUFF[ptr] + ptr += 1 + self._t1 = int.from_bytes(_BUFF[ptr:ptr+opt_len], 'l') + ptr += opt_len + print("t1: ", self._t1) + elif _BUFF[ptr] == T2_VAL: + ptr += 1 + opt_len = _BUFF[ptr] + ptr += 1 + self._t2 = int.from_bytes(_BUFF[ptr:ptr+opt_len], 'l') + ptr += opt_len + print("t2: ", self._t2) + elif _BUFF[ptr] == OPT_END: + break + else: + # We're not interested in this option + ptr += 1 + opt_len = _BUFF[ptr] + ptr += 1 + # no-op + ptr += opt_len + buff_remaining = ptr - buff_remaining + print('remaining: ', buff_remaining) gc.collect() return msg_type, xid @@ -289,18 +374,26 @@ def request_dhcp_lease(self): if self._dhcp_state == STATE_DHCP_START: self._transaction_id += 1 self._sock.connect(((BROADCAST_SERVER_ADDR), DHCP_SERVER_PORT)) + if self._debug: + print("* DHCP: Discover") self.send_dhcp_message(STATE_DHCP_DISCOVER, ((time.monotonic() - start_time) / 1000)) self._dhcp_state = STATE_DHCP_DISCOVER elif self._dhcp_state == STATE_DHCP_DISCOVER: + if self._debug: + print("* DHCP: Parsing OFFER") msg_type, xid = self.parse_dhcp_response(self._timeout) if msg_type == DHCP_OFFER: # use the _transaction_id the offer returned, # rather than the current one self._transaction_id = self._transaction_id.from_bytes(xid, 'l') + if self._debug: + print("* DHCP: Request") self.send_dhcp_message(DHCP_REQUEST, ((time.monotonic() - start_time) / 1000)) self._dhcp_state = STATE_DHCP_REQUEST elif STATE_DHCP_REQUEST: + if self._debug: + print("* DHCP: Parsing ACK") msg_type, xid = self.parse_dhcp_response(self._timeout) if msg_type == DHCP_ACK: self._dhcp_state = STATE_DHCP_LEASED From e0b3d232c84a945207d3093416ff139a3d662d4e Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 18:43:38 -0500 Subject: [PATCH 25/41] remove cruft, new impl --- adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py | 55 +++++---------------- 1 file changed, 12 insertions(+), 43 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py index 028cc4a..5edbb4b 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py @@ -228,7 +228,7 @@ def send_dhcp_message(self, state, time_elapsed): # Send DHCP packet self._sock.send(_BUFF) - def parse_dhcp_response(self, response_timeout): + def parse_dhcp_response(self, response_timeout): # pylint: disable=too-many-branches, too-many-statements """Parse DHCP response from DHCP server. Returns DHCP packet type. @@ -243,107 +243,77 @@ def parse_dhcp_response(self, response_timeout): time.sleep(0.05) # store packet in buffer _BUFF = self._sock.recv() - # _BUFF = b'\x02\x01\x06\x00\x00\x00\x05\x0e\x00\x00\x80\x00\x00\x00\x00\x00\n\x00\x010\x00\x00\x00\x00\x00\x00\x00\x00\xde\xad\xbe\xef\xfe\xed\xed\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x82Sc5\x01\x056\x04\n\x00\x01\x013\x04\x00\x00\xa8\xc0\x01\x04\xff\xff\xff\x00\x03\x04\n\x00\x01\x01\x06\x04\n\x00\x01\x01\x0f\x10fios-router.home:\x04\x00\x00T`;\x04\x00\x00\x93\xa8\xff' if self._debug: print("DHCP Response: ", _BUFF) - # Check OP, if valid, let's parse the packet out! + # -- Parse Packet, FIXED -- # + # Validate OP assert _BUFF[0] == DHCP_BOOT_REPLY, "Malformed Packet - \ DHCP message OP is not expected BOOT Reply." - # Parse out FIXED portion of DHCP packet - op = _BUFF[0] - htype = _BUFF[1] - hlen = _BUFF[2] - hops = _BUFF[3] xid = _BUFF[4:8] - if bytes(_BUFF[4:8]) < self._initial_xid: - print("yes") - #return 0, 0 + if bytes(xid) < self._initial_xid: + return 0, 0 - - secs = _BUFF[8:10] - flags = _BUFF[10:12] - ciaddr = _BUFF[12:16] - - self.local_ip = _BUFF[16:20] - self.gateway_ip = _BUFF[24:28] - yiaddr = _BUFF[16:20] - siaddr = _BUFF[20:24] - giaddr = _BUFF[24:28] + self.local_ip = _BUFF[16:20] if _BUFF[28:34] == 0: - print("no") - #return 0, 0 + return 0, 0 if int.from_bytes(_BUFF[235:240], 'l') != MAGIC_COOKIE: - print("NO!") - #return 0, 0 - + return 0, 0 - # Parse out VARIABLE options - print('Remaining Option Len: ', len(_BUFF[240:])) - print(_BUFF[240:]) + # -- Parse Packet, VARIABLE -- # ptr = 240 buff_remaining = len(_BUFF[240:]) while buff_remaining > 0: - print("reading..", ptr) - print('byte: ', _BUFF[ptr]) if _BUFF[ptr] == MSG_TYPE: ptr += 1 opt_len = _BUFF[ptr] ptr += opt_len msg_type = _BUFF[ptr] ptr += 1 - print("MSG TYPE: ", msg_type) elif _BUFF[ptr] == SUBNET_MASK: ptr += 1 opt_len = _BUFF[ptr] ptr += 1 self.subnet_mask = _BUFF[ptr:ptr+opt_len] ptr += opt_len - print("SUBNET MASK: ", self.subnet_mask) elif _BUFF[ptr] == DHCP_SERVER_ID: ptr += 1 opt_len = _BUFF[ptr] ptr += 1 self.dhcp_server_ip = _BUFF[ptr:ptr+opt_len] ptr += opt_len - print("DHCP SERVER ID: ", self.dhcp_server_ip) elif _BUFF[ptr] == LEASE_TIME: ptr += 1 opt_len = _BUFF[ptr] ptr += 1 - self._lease_time = int.from_bytes(_BUFF[ptr:ptr+opt_len], 'l') + self._lease_time = int.from_bytes(_BUFF[ptr:ptr+opt_len], 'l') ptr += opt_len - print("Lease Time: ", self._lease_time) elif _BUFF[ptr] == ROUTERS_ON_SUBNET: ptr += 1 opt_len = _BUFF[ptr] ptr += 1 - gateway_ip = _BUFF[ptr:ptr+opt_len] + self.gateway_ip = _BUFF[ptr:ptr+opt_len] ptr += opt_len - print("gateway_ip: ", gateway_ip) elif _BUFF[ptr] == DNS_SERVERS: ptr += 2 # move past length # NOTE: we're only using the first DNS server opt_len = _BUFF[ptr] self.dns_server_ip = _BUFF[ptr:ptr+4] ptr += opt_len # still increment even though we only read 1 addr. - print("dns_server: ", self.dns_server_ip) elif _BUFF[ptr] == T1_VAL: ptr += 1 opt_len = _BUFF[ptr] ptr += 1 self._t1 = int.from_bytes(_BUFF[ptr:ptr+opt_len], 'l') ptr += opt_len - print("t1: ", self._t1) elif _BUFF[ptr] == T2_VAL: ptr += 1 opt_len = _BUFF[ptr] ptr += 1 self._t2 = int.from_bytes(_BUFF[ptr:ptr+opt_len], 'l') ptr += opt_len - print("t2: ", self._t2) elif _BUFF[ptr] == OPT_END: break else: @@ -354,12 +324,11 @@ def parse_dhcp_response(self, response_timeout): # no-op ptr += opt_len buff_remaining = ptr - buff_remaining - print('remaining: ', buff_remaining) gc.collect() return msg_type, xid - def request_dhcp_lease(self): + def request_dhcp_lease(self): # pylint: disable=too-many-branches """Request to renew or acquire a DHCP lease. """ From 7d7ef0ecbd32574e3e82c7b866847fc907b362af Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 19:56:30 -0500 Subject: [PATCH 26/41] run buf til pointer is at end --- adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py index 5edbb4b..0a8c17f 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py @@ -264,8 +264,7 @@ def parse_dhcp_response(self, response_timeout): # pylint: disable=too-many-bran # -- Parse Packet, VARIABLE -- # ptr = 240 - buff_remaining = len(_BUFF[240:]) - while buff_remaining > 0: + while _BUFF[ptr] != OPT_END: if _BUFF[ptr] == MSG_TYPE: ptr += 1 opt_len = _BUFF[ptr] @@ -314,8 +313,6 @@ def parse_dhcp_response(self, response_timeout): # pylint: disable=too-many-bran ptr += 1 self._t2 = int.from_bytes(_BUFF[ptr:ptr+opt_len], 'l') ptr += opt_len - elif _BUFF[ptr] == OPT_END: - break else: # We're not interested in this option ptr += 1 @@ -323,7 +320,10 @@ def parse_dhcp_response(self, response_timeout): # pylint: disable=too-many-bran ptr += 1 # no-op ptr += opt_len - buff_remaining = ptr - buff_remaining + + if self._debug: + print("Msg Type: {}\nSubnet Mask: {}\n\ + DHCP Server ID:{}\n".format(msg_type, self.subnet_mask, self.dhcp_server_ip)) gc.collect() return msg_type, xid From 7db5a2ca74661ea2f48f38edc08bf430d604c139 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 20:03:01 -0500 Subject: [PATCH 27/41] add more verbose output for parsing DHCP requests if debug --- adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py index 0a8c17f..3c073a6 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py @@ -322,8 +322,13 @@ def parse_dhcp_response(self, response_timeout): # pylint: disable=too-many-bran ptr += opt_len if self._debug: - print("Msg Type: {}\nSubnet Mask: {}\n\ - DHCP Server ID:{}\n".format(msg_type, self.subnet_mask, self.dhcp_server_ip)) + print("Msg Type: {}\nSubnet Mask: {}\nDHCP Server ID:{}\nDNS Server IP:{}\ + \nGateway IP:{}\nT1:{}\nT2:{}\nLease Time:{}".format(msg_type, self.subnet_mask, + self.dhcp_server_ip, + self.dns_server_ip, + self.gateway_ip, + self._t1, self._t2, + self._lease_time)) gc.collect() return msg_type, xid From a028c346dd4d4b72b221da1aab28473baad0c30e Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 20:48:46 -0500 Subject: [PATCH 28/41] if initialized, dhcp failing to configure should Raise. Handle invalid xid, magic cookie, MAC within dhcp state machine --- adafruit_wiznet5k/adafruit_wiznet5k.py | 8 +++----- adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py | 10 +++++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index 38c6f00..d582d36 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -183,7 +183,8 @@ def __init__(self, spi_bus, cs, reset=None, self._dns = 0 # Set DHCP if is_dhcp: - self.set_dhcp() + ret = self.set_dhcp() + assert ret == 0, "Failed to configure DHCP Server!" def set_dhcp(self, response_timeout=1): """Initializes the DHCP client and attempts to retrieve @@ -218,10 +219,7 @@ def set_dhcp(self, response_timeout=1): _gw_addr, self._dns)) return 0 - if self._debug: - print("* Failed to find DHCP server!") - self._src_port = 0 - return 1 + return -1 def get_host_by_name(self, hostname): """Convert a hostname to a packed 4-byte IP Address. diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py index 3c073a6..173d534 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py @@ -296,9 +296,9 @@ def parse_dhcp_response(self, response_timeout): # pylint: disable=too-many-bran self.gateway_ip = _BUFF[ptr:ptr+opt_len] ptr += opt_len elif _BUFF[ptr] == DNS_SERVERS: - ptr += 2 # move past length - # NOTE: we're only using the first DNS server + ptr += 1 opt_len = _BUFF[ptr] + ptr += 1 self.dns_server_ip = _BUFF[ptr:ptr+4] ptr += opt_len # still increment even though we only read 1 addr. elif _BUFF[ptr] == T1_VAL: @@ -333,7 +333,7 @@ def parse_dhcp_response(self, response_timeout): # pylint: disable=too-many-bran gc.collect() return msg_type, xid - def request_dhcp_lease(self): # pylint: disable=too-many-branches + def request_dhcp_lease(self): # pylint: disable=too-many-branches, too-many-statements """Request to renew or acquire a DHCP lease. """ @@ -365,6 +365,8 @@ def request_dhcp_lease(self): # pylint: disable=too-many-branches print("* DHCP: Request") self.send_dhcp_message(DHCP_REQUEST, ((time.monotonic() - start_time) / 1000)) self._dhcp_state = STATE_DHCP_REQUEST + else: + print("* Received DHCP Message is not OFFER") elif STATE_DHCP_REQUEST: if self._debug: print("* DHCP: Parsing ACK") @@ -384,6 +386,8 @@ def request_dhcp_lease(self): # pylint: disable=too-many-branches self._rebind_in_sec = self._t2 elif msg_type == DHCP_NAK: self._dhcp_state = STATE_DHCP_START + else: + print("* Received DHCP Message is not OFFER") if msg_type == 255: msg_type = 0 From 30c9f0af9edde7d078608f514f4aefc07162be5c Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 4 Mar 2020 20:59:00 -0500 Subject: [PATCH 29/41] break on padding opt --- adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py index 173d534..4f6e602 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py @@ -313,6 +313,8 @@ def parse_dhcp_response(self, response_timeout): # pylint: disable=too-many-bran ptr += 1 self._t2 = int.from_bytes(_BUFF[ptr:ptr+opt_len], 'l') ptr += opt_len + elif _BUFF[ptr] == 0: + break else: # We're not interested in this option ptr += 1 From 088421ea4707c297f1093d30d797f6509f032548 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 5 Mar 2020 09:20:35 -0500 Subject: [PATCH 30/41] add TLS_mode conntype, assertion for connecting to HTTPS --- adafruit_wiznet5k/adafruit_wiznet5k.py | 1 + adafruit_wiznet5k/adafruit_wiznet5k_socket.py | 1 + 2 files changed, 2 insertions(+) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index d582d36..e0c7af8 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -151,6 +151,7 @@ class WIZNET5K: # pylint: disable=too-many-public-methods TCP_MODE = const(0x21) UDP_MODE = const(0x02) + TLS_MODE = const(0x03) # This is NOT currently implemented # pylint: disable=too-many-arguments def __init__(self, spi_bus, cs, reset=None, diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py index 5532d66..ddcc507 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_socket.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_socket.py @@ -141,6 +141,7 @@ def connect(self, address, conntype=None): :param tuple address: Remote socket as a (host, port) tuple. """ + assert conntype != 0x03, "Error: SSL/TLS is not currently supported by CircuitPython." host, port = address if hasattr(host, 'split'): From 406c7fb5cb238f80c52280177409ec4ecae0f21a Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 5 Mar 2020 11:27:50 -0500 Subject: [PATCH 31/41] use dynamic port numbers 41952-65535, randomize to prevent reuse! --- adafruit_wiznet5k/adafruit_wiznet5k.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index e0c7af8..a64f4af 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -41,7 +41,7 @@ * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice """ - +from random import randint import time from micropython import const @@ -540,8 +540,8 @@ def get_socket(self, sockets): break if self._src_port == 0: - self._src_port = 1024 - + # Dynamic ports 49152 to 65535. + self._src_port += randint(49152, 65535) if self._debug: print("Allocated socket #{}:{}".format(sock, self._src_port)) return sock From 4467ffe3213f307635739c9901829c74367c8b96 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 5 Mar 2020 11:39:49 -0500 Subject: [PATCH 32/41] switch to wait for sncr to clear? --- adafruit_wiznet5k/adafruit_wiznet5k.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index a64f4af..6fe3e1b 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -512,10 +512,11 @@ def socket_connect(self, socket_num, dest, port, conn_mode=SNMR_TCP): if conn_mode == SNMR_TCP: # TCP client - connect socket - self._write_sncr(socket_num, CMD_SOCK_CONNECT) - self._read_sncr(socket_num) + self._send_socket_cmd(socket_num, CMD_SOCK_CONNECT) # wait for tcp connection establishment while self.socket_status(socket_num)[0] != SNSR_SOCK_ESTABLISHED: + if self._debug: + print("STATUS:", self.socket_status(socket_num)[0]) if self.socket_status(socket_num)[0] == SNSR_SOCK_CLOSED: raise RuntimeError('Failed to establish connection.') time.sleep(1) @@ -523,6 +524,12 @@ def socket_connect(self, socket_num, dest, port, conn_mode=SNMR_TCP): UDP_SOCK['bytes_remaining'] = 0 return 1 + def _send_socket_cmd(self, socket, cmd): + self._write_sncr(socket, cmd) + while self._read_sncr(socket) != b'\x00': + if self._debug: + print("waiting for sncr to clear...") + def get_socket(self, sockets): """Requests, allocates and returns a socket from the W5k chip. Returned socket number may not exceed max_sockets. From 1eb1a5131a75c706fa8c7ab2dd397d51e176ebf2 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 5 Mar 2020 11:46:23 -0500 Subject: [PATCH 33/41] wait less time between checking sn_sr --- adafruit_wiznet5k/adafruit_wiznet5k.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index 6fe3e1b..24ffd19 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -515,11 +515,11 @@ def socket_connect(self, socket_num, dest, port, conn_mode=SNMR_TCP): self._send_socket_cmd(socket_num, CMD_SOCK_CONNECT) # wait for tcp connection establishment while self.socket_status(socket_num)[0] != SNSR_SOCK_ESTABLISHED: + time.sleep(0.001) if self._debug: - print("STATUS:", self.socket_status(socket_num)[0]) + print("SN_SR:", self.socket_status(socket_num)[0]) if self.socket_status(socket_num)[0] == SNSR_SOCK_CLOSED: raise RuntimeError('Failed to establish connection.') - time.sleep(1) elif conn_mode == SNMR_UDP: UDP_SOCK['bytes_remaining'] = 0 return 1 From ebf2d0ed41e9ee13550aef3e4cf95dfddc7f6369 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 5 Mar 2020 15:00:28 -0500 Subject: [PATCH 34/41] read and write to/from subnet registers better in ifconfig setter/getter --- adafruit_wiznet5k/adafruit_wiznet5k.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index 24ffd19..701b384 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -314,15 +314,8 @@ def remote_port(self): @property def ifconfig(self): """Returns the network configuration as a tuple.""" - # set subnet and gateway addresses - self._pbuff = bytearray(8) - for octet in range(0, 4): - self._pbuff += self.read(REG_SUBR+octet, 0x04) - for octet in range(0, 4): - self._pbuff += self.read(REG_GAR+octet, 0x04) - - params = (self.ip_address, self._pbuff[0:3], self._pbuff[3:7], self._dns) - return params + return (self.ip_address, self.read(REG_SUBR, 0x00, 4), + self.read(REG_GAR, 0x00, 4), self._dns) @ifconfig.setter def ifconfig(self, params): @@ -332,14 +325,10 @@ def ifconfig(self, params): """ ip_address, subnet_mask, gateway_address, dns_server = params - # Set IP Address self.write(REG_SIPR, 0x04, ip_address) + self.write(REG_SUBR, 0x04, subnet_mask) + self.write(REG_GAR, 0x04, gateway_address) - # set subnet and gateway addresses - for octet in range(0, 4): - self.write(REG_SUBR+octet, 0x04, subnet_mask[octet]) - self.write(REG_GAR+octet, 0x04, gateway_address[octet]) - # set dns server address self._dns = dns_server def _w5100_init(self): From 7df14f1e6b19a8b05a769961029949f9fe8259ca Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 5 Mar 2020 15:35:14 -0500 Subject: [PATCH 35/41] testing port configuration tweaks --- adafruit_wiznet5k/adafruit_wiznet5k.py | 30 ++++++++++----------- adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py | 1 + adafruit_wiznet5k/adafruit_wiznet5k_dns.py | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index 701b384..d6b3cf2 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -219,6 +219,7 @@ def set_dhcp(self, response_timeout=1): _subnet_mask, _gw_addr, self._dns)) + self._src_port = 0 return 0 return -1 @@ -495,10 +496,14 @@ def socket_connect(self, socket_num, dest, port, conn_mode=SNMR_TCP): print("*** Connecting: Socket# {}, conn_mode: {}".format(socket_num, conn_mode)) # initialize a socket and set the mode - res = self.socket_open(socket_num, dest, port, conn_mode=conn_mode) + res = self.socket_open(socket_num, port, conn_mode=conn_mode) if res == 1: raise RuntimeError('Failed to initalize a connection with the socket.') + + self._write_sndipr(socket_num, dest) + self._write_sndport(socket_num, port) + if conn_mode == SNMR_TCP: # TCP client - connect socket self._send_socket_cmd(socket_num, CMD_SOCK_CONNECT) @@ -535,14 +540,11 @@ def get_socket(self, sockets): sock = _sock break - if self._src_port == 0: - # Dynamic ports 49152 to 65535. - self._src_port += randint(49152, 65535) if self._debug: - print("Allocated socket #{}:{}".format(sock, self._src_port)) + print("Allocated socket #{}".format(sock)) return sock - def socket_open(self, socket_num, dest, port, conn_mode=SNMR_TCP): + def socket_open(self, socket_num, port, conn_mode=SNMR_TCP): """Opens a socket to a destination IP address or hostname. By default, we use 'conn_mode'=SNMR_TCP but we may also use SNMR_UDP. """ @@ -551,23 +553,18 @@ def socket_open(self, socket_num, dest, port, conn_mode=SNMR_TCP): print("*** Opening socket %d"%socket_num) if self._read_snsr(socket_num)[0] == SNSR_SOCK_CLOSED: if self._debug: - print("w5k socket begin, protocol={}, port={}, ip={}".format(conn_mode, port, - self.pretty_ip(dest))) + print("w5k socket begin, protocol={}, port={}".format(conn_mode, port)) time.sleep(0.00025) self._write_snmr(socket_num, conn_mode) self._write_snir(socket_num, 0xFF) - if self._src_port > 0: - # write to socket source port - self._write_sock_port(socket_num, self._src_port) + if port > 0: + # write to defined port + self._write_sock_port(socket_num, port) else: # if source port is not set, set the local port number - self._write_sock_port(socket_num, LOCAL_PORT) - - # set socket destination IP and port - self._write_sndipr(socket_num, dest) - self._write_sndport(socket_num, port) + self._write_sock_port(socket_num, randint(49152, 65535)) # open socket self._write_sncr(socket_num, CMD_SOCK_OPEN) @@ -584,6 +581,7 @@ def socket_close(self, socket_num): print("*** Closing socket #%d" % socket_num) self._write_sncr(socket_num, CMD_SOCK_CLOSE) self._read_sncr(socket_num) + self._src_port = 0 def socket_disconnect(self, socket_num): """Disconnect a TCP connection.""" diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py index 4f6e602..5993c22 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py @@ -253,6 +253,7 @@ def parse_dhcp_response(self, response_timeout): # pylint: disable=too-many-bran xid = _BUFF[4:8] if bytes(xid) < self._initial_xid: + print("f") return 0, 0 self.local_ip = _BUFF[16:20] diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py index a448548..083e10d 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k_dns.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_dns.py @@ -95,7 +95,7 @@ def gethostbyname(self, hostname): # wait and retry 3 times for a response retries = 0 addr = -1 - while (retries < 3) and (addr == -1): + while (retries < 5) and (addr == -1): addr = self._parse_dns_response() if addr == -1 and self._debug: print("* DNS ERROR: Failed to resolve DNS response, retrying...") From 74e6d7bc70733476be6694ec9afd48913e221a84 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 5 Mar 2020 16:04:03 -0500 Subject: [PATCH 36/41] prune extra from get_socket, just allocate a socket from the chipset --- adafruit_wiznet5k/adafruit_wiznet5k.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index d6b3cf2..142b542 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -219,7 +219,6 @@ def set_dhcp(self, response_timeout=1): _subnet_mask, _gw_addr, self._dns)) - self._src_port = 0 return 0 return -1 @@ -496,14 +495,10 @@ def socket_connect(self, socket_num, dest, port, conn_mode=SNMR_TCP): print("*** Connecting: Socket# {}, conn_mode: {}".format(socket_num, conn_mode)) # initialize a socket and set the mode - res = self.socket_open(socket_num, port, conn_mode=conn_mode) + res = self.socket_open(socket_num, dest, port, conn_mode=conn_mode) if res == 1: raise RuntimeError('Failed to initalize a connection with the socket.') - - self._write_sndipr(socket_num, dest) - self._write_sndport(socket_num, port) - if conn_mode == SNMR_TCP: # TCP client - connect socket self._send_socket_cmd(socket_num, CMD_SOCK_CONNECT) @@ -544,7 +539,7 @@ def get_socket(self, sockets): print("Allocated socket #{}".format(sock)) return sock - def socket_open(self, socket_num, port, conn_mode=SNMR_TCP): + def socket_open(self, socket_num, dest, port, conn_mode=SNMR_TCP): """Opens a socket to a destination IP address or hostname. By default, we use 'conn_mode'=SNMR_TCP but we may also use SNMR_UDP. """ @@ -553,19 +548,23 @@ def socket_open(self, socket_num, port, conn_mode=SNMR_TCP): print("*** Opening socket %d"%socket_num) if self._read_snsr(socket_num)[0] == SNSR_SOCK_CLOSED: if self._debug: - print("w5k socket begin, protocol={}, port={}".format(conn_mode, port)) + print("w5k socket begin, protocol={}, port={}, ip={}".format(conn_mode, port, + self.pretty_ip(dest))) time.sleep(0.00025) self._write_snmr(socket_num, conn_mode) self._write_snir(socket_num, 0xFF) - if port > 0: - # write to defined port - self._write_sock_port(socket_num, port) + if self._src_port > 0: + # write to socket source port + self._write_sock_port(socket_num, self._src_port) else: - # if source port is not set, set the local port number self._write_sock_port(socket_num, randint(49152, 65535)) + # set socket destination IP and port + self._write_sndipr(socket_num, dest) + self._write_sndport(socket_num, port) + # open socket self._write_sncr(socket_num, CMD_SOCK_OPEN) self._read_sncr(socket_num) @@ -581,7 +580,6 @@ def socket_close(self, socket_num): print("*** Closing socket #%d" % socket_num) self._write_sncr(socket_num, CMD_SOCK_CLOSE) self._read_sncr(socket_num) - self._src_port = 0 def socket_disconnect(self, socket_num): """Disconnect a TCP connection.""" From 4030144fbf65f384e0f7991449bdf0f14daaf5d8 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 5 Mar 2020 16:14:35 -0500 Subject: [PATCH 37/41] continue separating functionality: socket_open should only issue OPEN, not set anything --- adafruit_wiznet5k/adafruit_wiznet5k.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index 142b542..581368a 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -219,6 +219,7 @@ def set_dhcp(self, response_timeout=1): _subnet_mask, _gw_addr, self._dns)) + self._src_port = 0 return 0 return -1 @@ -492,16 +493,19 @@ def socket_connect(self, socket_num, dest, port, conn_mode=SNMR_TCP): """ assert self.link_status, "Ethernet cable disconnected!" if self._debug: - print("*** Connecting: Socket# {}, conn_mode: {}".format(socket_num, conn_mode)) - + print("* w5k socket connect, protocol={}, port={}, ip={}".format(conn_mode, port, + self.pretty_ip(dest))) # initialize a socket and set the mode - res = self.socket_open(socket_num, dest, port, conn_mode=conn_mode) + res = self.socket_open(socket_num, conn_mode=conn_mode) if res == 1: raise RuntimeError('Failed to initalize a connection with the socket.') + # set socket destination IP and port + self._write_sndipr(socket_num, dest) + self._write_sndport(socket_num, port) + self._send_socket_cmd(socket_num, CMD_SOCK_CONNECT) + if conn_mode == SNMR_TCP: - # TCP client - connect socket - self._send_socket_cmd(socket_num, CMD_SOCK_CONNECT) # wait for tcp connection establishment while self.socket_status(socket_num)[0] != SNSR_SOCK_ESTABLISHED: time.sleep(0.001) @@ -539,8 +543,8 @@ def get_socket(self, sockets): print("Allocated socket #{}".format(sock)) return sock - def socket_open(self, socket_num, dest, port, conn_mode=SNMR_TCP): - """Opens a socket to a destination IP address or hostname. By default, we use + def socket_open(self, socket_num, conn_mode=SNMR_TCP): + """Opens a TCP or UDP socket. By default, we use 'conn_mode'=SNMR_TCP but we may also use SNMR_UDP. """ assert self.link_status, "Ethernet cable disconnected!" @@ -548,8 +552,7 @@ def socket_open(self, socket_num, dest, port, conn_mode=SNMR_TCP): print("*** Opening socket %d"%socket_num) if self._read_snsr(socket_num)[0] == SNSR_SOCK_CLOSED: if self._debug: - print("w5k socket begin, protocol={}, port={}, ip={}".format(conn_mode, port, - self.pretty_ip(dest))) + print("* Opening W5k Socket, protocol={}".format(conn_mode)) time.sleep(0.00025) self._write_snmr(socket_num, conn_mode) @@ -561,10 +564,6 @@ def socket_open(self, socket_num, dest, port, conn_mode=SNMR_TCP): else: self._write_sock_port(socket_num, randint(49152, 65535)) - # set socket destination IP and port - self._write_sndipr(socket_num, dest) - self._write_sndport(socket_num, port) - # open socket self._write_sncr(socket_num, CMD_SOCK_OPEN) self._read_sncr(socket_num) From dab3551282cdcad18b48a463b099d6b7c33245b1 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 5 Mar 2020 16:16:25 -0500 Subject: [PATCH 38/41] fix indentation for lintin --- adafruit_wiznet5k/adafruit_wiznet5k.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k.py b/adafruit_wiznet5k/adafruit_wiznet5k.py index 581368a..2bfbd5d 100755 --- a/adafruit_wiznet5k/adafruit_wiznet5k.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k.py @@ -493,7 +493,7 @@ def socket_connect(self, socket_num, dest, port, conn_mode=SNMR_TCP): """ assert self.link_status, "Ethernet cable disconnected!" if self._debug: - print("* w5k socket connect, protocol={}, port={}, ip={}".format(conn_mode, port, + print("* w5k socket connect, protocol={}, port={}, ip={}".format(conn_mode, port, self.pretty_ip(dest))) # initialize a socket and set the mode res = self.socket_open(socket_num, conn_mode=conn_mode) From 55be280919dcd90039556d4a79576ffc292384d2 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 6 Mar 2020 12:11:43 -0500 Subject: [PATCH 39/41] add Adafruit IO example! --- examples/wiznet5k_aio_post.py | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 examples/wiznet5k_aio_post.py diff --git a/examples/wiznet5k_aio_post.py b/examples/wiznet5k_aio_post.py new file mode 100644 index 0000000..eb6f0a1 --- /dev/null +++ b/examples/wiznet5k_aio_post.py @@ -0,0 +1,39 @@ +import time +import board +import busio +from digitalio import DigitalInOut +from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K +import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket +import adafruit_requests as requests + +# Get Adafruit.io details from a secrets.py file +try: + from secrets import secrets +except ImportError: + print("WiFi secrets are kept in secrets.py, please add them there!") + raise + +cs = DigitalInOut(board.D10) +spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) + +# Initialize ethernet interface with DHCP +eth = WIZNET5K(spi_bus, cs) +requests.set_socket(socket, eth) + +counter = 0 + +while True: + print("Posting data...", end='') + data = counter + feed = 'test' + payload = {'value':data} + response = requests.post( + "http://io.adafruit.com/api/v2/"+secrets['aio_username']+"/feeds/"+feed+"/data", + json=payload, + headers={"X-AIO-KEY":secrets['aio_key']}) + print(response.json()) + response.close() + counter = counter + 1 + print("OK") + response = None + time.sleep(15) From 30569bd08f95f74f9e694b5cf707a917fdb896b6 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 6 Mar 2020 13:12:02 -0500 Subject: [PATCH 40/41] add example for manually setting the network configuration --- .../wiznet5k_simpletest_manual_network.py | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 examples/wiznet5k_simpletest_manual_network.py diff --git a/examples/wiznet5k_simpletest_manual_network.py b/examples/wiznet5k_simpletest_manual_network.py new file mode 100644 index 0000000..3da8b4a --- /dev/null +++ b/examples/wiznet5k_simpletest_manual_network.py @@ -0,0 +1,43 @@ +import board +import busio +import digitalio +import adafruit_requests as requests +from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K +import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket + +TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html" + +# Setup your network configuration below +IP_ADDRESS = (192, 168, 10, 1) +SUBNET_MASK = (255, 255, 0, 0) +GATEWAY_ADDRESS = (192, 168, 0, 1) +DNS_SERVER = (8, 8, 8, 8) + +print("Wiznet5k WebClient Test (no DHCP)") + +cs = digitalio.DigitalInOut(board.D10) +spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) + +# Initialize ethernet interface without DHCP +eth = WIZNET5K(spi_bus, cs, is_dhcp=False) + +# Set network configuration +eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER) + +# Initialize a requests object with a socket and ethernet interface +requests.set_socket(socket, eth) + +print("Chip Version:", eth.chip) +print("MAC Address:", [hex(i) for i in eth.mac_address]) +print("My IP address is:", eth.pretty_ip(eth.ip_address)) +print("IP lookup adafruit.com: %s" %eth.pretty_ip(eth.get_host_by_name("adafruit.com"))) + +#eth._debug = True +print("Fetching text from", TEXT_URL) +r = requests.get(TEXT_URL) +print('-'*40) +print(r.text) +print('-'*40) +r.close() + +print() \ No newline at end of file From f510eb2c590e81c71c2550641c9d0dea7aeb2e70 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 6 Mar 2020 13:14:44 -0500 Subject: [PATCH 41/41] fix newline --- examples/wiznet5k_simpletest_manual_network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wiznet5k_simpletest_manual_network.py b/examples/wiznet5k_simpletest_manual_network.py index 3da8b4a..9b5dfe3 100644 --- a/examples/wiznet5k_simpletest_manual_network.py +++ b/examples/wiznet5k_simpletest_manual_network.py @@ -40,4 +40,4 @@ print('-'*40) r.close() -print() \ No newline at end of file +print()