Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:9697009514d0, committed 2017-06-15
- Comitter:
- dgriffin65
- Date:
- Thu Jun 15 20:17:57 2017 +0000
- Commit message:
- Updated to mbed-os
Changed in this revision
DHCPClient.cpp | Show annotated file Show diff for this revision Revisions of this file |
DHCPClient.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DHCPClient.cpp Thu Jun 15 20:17:57 2017 +0000 @@ -0,0 +1,208 @@ +// DHCPClient.cpp 2013/4/10 +#include "mbed.h" +#include "mbed_debug.h" +#include "UDPSocket.h" +#include "DHCPClient.h" + +#define DBG_DHCP 0 + +#if DBG_DHCP +#define DBG(...) do{debug("[%s:%d]", __PRETTY_FUNCTION__,__LINE__);debug(__VA_ARGS__);} while(0); +#define DBG_HEX(A,B) do{debug("[%s:%d]\r\n", __PRETTY_FUNCTION__,__LINE__);debug_hex(A,B);} while(0); +#else +#define DBG(...) while(0); +#define DBG_HEX(A,B) while(0); +#endif + +int DHCPClient::discover() +{ + m_pos = 0; + const uint8_t header[] = {0x01,0x01,0x06,0x00}; + add_buf((uint8_t*)header, sizeof(header)); + uint32_t x = time(NULL) + rand(); + xid[0] = x>>24; xid[1] = x>>16; xid[2] = x>>8; xid[3] = x; + add_buf(xid, 4); + fill_buf(20, 0x00); + add_buf(chaddr, 6); + fill_buf(10+192, 0x00); + const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie + 53,1,DHCPDISCOVER, // DHCP option 53: DHCP Discover + 55,4,1,3,15,6, + 255}; + add_buf((uint8_t*)options, sizeof(options)); + return m_pos; +} + +int DHCPClient::request() +{ + m_pos = 0; + const uint8_t header[] = {0x01,0x01,0x06,0x00}; + add_buf((uint8_t*)header, sizeof(header)); + add_buf(xid, 4); + fill_buf(12, 0x00); + add_buf(siaddr, 4); + fill_buf(4, 0x00); // giaddr + add_buf(chaddr, 6); + fill_buf(10+192, 0x00); + const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie + 53,1,DHCPREQUEST, // DHCP option 53: DHCP Request + 55,4,1,3,15,6, // DHCP option 55: + }; + add_buf((uint8_t*)options, sizeof(options)); + add_option(50, yiaddr, 4); + add_option(54, siaddr, 4); + add_option(255); + return m_pos; +} + +int DHCPClient::offer(uint8_t buf[], int size) { + memcpy(yiaddr, buf+DHCP_OFFSET_YIADDR, 4); + memcpy(siaddr, buf+DHCP_OFFSET_SIADDR, 4); + uint8_t *p; + int msg_type = -1; + p = buf + DHCP_OFFSET_OPTIONS; + while(*p != 255 && p < (buf+size)) { + uint8_t code = *p++; + if (code == 0) { // Pad Option + continue; + } + int len = *p++; + + DBG("DHCP option: %d\r\n", code); + DBG_HEX(p, len); + + switch(code) { + case 53: + msg_type = *p; + break; + case 1: + memcpy(netmask, p, 4); // Subnet mask address + break; + case 3: + memcpy(gateway, p, 4); // Gateway IP address + break; + case 6: // DNS server + memcpy(dnsaddr, p, 4); + break; + case 51: // IP lease time + break; + case 54: // DHCP server + memcpy(siaddr, p, 4); + break; + } + p += len; + } + return msg_type; +} + +bool DHCPClient::verify(uint8_t buf[], int len) { + if (len < DHCP_OFFSET_OPTIONS) { + return false; + } + if (buf[DHCP_OFFSET_OP] != 0x02) { + return false; + } + if (memcmp(buf+DHCP_OFFSET_XID, xid, 4) != 0) { + return false; + } + return true; +} + +void DHCPClient::callback() +{ + //printf("DHCPClient callback\n"); + SocketAddress host; + int recv_len = m_udp->recvfrom(&host, (char*)m_buf, sizeof(m_buf)); + if (recv_len < 0) { + return; + } + if (!verify(m_buf, recv_len)) { + return; + } + int r = offer(m_buf, recv_len); + if (r == DHCPOFFER) { + int send_size = request(); + m_udp->sendto(m_server, (char*)m_buf, send_size); + } else if (r == DHCPACK) { + exit_flag = true; + } +} + +void DHCPClient::add_buf(uint8_t c) +{ + m_buf[m_pos++] = c; +} + +void DHCPClient::add_buf(uint8_t* buf, int len) +{ + for(int i = 0; i < len; i++) { + add_buf(buf[i]); + } +} + +void DHCPClient::fill_buf(int len, uint8_t data) +{ + while(len-- > 0) { + add_buf(data); + } +} + +void DHCPClient::add_option(uint8_t code, uint8_t* buf, int len) +{ + add_buf(code); + if (len > 0) { + add_buf((uint8_t)len); + add_buf(buf, len); + } +} + +int DHCPClient::setup(NetworkStack *ns, int timeout_ms) +{ + int interval_ms = 5*1000; // 5000msec + if (timeout_ms < interval_ms) { + interval_ms = timeout_ms; + } + UDPSocket udp_sock; + m_udp = &udp_sock; + + udp_sock.open(ns); + udp_sock.set_blocking(false); + udp_sock.bind(68); // local port + m_server.set_ip_address("255.255.255.255"); // DHCP broadcast + m_server.set_port(67); // DHCP broadcast + exit_flag = false; + int err = 0; + int seq = 0; + int send_size; + while(!exit_flag) { + switch(seq) { + case 0: + m_retry = 0; + seq++; + break; + case 1: + send_size = discover(); + udp_sock.sendto(m_server, (char*)m_buf, send_size); + m_interval.reset(); + m_interval.start(); + seq++; + break; + case 2: + callback(); + if (m_interval.read_ms() > interval_ms) { + DBG("m_retry: %d\n", m_retry); + if (++m_retry >= (timeout_ms/interval_ms)) { + err = -1; + exit_flag = true; + } + seq--; + } + break; + } + } + DBG("m_retry: %d, m_interval: %d\n", m_retry, m_interval.read_ms()); + return err; +} + +DHCPClient::DHCPClient() { +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DHCPClient.h Thu Jun 15 20:17:57 2017 +0000 @@ -0,0 +1,54 @@ +// DHCPClient.h 2013/4/10 +#ifndef DHCPCLIENT_H +#define DHCPCLIENT_H +#include "wiznet.h" +#include "UDPSocket.h" + +#define DHCP_OFFSET_OP 0 +#define DHCP_OFFSET_XID 4 +#define DHCP_OFFSET_YIADDR 16 +#define DHCP_OFFSET_SIADDR 20 +#define DHCP_OFFSET_OPTIONS 240 +#define DHCP_MAX_PACKET_SIZE 600 + +// DHCP Message Type +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 +#define DHCPINFORM 8 + +class DHCPClient { +public: + DHCPClient(); + int setup(NetworkStack *ns, int timeout_ms = 15*1000); + uint8_t chaddr[6]; // MAC + uint8_t yiaddr[4]; // IP + uint8_t dnsaddr[4]; // DNS + uint8_t gateway[4]; + uint8_t netmask[4]; + uint8_t siaddr[4]; +private: + int discover(); + int request(); + int offer(uint8_t buf[], int size); + void add_buf(uint8_t* buf, int len); + void fill_buf(int len, uint8_t data = 0x00); + void add_buf(uint8_t c); + void add_option(uint8_t code, uint8_t* buf = NULL, int len = 0); + bool verify(uint8_t buf[], int len); + void callback(); + UDPSocket* m_udp; + SocketAddress m_server; + uint8_t xid[4]; + bool exit_flag; + Timer m_interval; + int m_retry; + uint8_t m_buf[DHCP_MAX_PACKET_SIZE]; + int m_pos; + //WIZnet_Chip* eth; +}; +#endif //DHCPCLIENT_H