WIZNet W5500 with additional enhancements

Fork of WIZnetInterface by WIZnet

Files at this revision

API Documentation at this revision

Comitter:
Helmut Tschemernjak
Date:
Tue Oct 10 20:56:13 2017 +0200
Parent:
34:7d44648ec5f2
Child:
36:0ba2e8d5274a
Commit message:
Added support for DHCP lease time and domain name
Enhance DHCP code to use opcode defines to make it easier to
understand and maintain.

Changed in this revision

EthernetInterface.cpp Show annotated file Show diff for this revision Revisions of this file
EthernetInterface.h Show annotated file Show diff for this revision Revisions of this file
Socket/DHCPClient.cpp Show annotated file Show diff for this revision Revisions of this file
Socket/DHCPClient.h Show annotated file Show diff for this revision Revisions of this file
Socket/Endpoint.cpp Show annotated file Show diff for this revision Revisions of this file
arch/ext/W5500.cpp Show annotated file Show diff for this revision Revisions of this file
arch/ext/W5500.h Show annotated file Show diff for this revision Revisions of this file
--- a/EthernetInterface.cpp	Mon Oct 09 19:58:19 2017 +0200
+++ b/EthernetInterface.cpp	Tue Oct 10 20:56:13 2017 +0200
@@ -24,15 +24,25 @@
         WIZnet_Chip(mosi, miso, sclk, cs, reset)
 {
     ip_set = false;
+    domainName = NULL;
+    leaseStart = 0;
 }
 
 EthernetInterface::EthernetInterface(SPI* spi, PinName cs, PinName reset) :
         WIZnet_Chip(spi, cs, reset)
 {
     ip_set = false;
+    domainName = NULL;
+    leaseStart = 0;
 }
 #endif
 
+EthernetInterface::~EthernetInterface()
+{
+    if (domainName)
+        free(domainName);
+}
+
 int EthernetInterface::init()
 {
     dhcp = true;
@@ -83,7 +93,6 @@
             return r;
         }
     }
-    
     if (WIZnet_Chip::setip() == false) return -1;
     return 0;
 }
@@ -151,6 +160,7 @@
     
 }
 
+
 int EthernetInterface::IPrenew(int timeout_ms)
 {
     DHCPClient dhcp;
@@ -159,10 +169,24 @@
         return -1;
     }
 //    printf("Connected, IP: %d.%d.%d.%d\n", dhcp.yiaddr[0], dhcp.yiaddr[1], dhcp.yiaddr[2], dhcp.yiaddr[3]);
+    /*
+     * Sync DHCP response variables
+     */
     ip      = (dhcp.yiaddr[0] <<24) | (dhcp.yiaddr[1] <<16) | (dhcp.yiaddr[2] <<8) | dhcp.yiaddr[3];
     gateway = (dhcp.gateway[0]<<24) | (dhcp.gateway[1]<<16) | (dhcp.gateway[2]<<8) | dhcp.gateway[3];
     netmask = (dhcp.netmask[0]<<24) | (dhcp.netmask[1]<<16) | (dhcp.netmask[2]<<8) | dhcp.netmask[3];
     dnsaddr = (dhcp.dnsaddr[0]<<24) | (dhcp.dnsaddr[1]<<16) | (dhcp.dnsaddr[2]<<8) | dhcp.dnsaddr[3];
+    timesrv = (dhcp.timesrv[0]<<24) | (dhcp.timesrv[1]<<16) | (dhcp.timesrv[2]<<8) | dhcp.timesrv[3];
+    leaseTime = (dhcp.leaseTime[0]<<24) | (dhcp.leaseTime[1]<<16) | (dhcp.leaseTime[2]<<8) | dhcp.leaseTime[3];
+    leaseStart = time(NULL);
+    if (domainName) {
+        free(domainName);
+    	domainName = NULL;
+    }
+    if (dhcp.domainName) {
+        domainName = dhcp.domainName;
+        dhcp.domainName = NULL;
+    }
     return 0;
 }
 
--- a/EthernetInterface.h	Mon Oct 09 19:58:19 2017 +0200
+++ b/EthernetInterface.h	Tue Oct 10 20:56:13 2017 +0200
@@ -37,6 +37,7 @@
     */
     EthernetInterface(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset);
     EthernetInterface(SPI* spi, PinName cs, PinName reset);
+    ~EthernetInterface();
 #endif
 
   /** Initialize the interface with DHCP.
@@ -77,7 +78,10 @@
   char* getGateway();
   char* getDNSServer();
   char* getMACAddress();
-
+  int getLeaseTime() { return leaseTime; };
+  int getLeaseStart() { return leaseStart; };
+  char *getDomainName(void) { return domainName; };
+    
   int IPrenew(int timeout_ms = 15*1000);
     
 private:
@@ -87,6 +91,8 @@
     char dns_string[20];
     char mac_string[20];
     bool ip_set;
+    uint32_t leaseStart;
+    char *domainName;
 };
 
 #include "TCPSocketConnection.h"
--- a/Socket/DHCPClient.cpp	Mon Oct 09 19:58:19 2017 +0200
+++ b/Socket/DHCPClient.cpp	Tue Oct 10 20:56:13 2017 +0200
@@ -25,10 +25,10 @@
     fill_buf(20, 0x00);
     add_buf(chaddr, 6);
     fill_buf(10+192, 0x00);
-    const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie
-                               53,1,DHCPDISCOVER,   // DHCP option 53: DHCP Discover
-                               55,4,1,3,15,6,
-                               255}; 
+    const uint8_t options[] = {0x63,0x82,0x53,0x63, // DHCP_MAGIC_COOKIE
+        OPT_DHCP_MESSAGE, 1, DHCPDISCOVER,   // // DHCP message, len, discover
+        OPT_PARAMETER_REQ, 5, OPT_SUBNET_MASK, OPT_ROUTER, OPT_TIME_SERVER, OPT_DOMAIN_NAME, OPT_DNS,
+        OPT_END};
     add_buf((uint8_t*)options, sizeof(options));
     return m_pos;
 }
@@ -44,24 +44,30 @@
     fill_buf(4, 0x00); // giaddr
     add_buf(chaddr, 6);
     fill_buf(10+192, 0x00);
-    const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie
-                               53,1,DHCPREQUEST,    // DHCP option 53: DHCP Request
-                               55,4,1,3,15,6,       // DHCP option 55:
-                               };
+    const uint8_t options[] = {0x63,0x82,0x53,0x63, // DHCP_MAGIC_COOKIE
+        OPT_DHCP_MESSAGE,1, DHCPREQUEST,    // DHCP message, len, request
+        OPT_PARAMETER_REQ, 5, OPT_SUBNET_MASK, OPT_ROUTER, OPT_TIME_SERVER, OPT_DOMAIN_NAME, OPT_DNS };
     add_buf((uint8_t*)options, sizeof(options));
-    add_option(50, yiaddr, 4);
-    add_option(54, siaddr, 4);
-    add_option(255);
+    add_option(OPT_IP_ADDR_REQ, yiaddr, 4);
+    add_option(OPT_SERVER_IDENT, siaddr, 4);
+    add_option(OPT_END);
     return m_pos;
 }
 
 int DHCPClient::offer(uint8_t buf[], int size) {
     memcpy(yiaddr, buf+DHCP_OFFSET_YIADDR, 4);   
-    memcpy(siaddr, buf+DHCP_OFFSET_SIADDR, 4);   
+    memcpy(siaddr, buf+DHCP_OFFSET_SIADDR, 4);
+ 
+    memset(dnsaddr, 0, sizeof(dnsaddr));
+    memset(gateway, 0, sizeof(gateway));
+    memset(netmask, 0, sizeof(netmask));
+    memset(timesrv, 0, sizeof(timesrv));
+    memset(leaseTime, 0, sizeof(leaseTime));
+    
     uint8_t *p;
     int msg_type = -1;
     p = buf + DHCP_OFFSET_OPTIONS;
-    while(*p != 255 && p < (buf+size)) {
+    while(*p != OPT_END && p < (buf+size)) {
         uint8_t code = *p++;
         if (code == 0) { // Pad Option
             continue;
@@ -72,21 +78,40 @@
         DBG_HEX(p, len);
 
         switch(code) {
-            case 53:
+            case OPT_DHCP_MESSAGE:
                 msg_type = *p;
                 break;
-            case 1:
-                memcpy(netmask, p, 4); // Subnet mask address
+            case OPT_SUBNET_MASK:
+                memcpy(netmask, p, 4);
                 break;
-            case 3:
-                memcpy(gateway, p, 4); // Gateway IP address
+            case OPT_ROUTER:
+                memcpy(gateway, p, 4);
                 break; 
-            case 6:  // DNS server
+            case OPT_DNS:
                 memcpy(dnsaddr, p, 4);
                 break;
-            case 51: // IP lease time 
+            case OPT_TIME_SERVER:
+                memcpy(timesrv, p, 4);
+                break;
+            case OPT_ADDR_LEASE_TIME:
+                memcpy(leaseTime, p, 4);
                 break;
-            case 54: // DHCP server
+            case OPT_DOMAIN_NAME:
+            	{
+                	int cplen = len;
+                	if (cplen > 63)
+                    	cplen = 63; // max domain name
+                    if (domainName) {
+                        free(domainName);
+                        domainName = NULL;
+                    }
+                    if (cplen) {
+                    	domainName = (char *)calloc(1, cplen+1);
+                    	memcpy(domainName, p, cplen); // zero term is already here via calloc
+                    }
+            	}
+                break;
+            case OPT_SERVER_IDENT:
                 memcpy(siaddr, p, 4);
                 break;
         }
@@ -170,8 +195,8 @@
     m_udp->init();
     m_udp->set_blocking(false);
     eth->reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0"
-    m_udp->bind(68); // local port
-    m_server.set_address("255.255.255.255", 67); // DHCP broadcast
+    m_udp->bind(DHCP_CLIENT_PORT); // local port
+    m_server.set_address("255.255.255.255", DHCP_SERVER_PORT); // DHCP broadcast
     exit_flag = false;
     int err = 0;
     int seq = 0;
@@ -208,5 +233,10 @@
 }
 
 DHCPClient::DHCPClient() {
+    domainName = NULL;
 }
 
+DHCPClient::~DHCPClient() {
+    if (domainName)
+        free(domainName);
+}
--- a/Socket/DHCPClient.h	Mon Oct 09 19:58:19 2017 +0200
+++ b/Socket/DHCPClient.h	Tue Oct 10 20:56:13 2017 +0200
@@ -11,6 +11,9 @@
 #define DHCP_OFFSET_OPTIONS 240
 #define DHCP_MAX_PACKET_SIZE 600
 
+#define DHCP_SERVER_PORT 67
+#define DHCP_CLIENT_PORT 68
+
 // DHCP Message Type
 #define DHCPDISCOVER 1
 #define DHCPOFFER    2
@@ -20,17 +23,76 @@
 #define DHCPNAK      6
 #define DHCPRELEASE  7
 #define DHCPINFORM   8
+#define DHCP_MAGIC_COOKIE	0x63825363
+#define OPT_PAD				0
+#define OPT_SUBNET_MASK			1
+#define OPT_TIME_OFFSET			2
+#define OPT_ROUTER			3
+#define OPT_TIME_SERVER			4
+#define OPT_IEN116_NAME_SERVER		5
+#define OPT_DNS				6
+#define OPT_LOG_SERVER			7
+#define OPT_COOKIE_SERVER		8
+#define OPT_LPR_SERVER			9
+#define OPT_IMPRESS_SERVER		10
+#define OPT_RESOURCE_LOC_SERVER		11
+#define OPT_HOSTNAME			12
+#define OPT_BOOTFILE_SIZE		13
+#define OPT_MERIT_DUMP			14
+#define OPT_DOMAIN_NAME			15
+#define OPT_SWAP_SERVER			16
+#define OPT_ROOT_PATH			17
+#define OPT_EXTENSIONS_PATH		18
+#define OPT_IP_FORWARDING		19
+#define OPT_NONLOCAL_SOURCE_ROUTING	20
+#define OPT_POLICY_FILTER		21
+#define OPT_MAX_DATAGRAM_REASS	22
+#define OPT_DEFAULT_IP_TTL		23
+#define OPT_PATH_MTU_AGING_TIMEOUT	24
+#define OPT_PATH_MTU_PLATEAU_TABLE	25
+#define OPT_INTERFACE_MTU		26
+#define OPT_ALL_SUBNETS_ARE_LOCAL	27
+#define OPT_BROADCAST_ADDR		28
+#define OPT_STATIC_ROUTE		33
+#define OPT_VENDOR			43
+#define OPT_NETBIOS_NAME_SERVER	44
+#define OPT_NETBIOS_DATA_DIST	45
+#define OPT_NETBIOS_NODE_TYPE	46
+#define OPT_NETBIOS_SCOPE		47
+#define OPT_IP_ADDR_REQ			50
+#define OPT_ADDR_LEASE_TIME		51
+#define OPT_DHCP_MESSAGE		53
+#define OPT_SERVER_IDENT		54
+#define OPT_PARAMETER_REQ		55
+#define OPT_RENEWAL_TIME		58
+#define OPT_REBINDING_TIME		59
+#define OPT_CLIENT_IDENT		61
+#define OPT_TFTP_SERVER_NAME		66
+#define OPT_BOOTFILE_NAME		67
+#define OPT_LDAP_URL			95	/* from draft RFC */
+#define OPT_DOMAIN_SEARCH		119	/* from draft RFC 3397 */
+
+/* site specific options */
+#define SITE_HD				252
+#define SITE_BF				253
+#define SITE_SA				254
+#define OPT_END				255
 
 class DHCPClient {
 public:
     DHCPClient();
+    ~DHCPClient();
     int setup(int timeout_ms = 15*1000);
     uint8_t chaddr[6]; // MAC
     uint8_t yiaddr[4]; // IP
+    uint8_t siaddr[4]; // DHCP server
     uint8_t dnsaddr[4]; // DNS
     uint8_t gateway[4];
     uint8_t netmask[4];
-    uint8_t siaddr[4];
+    uint8_t timesrv[4];
+    uint8_t leaseTime[4];
+    char *domainName;
+   
 private:
     int discover();
     int request();
--- a/Socket/Endpoint.cpp	Mon Oct 09 19:58:19 2017 +0200
+++ b/Socket/Endpoint.cpp	Tue Oct 10 20:56:13 2017 +0200
@@ -53,6 +53,7 @@
 {
     snprintf(_ipAddress, sizeof(_ipAddress), "%d.%d.%d.%d", (int)(addr>>24)&0xff, (int)(addr>>16)&0xff, (int)(addr>>8)&0xff, (int)addr&0xff);
     _port = port;
+    return 0;
 }
 
 char* Endpoint::get_address()
--- a/arch/ext/W5500.cpp	Mon Oct 09 19:58:19 2017 +0200
+++ b/arch/ext/W5500.cpp	Tue Oct 10 20:56:13 2017 +0200
@@ -55,6 +55,8 @@
     reset_pin = 1;
     inst = this;
     dnsaddr = 0;
+    timesrv = 0;
+    leaseTime = 0;
     sock_any_port = SOCK_ANY_PORT_NUM;
 }
 
--- a/arch/ext/W5500.h	Mon Oct 09 19:58:19 2017 +0200
+++ b/arch/ext/W5500.h	Tue Oct 10 20:56:13 2017 +0200
@@ -996,6 +996,8 @@
     uint32_t netmask;
     uint32_t gateway;
     uint32_t dnsaddr;
+    uint32_t timesrv;
+    uint32_t leaseTime;
     bool dhcp;
     
     void spi_write(uint16_t addr, uint8_t cb, const uint8_t *buf, uint16_t len);