DHCP Client for WIZ820io(W5200)
Dependencies: EthernetNetIf mbed
Diff: DHCPClient.cpp
- Revision:
- 0:db4242c89949
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DHCPClient.cpp Tue Apr 10 03:38:22 2012 +0000 @@ -0,0 +1,100 @@ +// DHCPClient.cpp 2012/4/10 +// DHCP Client for WIZ820io(W5200) +#include "mbed.h" +#include "MyEthernetNetIf.h" +#include "MyUDPSocket.h" +#include "DHCPClient.h" +#ifdef DEBUG +#include "Utils.h" +#endif //DEBUG + +static DHCPClient* _g_dhcp; +static void _DHCP_OnEvent(UDPSocketEvent e) +{ + _g_dhcp->callback(e); +} + +int DHCPClient::offer_ack(uint8_t buf[], int size) { + memcpy(yiaddr, &buf[DHCP_OFFSET_YIADDR], 4); + uint8_t *p; + int msg_type = -1; + p = buf + DHCP_OFFSET_OPTIONS; + while(*p != 0xff && p < (uint8_t*)&buf[DHCP_MAX_PACKET_SIZE]) { + int code = *p++; + if (code == 0x00) { + continue; + } + int len = *p++; +#ifdef DHCP_VERBOSE + char codeStr[24]; + snprintf(codeStr, sizeof(codeStr), "DHCP option: %d", code); + printfBytes(codeStr, p, len); +#endif //DHCP_VERBOSE + if (code == 53) { + msg_type = *p; + } else if (code == 1) { + memcpy(netmask, p, 4); // Subnet mask address + } else if (code == 3) { + memcpy(gateway, p, 4); // Gateway IP address + } else if (code == 6) {// DNS + memcpy(dnsaddr, p, 4); + } + p += len; + } + return msg_type; +} + +void DHCPClient::callback(UDPSocketEvent e) +{ + PRINT_FUNC(); + uint8_t buf[DHCP_MAX_PACKET_SIZE]; + Host host; + int len = p_udp->recvfrom((char*)buf, sizeof(buf), &host); + if (!verify(buf, len)) { + return; + } + int r = offer_ack(buf, len); + if (r == 2) { // OFFER + request(buf, 300); + Host server(IpAddr(255,255,255,255), 67); // DHCP broadcast + p_udp->sendto((char*)buf, 300, &server); + } else if (r == 5) { // ACK + exit_flag = true; + } +} + +int DHCPClient::setup(int timeout_ms) +{ + Timer t; + t.start(); + p_udp = new MyUDPSocket; + p_udp->setOnEvent(_DHCP_OnEvent); + Host local(IpAddr(0,0,0,0), 68); + Host server(IpAddr(255,255,255,255), 67); // DHCP broadcast + p_udp->bind(local); + uint8_t buf[300]; + discover(buf, sizeof(buf)); + p_udp->sendto((char*)buf, sizeof(buf), &server); + exit_flag = false; + int err = 0; + while(1) { + p_udp->poll(); + if (exit_flag) { + break; + } + if (t.read_ms() > timeout_ms) { + err = -1; + break; + } +#ifdef DEBUG + wait_ms(100); +#endif //DEBUG + } + delete p_udp; + return err; +} + +DHCPClient::DHCPClient() +{ + _g_dhcp = this; +}