W5500 driver for mbed OS 5

Dependents:   http-webserver-example mbed-os-example-sockets

Fork of W5500Interface by Sergei G

Committer:
Bongjun
Date:
Thu Aug 09 08:10:27 2018 +0000
Revision:
6:e2ab76b2be07
Child:
9:351e20cf7d05
changes for mbed OS 5 web server example; - add internal W5500 instance; - changes for web server example

Who changed what in which revision?

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