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.
Dependents: EvrythngApi Websocket_Ethernet_HelloWorld_W5500 Websocket_Ethernet_W5500 CurrentWeatherData_W5500 ... more
DHCPClient.cpp
00001 // DHCPClient.cpp 2013/4/10 00002 #include "mbed.h" 00003 #include "mbed_debug.h" 00004 #include "UDPSocket.h" 00005 #include "DHCPClient.h" 00006 00007 #define DBG_DHCP 0 00008 00009 #if DBG_DHCP 00010 #define DBG(...) do{debug("[%s:%d]", __PRETTY_FUNCTION__,__LINE__);debug(__VA_ARGS__);} while(0); 00011 #define DBG_HEX(A,B) do{debug("[%s:%d]\r\n", __PRETTY_FUNCTION__,__LINE__);debug_hex(A,B);} while(0); 00012 #else 00013 #define DBG(...) while(0); 00014 #define DBG_HEX(A,B) while(0); 00015 #endif 00016 00017 int DHCPClient::discover() 00018 { 00019 m_pos = 0; 00020 const uint8_t header[] = {0x01,0x01,0x06,0x00}; 00021 add_buf((uint8_t*)header, sizeof(header)); 00022 uint32_t x = time(NULL) + rand(); 00023 xid[0] = x>>24; xid[1] = x>>16; xid[2] = x>>8; xid[3] = x; 00024 add_buf(xid, 4); 00025 fill_buf(20, 0x00); 00026 add_buf(chaddr, 6); 00027 fill_buf(10+192, 0x00); 00028 const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie 00029 53,1,DHCPDISCOVER, // DHCP option 53: DHCP Discover 00030 55,4,1,3,15,6, 00031 255}; 00032 add_buf((uint8_t*)options, sizeof(options)); 00033 return m_pos; 00034 } 00035 00036 int DHCPClient::request() 00037 { 00038 m_pos = 0; 00039 const uint8_t header[] = {0x01,0x01,0x06,0x00}; 00040 add_buf((uint8_t*)header, sizeof(header)); 00041 add_buf(xid, 4); 00042 fill_buf(12, 0x00); 00043 add_buf(siaddr, 4); 00044 fill_buf(4, 0x00); // giaddr 00045 add_buf(chaddr, 6); 00046 fill_buf(10+192, 0x00); 00047 const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie 00048 53,1,DHCPREQUEST, // DHCP option 53: DHCP Request 00049 55,4,1,3,15,6, // DHCP option 55: 00050 }; 00051 add_buf((uint8_t*)options, sizeof(options)); 00052 add_option(50, yiaddr, 4); 00053 add_option(54, siaddr, 4); 00054 add_option(255); 00055 return m_pos; 00056 } 00057 00058 int DHCPClient::offer(uint8_t buf[], int size) { 00059 memcpy(yiaddr, buf+DHCP_OFFSET_YIADDR, 4); 00060 memcpy(siaddr, buf+DHCP_OFFSET_SIADDR, 4); 00061 uint8_t *p; 00062 int msg_type = -1; 00063 p = buf + DHCP_OFFSET_OPTIONS; 00064 while(*p != 255 && p < (buf+size)) { 00065 uint8_t code = *p++; 00066 if (code == 0) { // Pad Option 00067 continue; 00068 } 00069 int len = *p++; 00070 00071 DBG("DHCP option: %d\r\n", code); 00072 DBG_HEX(p, len); 00073 00074 switch(code) { 00075 case 53: 00076 msg_type = *p; 00077 break; 00078 case 1: 00079 memcpy(netmask, p, 4); // Subnet mask address 00080 break; 00081 case 3: 00082 memcpy(gateway, p, 4); // Gateway IP address 00083 break; 00084 case 6: // DNS server 00085 memcpy(dnsaddr, p, 4); 00086 break; 00087 case 51: // IP lease time 00088 break; 00089 case 54: // DHCP server 00090 memcpy(siaddr, p, 4); 00091 break; 00092 } 00093 p += len; 00094 } 00095 return msg_type; 00096 } 00097 00098 bool DHCPClient::verify(uint8_t buf[], int len) { 00099 if (len < DHCP_OFFSET_OPTIONS) { 00100 return false; 00101 } 00102 if (buf[DHCP_OFFSET_OP] != 0x02) { 00103 return false; 00104 } 00105 if (memcmp(buf+DHCP_OFFSET_XID, xid, 4) != 0) { 00106 return false; 00107 } 00108 return true; 00109 } 00110 00111 void DHCPClient::callback() 00112 { 00113 Endpoint host; 00114 int recv_len = m_udp->receiveFrom(host, (char*)m_buf, sizeof(m_buf)); 00115 if (recv_len < 0) { 00116 return; 00117 } 00118 if (!verify(m_buf, recv_len)) { 00119 return; 00120 } 00121 int r = offer(m_buf, recv_len); 00122 if (r == DHCPOFFER) { 00123 int send_size = request(); 00124 m_udp->sendTo(m_server, (char*)m_buf, send_size); 00125 } else if (r == DHCPACK) { 00126 exit_flag = true; 00127 } 00128 } 00129 00130 void DHCPClient::add_buf(uint8_t c) 00131 { 00132 m_buf[m_pos++] = c; 00133 } 00134 00135 void DHCPClient::add_buf(uint8_t* buf, int len) 00136 { 00137 for(int i = 0; i < len; i++) { 00138 add_buf(buf[i]); 00139 } 00140 } 00141 00142 void DHCPClient::fill_buf(int len, uint8_t data) 00143 { 00144 while(len-- > 0) { 00145 add_buf(data); 00146 } 00147 } 00148 00149 void DHCPClient::add_option(uint8_t code, uint8_t* buf, int len) 00150 { 00151 add_buf(code); 00152 if (len > 0) { 00153 add_buf((uint8_t)len); 00154 add_buf(buf, len); 00155 } 00156 } 00157 00158 int DHCPClient::setup(int timeout_ms) 00159 { 00160 eth = WIZnet_Chip::getInstance(); 00161 if (eth == NULL) { 00162 return -1; 00163 } 00164 eth->reg_rd_mac(SHAR, chaddr); 00165 int interval_ms = 5*1000; // 5000msec 00166 if (timeout_ms < interval_ms) { 00167 interval_ms = timeout_ms; 00168 } 00169 m_udp = new UDPSocket; 00170 m_udp->init(); 00171 m_udp->set_blocking(false); 00172 eth->reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0" 00173 m_udp->bind(68); // local port 00174 m_server.set_address("255.255.255.255", 67); // DHCP broadcast 00175 exit_flag = false; 00176 int err = 0; 00177 int seq = 0; 00178 int send_size; 00179 while(!exit_flag) { 00180 switch(seq) { 00181 case 0: 00182 m_retry = 0; 00183 seq++; 00184 break; 00185 case 1: 00186 send_size = discover(); 00187 m_udp->sendTo(m_server, (char*)m_buf, send_size); 00188 m_interval.reset(); 00189 m_interval.start(); 00190 seq++; 00191 break; 00192 case 2: 00193 callback(); 00194 if (m_interval.read_ms() > interval_ms) { 00195 DBG("m_retry: %d\n", m_retry); 00196 if (++m_retry >= (timeout_ms/interval_ms)) { 00197 err = -1; 00198 exit_flag = true; 00199 } 00200 seq--; 00201 } 00202 break; 00203 } 00204 } 00205 DBG("m_retry: %d, m_interval: %d\n", m_retry, m_interval.read_ms()); 00206 delete m_udp; 00207 return err; 00208 } 00209 00210 DHCPClient::DHCPClient() { 00211 }
Generated on Thu Jul 14 2022 02:02:03 by 1.7.2