For mbed OS-5 version for WIZnet Ethernet Interface, this is Library using Hardware TCP/IP chip, W5500 and TCP/IP Offload Engine, W7500.

Dependents:   ledMapperTest

Warning

  • If you want to use existing codes, you need to change the class used as EthernetInterface to WIZnetInterface.

This is WIZnet Ethernet Interface using Hardware TCP/IP chip, W5500 and TCP/IP Offload Engine, W7500.

https://developer.mbed.org/media/cache/platforms/WIZwiki_W7500_enabled.JPG.250x250_q85.jpg

https://developer.mbed.org/media/cache/platforms/WIZwiki_W7500P_enabled2.JPG.250x250_q85.jpg

https://developer.mbed.org/media/cache/platforms/WIZwiki_W7500ECO_enabled2.JPG.250x250_q85.jpg

https://developer.mbed.org/media/cache/components/components/fetch.phpmediaoshw5500_ethernet_shieldw5500_main_picture2.png.200x200_q85.jpg

This library is an Ethernet Interface library port-based on [EthernetInterface](https://developer.mbed.org/users/mbed_official/code/EthernetInterface/docs/tip/).

For more detail, visit http://embeddist.blogspot.kr/2015/06/wiznetinterface-for-armmbed.html

Committer:
justinkim
Date:
Mon Sep 04 00:23:04 2017 +0000
Revision:
0:d4c8fe4d9b29
mbed OS 5 version migration...

Who changed what in which revision?

UserRevisionLine numberNew contents of line
justinkim 0:d4c8fe4d9b29 1 // DHCPClient.cpp 2013/4/10
justinkim 0:d4c8fe4d9b29 2 #include "mbed.h"
justinkim 0:d4c8fe4d9b29 3 #include "mbed_debug.h"
justinkim 0:d4c8fe4d9b29 4 #include "WIZnet_UDPSocket.h"
justinkim 0:d4c8fe4d9b29 5 #include "DHCPClient.h"
justinkim 0:d4c8fe4d9b29 6
justinkim 0:d4c8fe4d9b29 7 #define DBG_DHCP 0
justinkim 0:d4c8fe4d9b29 8
justinkim 0:d4c8fe4d9b29 9 #if DBG_DHCP
justinkim 0:d4c8fe4d9b29 10 #define DBG(...) do{debug("[%s:%d]", __PRETTY_FUNCTION__,__LINE__);debug(__VA_ARGS__);} while(0);
justinkim 0:d4c8fe4d9b29 11 #define DBG_HEX(A,B) do{debug("[%s:%d]\r\n", __PRETTY_FUNCTION__,__LINE__);debug_hex(A,B);} while(0);
justinkim 0:d4c8fe4d9b29 12 #else
justinkim 0:d4c8fe4d9b29 13 #define DBG(...) while(0);
justinkim 0:d4c8fe4d9b29 14 #define DBG_HEX(A,B) while(0);
justinkim 0:d4c8fe4d9b29 15 #endif
justinkim 0:d4c8fe4d9b29 16
justinkim 0:d4c8fe4d9b29 17 int DHCPClient::discover()
justinkim 0:d4c8fe4d9b29 18 {
justinkim 0:d4c8fe4d9b29 19 m_pos = 0;
justinkim 0:d4c8fe4d9b29 20 const uint8_t header[] = {0x01,0x01,0x06,0x00};
justinkim 0:d4c8fe4d9b29 21 add_buf((uint8_t*)header, sizeof(header));
justinkim 0:d4c8fe4d9b29 22 uint32_t x = time(NULL) + rand();
justinkim 0:d4c8fe4d9b29 23 xid[0] = x>>24; xid[1] = x>>16; xid[2] = x>>8; xid[3] = x;
justinkim 0:d4c8fe4d9b29 24 add_buf(xid, 4);
justinkim 0:d4c8fe4d9b29 25 fill_buf(20, 0x00);
justinkim 0:d4c8fe4d9b29 26 add_buf(chaddr, 6);
justinkim 0:d4c8fe4d9b29 27 fill_buf(10+192, 0x00);
justinkim 0:d4c8fe4d9b29 28 const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie
justinkim 0:d4c8fe4d9b29 29 53,1,DHCPDISCOVER, // DHCP option 53: DHCP Discover
justinkim 0:d4c8fe4d9b29 30 55,4,1,3,15,6,
justinkim 0:d4c8fe4d9b29 31 255};
justinkim 0:d4c8fe4d9b29 32 add_buf((uint8_t*)options, sizeof(options));
justinkim 0:d4c8fe4d9b29 33 return m_pos;
justinkim 0:d4c8fe4d9b29 34 }
justinkim 0:d4c8fe4d9b29 35
justinkim 0:d4c8fe4d9b29 36 int DHCPClient::request()
justinkim 0:d4c8fe4d9b29 37 {
justinkim 0:d4c8fe4d9b29 38 m_pos = 0;
justinkim 0:d4c8fe4d9b29 39 const uint8_t header[] = {0x01,0x01,0x06,0x00};
justinkim 0:d4c8fe4d9b29 40 add_buf((uint8_t*)header, sizeof(header));
justinkim 0:d4c8fe4d9b29 41 add_buf(xid, 4);
justinkim 0:d4c8fe4d9b29 42 fill_buf(12, 0x00);
justinkim 0:d4c8fe4d9b29 43 add_buf(siaddr, 4);
justinkim 0:d4c8fe4d9b29 44 fill_buf(4, 0x00); // giaddr
justinkim 0:d4c8fe4d9b29 45 add_buf(chaddr, 6);
justinkim 0:d4c8fe4d9b29 46 fill_buf(10+192, 0x00);
justinkim 0:d4c8fe4d9b29 47 const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie
justinkim 0:d4c8fe4d9b29 48 53,1,DHCPREQUEST, // DHCP option 53: DHCP Request
justinkim 0:d4c8fe4d9b29 49 55,4,1,3,15,6, // DHCP option 55:
justinkim 0:d4c8fe4d9b29 50 };
justinkim 0:d4c8fe4d9b29 51 add_buf((uint8_t*)options, sizeof(options));
justinkim 0:d4c8fe4d9b29 52 add_option(50, yiaddr, 4);
justinkim 0:d4c8fe4d9b29 53 add_option(54, siaddr, 4);
justinkim 0:d4c8fe4d9b29 54 add_option(255);
justinkim 0:d4c8fe4d9b29 55 return m_pos;
justinkim 0:d4c8fe4d9b29 56 }
justinkim 0:d4c8fe4d9b29 57
justinkim 0:d4c8fe4d9b29 58 int DHCPClient::offer(uint8_t buf[], int size) {
justinkim 0:d4c8fe4d9b29 59 memcpy(yiaddr, buf+DHCP_OFFSET_YIADDR, 4);
justinkim 0:d4c8fe4d9b29 60 memcpy(siaddr, buf+DHCP_OFFSET_SIADDR, 4);
justinkim 0:d4c8fe4d9b29 61 uint8_t *p;
justinkim 0:d4c8fe4d9b29 62 int msg_type = -1;
justinkim 0:d4c8fe4d9b29 63 p = buf + DHCP_OFFSET_OPTIONS;
justinkim 0:d4c8fe4d9b29 64 while(*p != 255 && p < (buf+size)) {
justinkim 0:d4c8fe4d9b29 65 uint8_t code = *p++;
justinkim 0:d4c8fe4d9b29 66 if (code == 0) { // Pad Option
justinkim 0:d4c8fe4d9b29 67 continue;
justinkim 0:d4c8fe4d9b29 68 }
justinkim 0:d4c8fe4d9b29 69 int len = *p++;
justinkim 0:d4c8fe4d9b29 70
justinkim 0:d4c8fe4d9b29 71 DBG("DHCP option: %d\r\n", code);
justinkim 0:d4c8fe4d9b29 72 DBG_HEX(p, len);
justinkim 0:d4c8fe4d9b29 73
justinkim 0:d4c8fe4d9b29 74 switch(code) {
justinkim 0:d4c8fe4d9b29 75 case 53:
justinkim 0:d4c8fe4d9b29 76 msg_type = *p;
justinkim 0:d4c8fe4d9b29 77 break;
justinkim 0:d4c8fe4d9b29 78 case 1:
justinkim 0:d4c8fe4d9b29 79 memcpy(netmask, p, 4); // Subnet mask address
justinkim 0:d4c8fe4d9b29 80 break;
justinkim 0:d4c8fe4d9b29 81 case 3:
justinkim 0:d4c8fe4d9b29 82 memcpy(gateway, p, 4); // Gateway IP address
justinkim 0:d4c8fe4d9b29 83 break;
justinkim 0:d4c8fe4d9b29 84 case 6: // DNS server
justinkim 0:d4c8fe4d9b29 85 memcpy(dnsaddr, p, 4);
justinkim 0:d4c8fe4d9b29 86 break;
justinkim 0:d4c8fe4d9b29 87 case 51: // IP lease time
justinkim 0:d4c8fe4d9b29 88 break;
justinkim 0:d4c8fe4d9b29 89 case 54: // DHCP server
justinkim 0:d4c8fe4d9b29 90 memcpy(siaddr, p, 4);
justinkim 0:d4c8fe4d9b29 91 break;
justinkim 0:d4c8fe4d9b29 92 }
justinkim 0:d4c8fe4d9b29 93 p += len;
justinkim 0:d4c8fe4d9b29 94 }
justinkim 0:d4c8fe4d9b29 95 return msg_type;
justinkim 0:d4c8fe4d9b29 96 }
justinkim 0:d4c8fe4d9b29 97
justinkim 0:d4c8fe4d9b29 98 bool DHCPClient::verify(uint8_t buf[], int len) {
justinkim 0:d4c8fe4d9b29 99 if (len < DHCP_OFFSET_OPTIONS) {
justinkim 0:d4c8fe4d9b29 100 return false;
justinkim 0:d4c8fe4d9b29 101 }
justinkim 0:d4c8fe4d9b29 102 if (buf[DHCP_OFFSET_OP] != 0x02) {
justinkim 0:d4c8fe4d9b29 103 return false;
justinkim 0:d4c8fe4d9b29 104 }
justinkim 0:d4c8fe4d9b29 105 if (memcmp(buf+DHCP_OFFSET_XID, xid, 4) != 0) {
justinkim 0:d4c8fe4d9b29 106 return false;
justinkim 0:d4c8fe4d9b29 107 }
justinkim 0:d4c8fe4d9b29 108 return true;
justinkim 0:d4c8fe4d9b29 109 }
justinkim 0:d4c8fe4d9b29 110
justinkim 0:d4c8fe4d9b29 111 void DHCPClient::callback()
justinkim 0:d4c8fe4d9b29 112 {
justinkim 0:d4c8fe4d9b29 113 Endpoint host;
justinkim 0:d4c8fe4d9b29 114 int recv_len = m_udp->receiveFrom(host, (char*)m_buf, sizeof(m_buf));
justinkim 0:d4c8fe4d9b29 115 if (recv_len < 0) {
justinkim 0:d4c8fe4d9b29 116 return;
justinkim 0:d4c8fe4d9b29 117 }
justinkim 0:d4c8fe4d9b29 118 if (!verify(m_buf, recv_len)) {
justinkim 0:d4c8fe4d9b29 119 return;
justinkim 0:d4c8fe4d9b29 120 }
justinkim 0:d4c8fe4d9b29 121 int r = offer(m_buf, recv_len);
justinkim 0:d4c8fe4d9b29 122 if (r == DHCPOFFER) {
justinkim 0:d4c8fe4d9b29 123 int send_size = request();
justinkim 0:d4c8fe4d9b29 124 m_udp->sendTo(m_server, (char*)m_buf, send_size);
justinkim 0:d4c8fe4d9b29 125 } else if (r == DHCPACK) {
justinkim 0:d4c8fe4d9b29 126 exit_flag = true;
justinkim 0:d4c8fe4d9b29 127 }
justinkim 0:d4c8fe4d9b29 128 }
justinkim 0:d4c8fe4d9b29 129
justinkim 0:d4c8fe4d9b29 130 void DHCPClient::add_buf(uint8_t c)
justinkim 0:d4c8fe4d9b29 131 {
justinkim 0:d4c8fe4d9b29 132 m_buf[m_pos++] = c;
justinkim 0:d4c8fe4d9b29 133 }
justinkim 0:d4c8fe4d9b29 134
justinkim 0:d4c8fe4d9b29 135 void DHCPClient::add_buf(uint8_t* buf, int len)
justinkim 0:d4c8fe4d9b29 136 {
justinkim 0:d4c8fe4d9b29 137 for(int i = 0; i < len; i++) {
justinkim 0:d4c8fe4d9b29 138 add_buf(buf[i]);
justinkim 0:d4c8fe4d9b29 139 }
justinkim 0:d4c8fe4d9b29 140 }
justinkim 0:d4c8fe4d9b29 141
justinkim 0:d4c8fe4d9b29 142 void DHCPClient::fill_buf(int len, uint8_t data)
justinkim 0:d4c8fe4d9b29 143 {
justinkim 0:d4c8fe4d9b29 144 while(len-- > 0) {
justinkim 0:d4c8fe4d9b29 145 add_buf(data);
justinkim 0:d4c8fe4d9b29 146 }
justinkim 0:d4c8fe4d9b29 147 }
justinkim 0:d4c8fe4d9b29 148
justinkim 0:d4c8fe4d9b29 149 void DHCPClient::add_option(uint8_t code, uint8_t* buf, int len)
justinkim 0:d4c8fe4d9b29 150 {
justinkim 0:d4c8fe4d9b29 151 add_buf(code);
justinkim 0:d4c8fe4d9b29 152 if (len > 0) {
justinkim 0:d4c8fe4d9b29 153 add_buf((uint8_t)len);
justinkim 0:d4c8fe4d9b29 154 add_buf(buf, len);
justinkim 0:d4c8fe4d9b29 155 }
justinkim 0:d4c8fe4d9b29 156 }
justinkim 0:d4c8fe4d9b29 157
justinkim 0:d4c8fe4d9b29 158 int DHCPClient::setup(int timeout_ms)
justinkim 0:d4c8fe4d9b29 159 {
justinkim 0:d4c8fe4d9b29 160 eth = WIZnet_Chip::getInstance();
justinkim 0:d4c8fe4d9b29 161 if (eth == NULL) {
justinkim 0:d4c8fe4d9b29 162 return -1;
justinkim 0:d4c8fe4d9b29 163 }
justinkim 0:d4c8fe4d9b29 164 eth->reg_rd_mac(SHAR, chaddr);
justinkim 0:d4c8fe4d9b29 165 int interval_ms = 5*1000; // 5000msec
justinkim 0:d4c8fe4d9b29 166 if (timeout_ms < interval_ms) {
justinkim 0:d4c8fe4d9b29 167 interval_ms = timeout_ms;
justinkim 0:d4c8fe4d9b29 168 }
justinkim 0:d4c8fe4d9b29 169 m_udp = new WIZnet_UDPSocket;
justinkim 0:d4c8fe4d9b29 170 m_udp->init();
justinkim 0:d4c8fe4d9b29 171 m_udp->set_blocking(false);
justinkim 0:d4c8fe4d9b29 172 eth->reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0"
justinkim 0:d4c8fe4d9b29 173 m_udp->bind(68); // local port
justinkim 0:d4c8fe4d9b29 174 m_server.set_address("255.255.255.255", 67); // DHCP broadcast
justinkim 0:d4c8fe4d9b29 175 exit_flag = false;
justinkim 0:d4c8fe4d9b29 176 int err = 0;
justinkim 0:d4c8fe4d9b29 177 int seq = 0;
justinkim 0:d4c8fe4d9b29 178 int send_size;
justinkim 0:d4c8fe4d9b29 179 while(!exit_flag) {
justinkim 0:d4c8fe4d9b29 180 switch(seq) {
justinkim 0:d4c8fe4d9b29 181 case 0:
justinkim 0:d4c8fe4d9b29 182 m_retry = 0;
justinkim 0:d4c8fe4d9b29 183 seq++;
justinkim 0:d4c8fe4d9b29 184 break;
justinkim 0:d4c8fe4d9b29 185 case 1:
justinkim 0:d4c8fe4d9b29 186 send_size = discover();
justinkim 0:d4c8fe4d9b29 187 m_udp->sendTo(m_server, (char*)m_buf, send_size);
justinkim 0:d4c8fe4d9b29 188 m_interval.reset();
justinkim 0:d4c8fe4d9b29 189 m_interval.start();
justinkim 0:d4c8fe4d9b29 190 seq++;
justinkim 0:d4c8fe4d9b29 191 break;
justinkim 0:d4c8fe4d9b29 192 case 2:
justinkim 0:d4c8fe4d9b29 193 callback();
justinkim 0:d4c8fe4d9b29 194 if (m_interval.read_ms() > interval_ms) {
justinkim 0:d4c8fe4d9b29 195 DBG("m_retry: %d\n", m_retry);
justinkim 0:d4c8fe4d9b29 196 if (++m_retry >= (timeout_ms/interval_ms)) {
justinkim 0:d4c8fe4d9b29 197 err = -1;
justinkim 0:d4c8fe4d9b29 198 exit_flag = true;
justinkim 0:d4c8fe4d9b29 199 }
justinkim 0:d4c8fe4d9b29 200 seq--;
justinkim 0:d4c8fe4d9b29 201 }
justinkim 0:d4c8fe4d9b29 202 break;
justinkim 0:d4c8fe4d9b29 203 }
justinkim 0:d4c8fe4d9b29 204 }
justinkim 0:d4c8fe4d9b29 205 DBG("m_retry: %d, m_interval: %d\n", m_retry, m_interval.read_ms());
justinkim 0:d4c8fe4d9b29 206 delete m_udp;
justinkim 0:d4c8fe4d9b29 207 return err;
justinkim 0:d4c8fe4d9b29 208 }
justinkim 0:d4c8fe4d9b29 209
justinkim 0:d4c8fe4d9b29 210 DHCPClient::DHCPClient() {
justinkim 0:d4c8fe4d9b29 211 }