WIZnetInterface using namespace

Dependents:   DualNetworkInterface-Basic

Fork of WIZnetInterface by WIZnet

Committer:
SteveKim
Date:
Tue Jul 14 10:16:16 2015 +0000
Revision:
20:3e61863c1f67
Parent:
15:24a9f2df2145
Dual Network Interface for mbed;  - WIZwiki-W7500;  - ESP8266

Who changed what in which revision?

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