7 #ifndef ZRTOS_VFS_MODULE_DHCP_H 8 #define ZRTOS_VFS_MODULE_DHCP_H 15 #define ZRTOS_VFS_MODULE_DHCP__FLAGSBROADCAST 0x8000 18 #define ZRTOS_VFS_MODULE_DHCP__SERVER_PORT 67 19 #define ZRTOS_VFS_MODULE_DHCP__CLIENT_PORT 68 21 #define ZRTOS_VFS_MODULE_DHCP__HTYPE10MB 1 22 #define ZRTOS_VFS_MODULE_DHCP__HTYPE100MB 2 24 #define ZRTOS_VFS_MODULE_DHCP__HLENETHERNET 6 25 #define ZRTOS_VFS_MODULE_DHCP__HOPS 0 26 #define ZRTOS_VFS_MODULE_DHCP__SECS 0 28 #define ZRTOS_VFS_MODULE_DHCP__MAGIC_COOKIE 0x63825363 29 #define ZRTOS_VFS_MODULE_DHCP__MAX_DHCP_OPT 16 31 #define ZRTOS_VFS_MODULE_DHCP__HOST_NAME "WIZnet" 32 #define ZRTOS_VFS_MODULE_DHCP__DEFAULT_LEASE (900) //default lease time in seconds 158 zrtos_vfs_module_network_ip_t
ip;
165 int DhcpClass::beginWithDHCP(
uint8_t *mac,
unsigned long timeout,
unsigned long responseTimeout)
172 _responseTimeout = responseTimeout;
175 memset(_dhcpMacAddr, 0, 6);
178 memcpy((
void*)_dhcpMacAddr, (
void*)mac, 6);
179 _dhcp_state = STATE_DHCP_START;
180 return request_DHCP_lease();
183 void DhcpClass::reset_DHCP_lease(){
185 memset(_dhcpLocalIp, 0, 20);
189 int DhcpClass::request_DHCP_lease(){
193 _dhcpTransactionId = random(1UL, 2000UL);
194 _dhcpInitialTransactionId = _dhcpTransactionId;
196 _dhcpUdpSocket.stop();
197 if (_dhcpUdpSocket.begin(DHCP_CLIENT_PORT) == 0)
207 unsigned long startTime = millis();
209 while(_dhcp_state != STATE_DHCP_LEASED)
211 if(_dhcp_state == STATE_DHCP_START)
213 _dhcpTransactionId++;
215 send_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));
216 _dhcp_state = STATE_DHCP_DISCOVER;
218 else if(_dhcp_state == STATE_DHCP_REREQUEST){
219 _dhcpTransactionId++;
220 send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000));
221 _dhcp_state = STATE_DHCP_REQUEST;
223 else if(_dhcp_state == STATE_DHCP_DISCOVER)
226 messageType = parseDHCPResponse(_responseTimeout, respId);
227 if(messageType == DHCP_OFFER)
231 _dhcpTransactionId = respId;
232 send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
233 _dhcp_state = STATE_DHCP_REQUEST;
236 else if(_dhcp_state == STATE_DHCP_REQUEST)
239 messageType = parseDHCPResponse(_responseTimeout, respId);
240 if(messageType == DHCP_ACK)
242 _dhcp_state = STATE_DHCP_LEASED;
245 if(_dhcpLeaseTime == 0){
246 _dhcpLeaseTime = DEFAULT_LEASE;
251 _dhcpT1 = _dhcpLeaseTime >> 1;
255 _dhcpT2 = _dhcpT1 << 1;
257 _renewInSec = _dhcpT1;
258 _rebindInSec = _dhcpT2;
260 else if(messageType == DHCP_NAK)
261 _dhcp_state = STATE_DHCP_START;
264 if(messageType == 255)
267 _dhcp_state = STATE_DHCP_START;
270 if(result != 1 && ((millis() - startTime) > _timeout))
275 _dhcpUdpSocket.stop();
276 _dhcpTransactionId++;
281 void DhcpClass::presend_DHCP()
285 void DhcpClass::send_DHCP_MESSAGE(
uint8_t messageType, uint16_t secondsElapsed)
288 memset(buffer, 0, 32);
289 IPAddress dest_addr( 255, 255, 255, 255 );
291 if (-1 == _dhcpUdpSocket.beginPacket(dest_addr, DHCP_SERVER_PORT))
297 buffer[0] = DHCP_BOOTREQUEST;
298 buffer[1] = DHCP_HTYPE10MB;
299 buffer[2] = DHCP_HLENETHERNET;
300 buffer[3] = DHCP_HOPS;
303 unsigned long xid = htonl(_dhcpTransactionId);
304 memcpy(buffer + 4, &(xid), 4);
307 buffer[8] = ((secondsElapsed & 0xff00) >> 8);
308 buffer[9] = (secondsElapsed & 0x00ff);
311 unsigned short flags = htons(DHCP_FLAGSBROADCAST);
312 memcpy(buffer + 10, &(flags), 2);
320 _dhcpUdpSocket.write(buffer, 28);
322 memset(buffer, 0, 32);
324 memcpy(buffer, _dhcpMacAddr, 6);
327 _dhcpUdpSocket.write(buffer, 16);
329 memset(buffer, 0, 32);
334 for(
int i = 0; i < 6; i++) {
335 _dhcpUdpSocket.write(buffer, 32);
339 buffer[0] = (
uint8_t)((MAGIC_COOKIE >> 24)& 0xFF);
340 buffer[1] = (
uint8_t)((MAGIC_COOKIE >> 16)& 0xFF);
341 buffer[2] = (
uint8_t)((MAGIC_COOKIE >> 8)& 0xFF);
342 buffer[3] = (
uint8_t)(MAGIC_COOKIE& 0xFF);
345 buffer[4] = dhcpMessageType;
347 buffer[6] = messageType;
350 buffer[7] = dhcpClientIdentifier;
353 memcpy(buffer + 10, _dhcpMacAddr, 6);
356 buffer[16] = hostName;
357 buffer[17] = strlen(HOST_NAME) + 6;
358 strcpy((
char*)&(buffer[18]), HOST_NAME);
360 printByte((
char*)&(buffer[24]), _dhcpMacAddr[3]);
361 printByte((
char*)&(buffer[26]), _dhcpMacAddr[4]);
362 printByte((
char*)&(buffer[28]), _dhcpMacAddr[5]);
365 _dhcpUdpSocket.write(buffer, 30);
367 if(messageType == DHCP_REQUEST)
369 buffer[0] = dhcpRequestedIPaddr;
371 buffer[2] = _dhcpLocalIp[0];
372 buffer[3] = _dhcpLocalIp[1];
373 buffer[4] = _dhcpLocalIp[2];
374 buffer[5] = _dhcpLocalIp[3];
376 buffer[6] = dhcpServerIdentifier;
378 buffer[8] = _dhcpDhcpServerIp[0];
379 buffer[9] = _dhcpDhcpServerIp[1];
380 buffer[10] = _dhcpDhcpServerIp[2];
381 buffer[11] = _dhcpDhcpServerIp[3];
384 _dhcpUdpSocket.write(buffer, 12);
387 buffer[0] = dhcpParamRequest;
389 buffer[2] = subnetMask;
390 buffer[3] = routersOnSubnet;
392 buffer[5] = domainName;
393 buffer[6] = dhcpT1value;
394 buffer[7] = dhcpT2value;
395 buffer[8] = endOption;
398 _dhcpUdpSocket.write(buffer, 9);
400 _dhcpUdpSocket.endPacket();
403 uint8_t DhcpClass::parseDHCPResponse(
unsigned long responseTimeout, uint32_t& transactionId)
408 unsigned long startTime = millis();
410 while(_dhcpUdpSocket.parsePacket() <= 0)
412 if((millis() - startTime) > responseTimeout)
419 RIP_MSG_FIXED fixedMsg;
420 _dhcpUdpSocket.read((
uint8_t*)&fixedMsg,
sizeof(RIP_MSG_FIXED));
422 if(fixedMsg.op == DHCP_BOOTREPLY && _dhcpUdpSocket.remotePort() == DHCP_SERVER_PORT)
424 transactionId = ntohl(fixedMsg.xid);
425 if(memcmp(fixedMsg.chaddr, _dhcpMacAddr, 6) != 0 || (transactionId < _dhcpInitialTransactionId) || (transactionId > _dhcpTransactionId))
428 _dhcpUdpSocket.flush();
432 memcpy(_dhcpLocalIp, fixedMsg.yiaddr, 4);
437 for (
int i =0; i < (240 - (int)
sizeof(RIP_MSG_FIXED)); i++)
439 _dhcpUdpSocket.read();
442 while (_dhcpUdpSocket.available() > 0)
444 switch (_dhcpUdpSocket.read())
452 case dhcpMessageType :
453 opt_len = _dhcpUdpSocket.read();
454 type = _dhcpUdpSocket.read();
458 opt_len = _dhcpUdpSocket.read();
459 _dhcpUdpSocket.read(_dhcpSubnetMask, 4);
462 case routersOnSubnet :
463 opt_len = _dhcpUdpSocket.read();
464 _dhcpUdpSocket.read(_dhcpGatewayIp, 4);
465 for (
int i = 0; i < opt_len-4; i++)
467 _dhcpUdpSocket.read();
472 opt_len = _dhcpUdpSocket.read();
473 _dhcpUdpSocket.read(_dhcpDnsServerIp, 4);
474 for (
int i = 0; i < opt_len-4; i++)
476 _dhcpUdpSocket.read();
480 case dhcpServerIdentifier :
481 opt_len = _dhcpUdpSocket.read();
482 if( *((uint32_t*)_dhcpDhcpServerIp) == 0 ||
483 IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP() )
485 _dhcpUdpSocket.read(_dhcpDhcpServerIp,
sizeof(_dhcpDhcpServerIp));
492 _dhcpUdpSocket.read();
498 opt_len = _dhcpUdpSocket.read();
499 _dhcpUdpSocket.read((
uint8_t*)&_dhcpT1,
sizeof(_dhcpT1));
500 _dhcpT1 = ntohl(_dhcpT1);
504 opt_len = _dhcpUdpSocket.read();
505 _dhcpUdpSocket.read((
uint8_t*)&_dhcpT2,
sizeof(_dhcpT2));
506 _dhcpT2 = ntohl(_dhcpT2);
509 case dhcpIPaddrLeaseTime :
510 opt_len = _dhcpUdpSocket.read();
511 _dhcpUdpSocket.read((
uint8_t*)&_dhcpLeaseTime,
sizeof(_dhcpLeaseTime));
512 _dhcpLeaseTime = ntohl(_dhcpLeaseTime);
513 _renewInSec = _dhcpLeaseTime;
517 opt_len = _dhcpUdpSocket.read();
521 _dhcpUdpSocket.read();
529 _dhcpUdpSocket.flush();
543 int DhcpClass::checkLease(){
545 unsigned long now = millis();
546 signed long snow = (long)now;
547 int rc=DHCP_CHECK_NONE;
548 if (_lastCheck != 0){
551 factor = snow - (long)_secTimeout;
555 _secTimeout = snow + 1000 - factor % 1000;
557 factor = factor / 1000 +1;
563 if(_renewInSec < factor*2 )
566 _renewInSec -= factor;
568 if(_rebindInSec < factor*2 )
571 _rebindInSec -= factor;
575 if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <=0){
576 _dhcp_state = STATE_DHCP_REREQUEST;
577 rc = 1 + request_DHCP_lease();
581 if( (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <=0){
583 _dhcp_state = STATE_DHCP_START;
585 rc = 3 + request_DHCP_lease();
589 _secTimeout = snow + 1000;
zrtos_vfs_module_dhcp_state_t state
zrtos_vfs_module_dhcp_state_t
zrtos_vfs_module_network_subnet_mask_t subnet_mask
zrtos_vfs_module_dhcp_message_type_t
zrtos_vfs_module_dhcp_option_t
zrtos_vfs_module_network_ip_t gateway
zrtos_vfs_module_dhcp_error_t
zrtos_vfs_module_network_ip_t ip
zrtos_vfs_module_dhcp_message_op_t
zrtos_vfs_module_network_ip_t dns_server