
DHCP Client for WIZ820io(W5200)
Dependencies: EthernetNetIf mbed
DHCPClient.cpp@0:db4242c89949, 2012-04-10 (annotated)
- Committer:
- va009039
- Date:
- Tue Apr 10 03:38:22 2012 +0000
- Revision:
- 0:db4242c89949
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:db4242c89949 | 1 | // DHCPClient.cpp 2012/4/10 |
va009039 | 0:db4242c89949 | 2 | // DHCP Client for WIZ820io(W5200) |
va009039 | 0:db4242c89949 | 3 | #include "mbed.h" |
va009039 | 0:db4242c89949 | 4 | #include "MyEthernetNetIf.h" |
va009039 | 0:db4242c89949 | 5 | #include "MyUDPSocket.h" |
va009039 | 0:db4242c89949 | 6 | #include "DHCPClient.h" |
va009039 | 0:db4242c89949 | 7 | #ifdef DEBUG |
va009039 | 0:db4242c89949 | 8 | #include "Utils.h" |
va009039 | 0:db4242c89949 | 9 | #endif //DEBUG |
va009039 | 0:db4242c89949 | 10 | |
va009039 | 0:db4242c89949 | 11 | static DHCPClient* _g_dhcp; |
va009039 | 0:db4242c89949 | 12 | static void _DHCP_OnEvent(UDPSocketEvent e) |
va009039 | 0:db4242c89949 | 13 | { |
va009039 | 0:db4242c89949 | 14 | _g_dhcp->callback(e); |
va009039 | 0:db4242c89949 | 15 | } |
va009039 | 0:db4242c89949 | 16 | |
va009039 | 0:db4242c89949 | 17 | int DHCPClient::offer_ack(uint8_t buf[], int size) { |
va009039 | 0:db4242c89949 | 18 | memcpy(yiaddr, &buf[DHCP_OFFSET_YIADDR], 4); |
va009039 | 0:db4242c89949 | 19 | uint8_t *p; |
va009039 | 0:db4242c89949 | 20 | int msg_type = -1; |
va009039 | 0:db4242c89949 | 21 | p = buf + DHCP_OFFSET_OPTIONS; |
va009039 | 0:db4242c89949 | 22 | while(*p != 0xff && p < (uint8_t*)&buf[DHCP_MAX_PACKET_SIZE]) { |
va009039 | 0:db4242c89949 | 23 | int code = *p++; |
va009039 | 0:db4242c89949 | 24 | if (code == 0x00) { |
va009039 | 0:db4242c89949 | 25 | continue; |
va009039 | 0:db4242c89949 | 26 | } |
va009039 | 0:db4242c89949 | 27 | int len = *p++; |
va009039 | 0:db4242c89949 | 28 | #ifdef DHCP_VERBOSE |
va009039 | 0:db4242c89949 | 29 | char codeStr[24]; |
va009039 | 0:db4242c89949 | 30 | snprintf(codeStr, sizeof(codeStr), "DHCP option: %d", code); |
va009039 | 0:db4242c89949 | 31 | printfBytes(codeStr, p, len); |
va009039 | 0:db4242c89949 | 32 | #endif //DHCP_VERBOSE |
va009039 | 0:db4242c89949 | 33 | if (code == 53) { |
va009039 | 0:db4242c89949 | 34 | msg_type = *p; |
va009039 | 0:db4242c89949 | 35 | } else if (code == 1) { |
va009039 | 0:db4242c89949 | 36 | memcpy(netmask, p, 4); // Subnet mask address |
va009039 | 0:db4242c89949 | 37 | } else if (code == 3) { |
va009039 | 0:db4242c89949 | 38 | memcpy(gateway, p, 4); // Gateway IP address |
va009039 | 0:db4242c89949 | 39 | } else if (code == 6) {// DNS |
va009039 | 0:db4242c89949 | 40 | memcpy(dnsaddr, p, 4); |
va009039 | 0:db4242c89949 | 41 | } |
va009039 | 0:db4242c89949 | 42 | p += len; |
va009039 | 0:db4242c89949 | 43 | } |
va009039 | 0:db4242c89949 | 44 | return msg_type; |
va009039 | 0:db4242c89949 | 45 | } |
va009039 | 0:db4242c89949 | 46 | |
va009039 | 0:db4242c89949 | 47 | void DHCPClient::callback(UDPSocketEvent e) |
va009039 | 0:db4242c89949 | 48 | { |
va009039 | 0:db4242c89949 | 49 | PRINT_FUNC(); |
va009039 | 0:db4242c89949 | 50 | uint8_t buf[DHCP_MAX_PACKET_SIZE]; |
va009039 | 0:db4242c89949 | 51 | Host host; |
va009039 | 0:db4242c89949 | 52 | int len = p_udp->recvfrom((char*)buf, sizeof(buf), &host); |
va009039 | 0:db4242c89949 | 53 | if (!verify(buf, len)) { |
va009039 | 0:db4242c89949 | 54 | return; |
va009039 | 0:db4242c89949 | 55 | } |
va009039 | 0:db4242c89949 | 56 | int r = offer_ack(buf, len); |
va009039 | 0:db4242c89949 | 57 | if (r == 2) { // OFFER |
va009039 | 0:db4242c89949 | 58 | request(buf, 300); |
va009039 | 0:db4242c89949 | 59 | Host server(IpAddr(255,255,255,255), 67); // DHCP broadcast |
va009039 | 0:db4242c89949 | 60 | p_udp->sendto((char*)buf, 300, &server); |
va009039 | 0:db4242c89949 | 61 | } else if (r == 5) { // ACK |
va009039 | 0:db4242c89949 | 62 | exit_flag = true; |
va009039 | 0:db4242c89949 | 63 | } |
va009039 | 0:db4242c89949 | 64 | } |
va009039 | 0:db4242c89949 | 65 | |
va009039 | 0:db4242c89949 | 66 | int DHCPClient::setup(int timeout_ms) |
va009039 | 0:db4242c89949 | 67 | { |
va009039 | 0:db4242c89949 | 68 | Timer t; |
va009039 | 0:db4242c89949 | 69 | t.start(); |
va009039 | 0:db4242c89949 | 70 | p_udp = new MyUDPSocket; |
va009039 | 0:db4242c89949 | 71 | p_udp->setOnEvent(_DHCP_OnEvent); |
va009039 | 0:db4242c89949 | 72 | Host local(IpAddr(0,0,0,0), 68); |
va009039 | 0:db4242c89949 | 73 | Host server(IpAddr(255,255,255,255), 67); // DHCP broadcast |
va009039 | 0:db4242c89949 | 74 | p_udp->bind(local); |
va009039 | 0:db4242c89949 | 75 | uint8_t buf[300]; |
va009039 | 0:db4242c89949 | 76 | discover(buf, sizeof(buf)); |
va009039 | 0:db4242c89949 | 77 | p_udp->sendto((char*)buf, sizeof(buf), &server); |
va009039 | 0:db4242c89949 | 78 | exit_flag = false; |
va009039 | 0:db4242c89949 | 79 | int err = 0; |
va009039 | 0:db4242c89949 | 80 | while(1) { |
va009039 | 0:db4242c89949 | 81 | p_udp->poll(); |
va009039 | 0:db4242c89949 | 82 | if (exit_flag) { |
va009039 | 0:db4242c89949 | 83 | break; |
va009039 | 0:db4242c89949 | 84 | } |
va009039 | 0:db4242c89949 | 85 | if (t.read_ms() > timeout_ms) { |
va009039 | 0:db4242c89949 | 86 | err = -1; |
va009039 | 0:db4242c89949 | 87 | break; |
va009039 | 0:db4242c89949 | 88 | } |
va009039 | 0:db4242c89949 | 89 | #ifdef DEBUG |
va009039 | 0:db4242c89949 | 90 | wait_ms(100); |
va009039 | 0:db4242c89949 | 91 | #endif //DEBUG |
va009039 | 0:db4242c89949 | 92 | } |
va009039 | 0:db4242c89949 | 93 | delete p_udp; |
va009039 | 0:db4242c89949 | 94 | return err; |
va009039 | 0:db4242c89949 | 95 | } |
va009039 | 0:db4242c89949 | 96 | |
va009039 | 0:db4242c89949 | 97 | DHCPClient::DHCPClient() |
va009039 | 0:db4242c89949 | 98 | { |
va009039 | 0:db4242c89949 | 99 | _g_dhcp = this; |
va009039 | 0:db4242c89949 | 100 | } |