WIZ820io(W5200) network interface、EthernetNetIf compatible.
example
#include "WIZ820ioNetIf.h" #include "HTTPClient.h" #include "HTTPServer.h" #if defined(TARGET_KL25Z) WIZ820ioNetIf eth(PTD2,PTD3,PTD1,PTD0,PTD5); #endif HTTPClient http; HTTPStream stream; void callback(HTTPResult r){ printf("callback %d %s\n", r, HTTPClient::ResultStr(r)); } int main() { int err = eth.setup(); if (err < 0) { printf("setup error %d\n", err); exit(-1); } HTTPServer svr; svr.addHandler<SimpleHandler>("/"); svr.bind(80); const char* uri = "http://va009039-mbed.appspot.com/kl25z/"; http.get(uri, &stream, callback); uint8_t buf[256]; int total = 0; stream.readNext(buf, sizeof(buf)); while(1) { if(stream.readable()) { int len = stream.readLen(); total += len; printf("%d %d\n", total, len); stream.readNext(buf, sizeof(buf)); } Net::poll(); } }
DHCPClient.cpp@1:22b9052d864d, 2013-03-24 (annotated)
- Committer:
- va009039
- Date:
- Sun Mar 24 11:25:31 2013 +0000
- Revision:
- 1:22b9052d864d
- Parent:
- 0:bdeec5f86894
WIZ820io(W8200) ethernet interface, EthernetNetIf compatible.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:bdeec5f86894 | 1 | // DHCPClient.cpp 2012/4/21 |
va009039 | 0:bdeec5f86894 | 2 | // DHCP Client for WIZ820io(W5200) |
va009039 | 0:bdeec5f86894 | 3 | #include "mbed.h" |
va009039 | 1:22b9052d864d | 4 | #include "w5200.h" |
va009039 | 1:22b9052d864d | 5 | //#include "UDPSocket.h" |
va009039 | 0:bdeec5f86894 | 6 | #include "DHCPClient.h" |
va009039 | 0:bdeec5f86894 | 7 | //#define __DEBUG |
va009039 | 0:bdeec5f86894 | 8 | #include "dbg/dbg.h" |
va009039 | 0:bdeec5f86894 | 9 | |
va009039 | 0:bdeec5f86894 | 10 | #ifdef __DEBUG |
va009039 | 0:bdeec5f86894 | 11 | #define DBG2(...) do{ DebugStream::debug("%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); DebugStream::debug(__VA_ARGS__); } while(0); |
va009039 | 0:bdeec5f86894 | 12 | #else |
va009039 | 0:bdeec5f86894 | 13 | #define DBG2(...) while(0); |
va009039 | 0:bdeec5f86894 | 14 | #endif //__DEBUG |
va009039 | 0:bdeec5f86894 | 15 | |
va009039 | 0:bdeec5f86894 | 16 | //#define DEBUG |
va009039 | 0:bdeec5f86894 | 17 | |
va009039 | 0:bdeec5f86894 | 18 | #ifdef DEBUG |
va009039 | 0:bdeec5f86894 | 19 | #include "Utils.h" |
va009039 | 0:bdeec5f86894 | 20 | #define PRINT_FUNC() printf("%p %d:%s\n", this,__LINE__,__PRETTY_FUNCTION__) |
va009039 | 0:bdeec5f86894 | 21 | #else //DEBUG |
va009039 | 0:bdeec5f86894 | 22 | #define PRINT_FUNC() |
va009039 | 0:bdeec5f86894 | 23 | #endif //DEBUG |
va009039 | 0:bdeec5f86894 | 24 | |
va009039 | 0:bdeec5f86894 | 25 | int DHCPClient::discover(uint8_t buf[], int size) { |
va009039 | 0:bdeec5f86894 | 26 | memset(buf, 0x00, size); |
va009039 | 0:bdeec5f86894 | 27 | const uint8_t headers[] = {0x01,0x01,0x06,0x00, |
va009039 | 0:bdeec5f86894 | 28 | 0x12,0x34,0x56,0x78}; // xid |
va009039 | 0:bdeec5f86894 | 29 | memcpy(buf, headers, sizeof(headers)); |
va009039 | 0:bdeec5f86894 | 30 | int t = clock(); |
va009039 | 0:bdeec5f86894 | 31 | xid[0] = t<<24; |
va009039 | 0:bdeec5f86894 | 32 | xid[1] = t<<16; |
va009039 | 0:bdeec5f86894 | 33 | xid[2] = t<<8; |
va009039 | 0:bdeec5f86894 | 34 | xid[3] = t; |
va009039 | 0:bdeec5f86894 | 35 | memcpy(buf+DHCP_OFFSET_XID, xid, 4); |
va009039 | 1:22b9052d864d | 36 | W5200.getMACAddress(buf+DHCP_OFFSET_CHADDR); |
va009039 | 0:bdeec5f86894 | 37 | const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie |
va009039 | 0:bdeec5f86894 | 38 | 0x35,0x01,0x01, // DHCP DISCOVER |
va009039 | 0:bdeec5f86894 | 39 | 0xff}; |
va009039 | 0:bdeec5f86894 | 40 | memcpy(buf+DHCP_OFFSET_MAGIC_COOKIE, options, sizeof(options)); |
va009039 | 0:bdeec5f86894 | 41 | uint8_t ip[4] = {0,0,0,0}; |
va009039 | 1:22b9052d864d | 42 | W5200.setIPAddress(ip); |
va009039 | 0:bdeec5f86894 | 43 | return DHCP_OFFSET_MAGIC_COOKIE + sizeof(options); |
va009039 | 0:bdeec5f86894 | 44 | } |
va009039 | 0:bdeec5f86894 | 45 | |
va009039 | 0:bdeec5f86894 | 46 | int DHCPClient::request(uint8_t buf[], int size) { |
va009039 | 0:bdeec5f86894 | 47 | memset(buf, 0x00, size); |
va009039 | 0:bdeec5f86894 | 48 | const uint8_t headers[] = {0x01,0x01,0x06,0x00, |
va009039 | 0:bdeec5f86894 | 49 | 0x12,0x34,0x56,0x78}; // xid |
va009039 | 0:bdeec5f86894 | 50 | memcpy(buf, headers, sizeof(headers)); |
va009039 | 0:bdeec5f86894 | 51 | memcpy(buf+DHCP_OFFSET_XID, xid, 4); |
va009039 | 0:bdeec5f86894 | 52 | memcpy(buf+DHCP_OFFSET_YIADDR, yiaddr, 4); |
va009039 | 1:22b9052d864d | 53 | W5200.getMACAddress(buf+DHCP_OFFSET_CHADDR); |
va009039 | 0:bdeec5f86894 | 54 | const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie |
va009039 | 0:bdeec5f86894 | 55 | 0x35,0x01,0x03, // DHCP REQUEST |
va009039 | 0:bdeec5f86894 | 56 | 0x32,0x04,0x00,0x00,0x00,0x00, // request IP |
va009039 | 0:bdeec5f86894 | 57 | 0xff}; |
va009039 | 0:bdeec5f86894 | 58 | memcpy(buf+DHCP_OFFSET_MAGIC_COOKIE, options, sizeof(options)); |
va009039 | 0:bdeec5f86894 | 59 | memcpy(buf+DHCP_OFFSET_MAGIC_COOKIE+9, yiaddr, 4); |
va009039 | 0:bdeec5f86894 | 60 | return DHCP_OFFSET_MAGIC_COOKIE + sizeof(options); |
va009039 | 0:bdeec5f86894 | 61 | } |
va009039 | 0:bdeec5f86894 | 62 | |
va009039 | 0:bdeec5f86894 | 63 | int DHCPClient::offer_ack(uint8_t buf[], int size) { |
va009039 | 0:bdeec5f86894 | 64 | memcpy(yiaddr, &buf[DHCP_OFFSET_YIADDR], 4); |
va009039 | 0:bdeec5f86894 | 65 | uint8_t *p; |
va009039 | 0:bdeec5f86894 | 66 | int msg_type = -1; |
va009039 | 0:bdeec5f86894 | 67 | p = buf + DHCP_OFFSET_OPTIONS; |
va009039 | 0:bdeec5f86894 | 68 | while(*p != 0xff && p < (uint8_t*)&buf[DHCP_MAX_PACKET_SIZE]) { |
va009039 | 0:bdeec5f86894 | 69 | int code = *p++; |
va009039 | 0:bdeec5f86894 | 70 | if (code == 0x00) { |
va009039 | 0:bdeec5f86894 | 71 | continue; |
va009039 | 0:bdeec5f86894 | 72 | } |
va009039 | 0:bdeec5f86894 | 73 | int len = *p++; |
va009039 | 0:bdeec5f86894 | 74 | #ifdef DEBUG |
va009039 | 0:bdeec5f86894 | 75 | char codeStr[24]; |
va009039 | 0:bdeec5f86894 | 76 | snprintf(codeStr, sizeof(codeStr), "DHCP option: %d", code); |
va009039 | 0:bdeec5f86894 | 77 | printfBytes(codeStr, p, len); |
va009039 | 0:bdeec5f86894 | 78 | #endif //DEBUG |
va009039 | 0:bdeec5f86894 | 79 | if (code == 53) { |
va009039 | 0:bdeec5f86894 | 80 | msg_type = *p; |
va009039 | 0:bdeec5f86894 | 81 | } else if (code == 1) { |
va009039 | 0:bdeec5f86894 | 82 | memcpy(netmask, p, 4); // Subnet mask address |
va009039 | 0:bdeec5f86894 | 83 | } else if (code == 3) { |
va009039 | 0:bdeec5f86894 | 84 | memcpy(gateway, p, 4); // Gateway IP address |
va009039 | 0:bdeec5f86894 | 85 | } else if (code == 6) {// DNS |
va009039 | 0:bdeec5f86894 | 86 | memcpy(dnsaddr, p, 4); |
va009039 | 0:bdeec5f86894 | 87 | } |
va009039 | 0:bdeec5f86894 | 88 | p += len; |
va009039 | 0:bdeec5f86894 | 89 | } |
va009039 | 0:bdeec5f86894 | 90 | return msg_type; |
va009039 | 0:bdeec5f86894 | 91 | } |
va009039 | 0:bdeec5f86894 | 92 | |
va009039 | 0:bdeec5f86894 | 93 | bool DHCPClient::verify(uint8_t buf[], int len) { |
va009039 | 0:bdeec5f86894 | 94 | if (len < DHCP_OFFSET_OPTIONS) { |
va009039 | 0:bdeec5f86894 | 95 | return false; |
va009039 | 0:bdeec5f86894 | 96 | } |
va009039 | 0:bdeec5f86894 | 97 | if (buf[DHCP_OFFSET_OP] != 0x02) { |
va009039 | 0:bdeec5f86894 | 98 | return false; |
va009039 | 0:bdeec5f86894 | 99 | } |
va009039 | 0:bdeec5f86894 | 100 | if (memcmp(buf+DHCP_OFFSET_XID, xid, 4) != 0) { |
va009039 | 0:bdeec5f86894 | 101 | return false; |
va009039 | 0:bdeec5f86894 | 102 | } |
va009039 | 0:bdeec5f86894 | 103 | return true; |
va009039 | 0:bdeec5f86894 | 104 | } |
va009039 | 0:bdeec5f86894 | 105 | |
va009039 | 0:bdeec5f86894 | 106 | void DHCPClient::callback(UDPSocketEvent e) |
va009039 | 0:bdeec5f86894 | 107 | { |
va009039 | 0:bdeec5f86894 | 108 | PRINT_FUNC(); |
va009039 | 0:bdeec5f86894 | 109 | uint8_t buf[DHCP_MAX_PACKET_SIZE]; |
va009039 | 0:bdeec5f86894 | 110 | Host host; |
va009039 | 0:bdeec5f86894 | 111 | int len = m_udp->recvfrom((char*)buf, sizeof(buf), &host); |
va009039 | 0:bdeec5f86894 | 112 | if (!verify(buf, len)) { |
va009039 | 0:bdeec5f86894 | 113 | return; |
va009039 | 0:bdeec5f86894 | 114 | } |
va009039 | 0:bdeec5f86894 | 115 | int r = offer_ack(buf, len); |
va009039 | 0:bdeec5f86894 | 116 | if (r == 2) { // OFFER |
va009039 | 0:bdeec5f86894 | 117 | request(buf, 300); |
va009039 | 0:bdeec5f86894 | 118 | Host server(IpAddr(255,255,255,255), 67); // DHCP broadcast |
va009039 | 0:bdeec5f86894 | 119 | m_udp->sendto((char*)buf, 300, &server); |
va009039 | 0:bdeec5f86894 | 120 | } else if (r == 5) { // ACK |
va009039 | 0:bdeec5f86894 | 121 | exit_flag = true; |
va009039 | 0:bdeec5f86894 | 122 | } |
va009039 | 0:bdeec5f86894 | 123 | } |
va009039 | 0:bdeec5f86894 | 124 | |
va009039 | 0:bdeec5f86894 | 125 | int DHCPClient::setup(int timeout_ms) |
va009039 | 0:bdeec5f86894 | 126 | { |
va009039 | 0:bdeec5f86894 | 127 | PRINT_FUNC(); |
va009039 | 0:bdeec5f86894 | 128 | int interval_ms = 2000; // 2000msec |
va009039 | 0:bdeec5f86894 | 129 | if (timeout_ms < interval_ms) { |
va009039 | 0:bdeec5f86894 | 130 | interval_ms = timeout_ms; |
va009039 | 0:bdeec5f86894 | 131 | } |
va009039 | 0:bdeec5f86894 | 132 | m_retry = 0; |
va009039 | 0:bdeec5f86894 | 133 | m_interval.start(); |
va009039 | 0:bdeec5f86894 | 134 | m_udp = new UDPSocket; |
va009039 | 0:bdeec5f86894 | 135 | m_udp->setOnEvent(this, &DHCPClient::callback); |
va009039 | 0:bdeec5f86894 | 136 | Host local(IpAddr(0,0,0,0), 68); |
va009039 | 0:bdeec5f86894 | 137 | Host server(IpAddr(255,255,255,255), 67); // DHCP broadcast |
va009039 | 0:bdeec5f86894 | 138 | m_udp->bind(local); |
va009039 | 0:bdeec5f86894 | 139 | uint8_t buf[300]; |
va009039 | 0:bdeec5f86894 | 140 | discover(buf, sizeof(buf)); |
va009039 | 0:bdeec5f86894 | 141 | m_udp->sendto((char*)buf, sizeof(buf), &server); |
va009039 | 0:bdeec5f86894 | 142 | m_interval.reset(); |
va009039 | 0:bdeec5f86894 | 143 | exit_flag = false; |
va009039 | 0:bdeec5f86894 | 144 | int err = 0; |
va009039 | 0:bdeec5f86894 | 145 | while(1) { |
va009039 | 0:bdeec5f86894 | 146 | Net::poll(); |
va009039 | 0:bdeec5f86894 | 147 | if (exit_flag) { |
va009039 | 0:bdeec5f86894 | 148 | DBG2("m_retry: %d, m_interval: %d\n", m_retry, m_interval.read_ms()); |
va009039 | 0:bdeec5f86894 | 149 | break; |
va009039 | 0:bdeec5f86894 | 150 | } |
va009039 | 0:bdeec5f86894 | 151 | if (m_interval.read_ms() > interval_ms) { |
va009039 | 0:bdeec5f86894 | 152 | DBG2("m_retry: %d\n", m_retry); |
va009039 | 0:bdeec5f86894 | 153 | if (++m_retry >= (timeout_ms/interval_ms)) { |
va009039 | 0:bdeec5f86894 | 154 | err = -1; |
va009039 | 0:bdeec5f86894 | 155 | break; |
va009039 | 0:bdeec5f86894 | 156 | } |
va009039 | 0:bdeec5f86894 | 157 | m_udp->sendto((char*)buf, sizeof(buf), &server); |
va009039 | 0:bdeec5f86894 | 158 | m_interval.reset(); |
va009039 | 0:bdeec5f86894 | 159 | } |
va009039 | 0:bdeec5f86894 | 160 | #ifdef DEBUG |
va009039 | 0:bdeec5f86894 | 161 | wait_ms(500); |
va009039 | 0:bdeec5f86894 | 162 | #endif //DEBUG |
va009039 | 0:bdeec5f86894 | 163 | } |
va009039 | 0:bdeec5f86894 | 164 | delete m_udp; |
va009039 | 0:bdeec5f86894 | 165 | return err; |
va009039 | 0:bdeec5f86894 | 166 | } |
va009039 | 0:bdeec5f86894 | 167 | |
va009039 | 0:bdeec5f86894 | 168 | DHCPClient::DHCPClient() { |
va009039 | 0:bdeec5f86894 | 169 | m_udp = NULL; |
va009039 | 0:bdeec5f86894 | 170 | } |