Skip to content

Commit 236a3e9

Browse files
authored
Merge pull request #20 from xorbit/master
DHCP timeout and hostname fix, make both user settable
2 parents 07a39d4 + 0411aac commit 236a3e9

File tree

3 files changed

+57
-37
lines changed

3 files changed

+57
-37
lines changed

adafruit_wiznet5k/adafruit_wiznet5k.py

+17-6
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,10 @@ class WIZNET5K: # pylint: disable=too-many-public-methods
142142
:param ~busio.SPI spi_bus: The SPI bus the Wiznet module is connected to.
143143
:param ~digitalio.DigitalInOut cs: Chip select pin.
144144
:param ~digitalio.DigitalInOut rst: Optional reset pin.
145-
:param bool dhcp: Whether to start DHCP automatically or not.
146-
:param str mac: The Wiznet's MAC Address.
145+
:param bool is_dhcp: Whether to start DHCP automatically or not.
146+
:param list mac: The Wiznet's MAC Address.
147+
:param str hostname: The desired hostname, with optional {} to fill in MAC.
148+
:param int dhcp_timeout: Timeout in seconds for DHCP response.
147149
:param bool debug: Enable debugging output.
148150
149151
"""
@@ -154,7 +156,15 @@ class WIZNET5K: # pylint: disable=too-many-public-methods
154156

155157
# pylint: disable=too-many-arguments
156158
def __init__(
157-
self, spi_bus, cs, reset=None, is_dhcp=True, mac=DEFAULT_MAC, debug=False
159+
self,
160+
spi_bus,
161+
cs,
162+
reset=None,
163+
is_dhcp=True,
164+
mac=DEFAULT_MAC,
165+
hostname=None,
166+
dhcp_timeout=3,
167+
debug=False,
158168
):
159169
self._debug = debug
160170
self._chip_type = None
@@ -182,13 +192,14 @@ def __init__(
182192
self._dns = 0
183193
# Set DHCP
184194
if is_dhcp:
185-
ret = self.set_dhcp()
195+
ret = self.set_dhcp(hostname, dhcp_timeout)
186196
assert ret == 0, "Failed to configure DHCP Server!"
187197

188-
def set_dhcp(self, response_timeout=1):
198+
def set_dhcp(self, hostname=None, response_timeout=3):
189199
"""Initializes the DHCP client and attempts to retrieve
190200
and set network configuration from the DHCP server.
191201
Returns True if DHCP configured, False otherwise.
202+
:param str hostname: The desired hostname, with optional {} to fill in MAC.
192203
:param int response_timeout: Time to wait for server to return packet, in seconds.
193204
194205
"""
@@ -197,7 +208,7 @@ def set_dhcp(self, response_timeout=1):
197208
self._src_port = 68
198209
# Return IP assigned by DHCP
199210
_dhcp_client = dhcp.DHCP(
200-
self, self.mac_address, response_timeout, debug=self._debug
211+
self, self.mac_address, hostname, response_timeout, debug=self._debug
201212
)
202213
ret = _dhcp_client.request_dhcp_lease()
203214
if ret == 1:

adafruit_wiznet5k/adafruit_wiznet5k_dhcp.py

+38-29
Original file line numberDiff line numberDiff line change
@@ -95,23 +95,24 @@ class DHCP:
9595
"""W5k DHCP Client implementation.
9696
:param eth: Wiznet 5k object
9797
:param list mac_address: Hardware MAC.
98-
:param int timeout: Packet parsing timeout.
99-
:param int timeout_response: DHCP Response timeout.
98+
:param str hostname: The desired hostname, with optional {} to fill in MAC.
99+
:param int response_timeout: DHCP Response timeout.
100100
:param bool debug: Enable debugging output.
101101
102102
"""
103103

104104
# pylint: disable=too-many-arguments, too-many-instance-attributes, invalid-name
105-
def __init__(self, eth, mac_address, timeout=1, timeout_response=1, debug=False):
105+
def __init__(
106+
self, eth, mac_address, hostname=None, response_timeout=3, debug=False
107+
):
106108
self._debug = debug
107-
self._timeout = timeout
108-
self._response_timeout = timeout_response
109+
self._response_timeout = response_timeout
109110
self._mac_address = mac_address
110111

111112
# Initalize a new UDP socket for DHCP
112113
socket.set_interface(eth)
113114
self._sock = socket.socket(type=socket.SOCK_DGRAM)
114-
self._sock.settimeout(timeout)
115+
self._sock.settimeout(response_timeout)
115116

116117
# DHCP state machine
117118
self._dhcp_state = STATE_DHCP_START
@@ -124,6 +125,7 @@ def __init__(self, eth, mac_address, timeout=1, timeout_response=1, debug=False)
124125
self.gateway_ip = 0
125126
self.subnet_mask = 0
126127
self.dns_server_ip = 0
128+
127129
# Lease configuration
128130
self._lease_time = 0
129131
self._last_check_lease_ms = 0
@@ -132,6 +134,12 @@ def __init__(self, eth, mac_address, timeout=1, timeout_response=1, debug=False)
132134
self._t1 = 0
133135
self._t2 = 0
134136

137+
# Host name
138+
mac_string = "".join("{:02X}".format(o) for o in mac_address)
139+
self._hostname = bytes(
140+
(hostname or "WIZnet{}").split(".")[0].format(mac_string)[:42], "utf-8"
141+
)
142+
135143
def send_dhcp_message(self, state, time_elapsed):
136144
"""Assemble and send a DHCP message packet to a socket.
137145
:param int state: DHCP Message state.
@@ -193,38 +201,37 @@ def send_dhcp_message(self, state, time_elapsed):
193201

194202
# Option - Host Name
195203
_BUFF[252] = 12
196-
_BUFF[253] = len(b"Wiznet") + 6
197-
_BUFF[254:260] = b"WIZnet"
198-
199-
for mac in range(0, 5):
200-
_BUFF[260 + mac] = self._mac_address[mac]
204+
hostname_len = len(self._hostname)
205+
after_hostname = 254 + hostname_len
206+
_BUFF[253] = hostname_len
207+
_BUFF[254:after_hostname] = self._hostname
201208

202209
if state == DHCP_REQUEST:
203210
# Set the parsed local IP addr
204-
_BUFF[266] = 50
205-
_BUFF[267] = 0x04
211+
_BUFF[after_hostname] = 50
212+
_BUFF[after_hostname + 1] = 0x04
206213

207-
_BUFF[268:272] = self.local_ip
214+
_BUFF[after_hostname + 2 : after_hostname + 6] = self.local_ip
208215
# Set the parsed dhcp server ip addr
209-
_BUFF[272] = 54
210-
_BUFF[273] = 0x04
211-
_BUFF[274:278] = self.dhcp_server_ip
216+
_BUFF[after_hostname + 6] = 54
217+
_BUFF[after_hostname + 7] = 0x04
218+
_BUFF[after_hostname + 8 : after_hostname + 12] = self.dhcp_server_ip
212219

213-
_BUFF[278] = 55
214-
_BUFF[279] = 0x06
220+
_BUFF[after_hostname + 12] = 55
221+
_BUFF[after_hostname + 13] = 0x06
215222
# subnet mask
216-
_BUFF[280] = 1
223+
_BUFF[after_hostname + 14] = 1
217224
# routers on subnet
218-
_BUFF[281] = 3
225+
_BUFF[after_hostname + 15] = 3
219226
# DNS
220-
_BUFF[282] = 6
227+
_BUFF[after_hostname + 16] = 6
221228
# domain name
222-
_BUFF[283] = 15
229+
_BUFF[after_hostname + 17] = 15
223230
# renewal (T1) value
224-
_BUFF[284] = 58
231+
_BUFF[after_hostname + 18] = 58
225232
# rebinding (T2) value
226-
_BUFF[285] = 59
227-
_BUFF[286] = 255
233+
_BUFF[after_hostname + 19] = 59
234+
_BUFF[after_hostname + 20] = 255
228235

229236
# Send DHCP packet
230237
self._sock.send(_BUFF)
@@ -373,7 +380,7 @@ def request_dhcp_lease(
373380
elif self._dhcp_state == STATE_DHCP_DISCOVER:
374381
if self._debug:
375382
print("* DHCP: Parsing OFFER")
376-
msg_type, xid = self.parse_dhcp_response(self._timeout)
383+
msg_type, xid = self.parse_dhcp_response(self._response_timeout)
377384
if msg_type == DHCP_OFFER:
378385
# use the _transaction_id the offer returned,
379386
# rather than the current one
@@ -389,7 +396,7 @@ def request_dhcp_lease(
389396
elif STATE_DHCP_REQUEST:
390397
if self._debug:
391398
print("* DHCP: Parsing ACK")
392-
msg_type, xid = self.parse_dhcp_response(self._timeout)
399+
msg_type, xid = self.parse_dhcp_response(self._response_timeout)
393400
if msg_type == DHCP_ACK:
394401
self._dhcp_state = STATE_DHCP_LEASED
395402
result = 1
@@ -412,7 +419,9 @@ def request_dhcp_lease(
412419
msg_type = 0
413420
self._dhcp_state = STATE_DHCP_START
414421

415-
if result != 1 and ((time.monotonic() - start_time > self._timeout)):
422+
if result != 1 and (
423+
(time.monotonic() - start_time > self._response_timeout)
424+
):
416425
break
417426

418427
self._transaction_id += 1

docs/conf.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@
147147
"AdafruitWiznet5k Library Documentation",
148148
author,
149149
"manual",
150-
),
150+
)
151151
]
152152

153153
# -- Options for manual page output ---------------------------------------
@@ -178,5 +178,5 @@
178178
"AdafruitWiznet5kLibrary",
179179
"One line description of project.",
180180
"Miscellaneous",
181-
),
181+
)
182182
]

0 commit comments

Comments
 (0)