This is WIZnet Ethernet Interface using Hardware TCP/IP chip, W5500, W5200 and W5100. One of them can be selected by enabling it in wiznet.h.

Dependents:   Embedded_web EmailButton EmailButton HTTPClient_Weather ... more

other drivers

for only W5500 / WIZ550io user, you could use

Import libraryW5500Interface

This is the Interface library for WIZnet W5500 chip which forked of EthernetInterfaceW5500, WIZnetInterface and WIZ550ioInterface. This library has simple name as "W5500Interface". and can be used for Wiz550io users also.

Committer:
Bongjun
Date:
Sun May 31 10:25:40 2015 +0000
Revision:
8:cb8808b47e69
Parent:
0:b72d22e10709
fix some codes of reading Sn_RX_RSR, Sn_TX_FSR in W5100.cpp, W5200.cpp; added is_fin_received()  in W5100, W5200 files

Who changed what in which revision?

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