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(); } }
Diff: DHCPClient.cpp
- Revision:
- 0:bdeec5f86894
- Child:
- 1:22b9052d864d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DHCPClient.cpp Fri Mar 22 11:51:24 2013 +0000 @@ -0,0 +1,170 @@ +// DHCPClient.cpp 2012/4/21 +// DHCP Client for WIZ820io(W5200) +#include "mbed.h" +#include "w5100.h" +#include "UDPSocket.h" +#include "DHCPClient.h" +//#define __DEBUG +#include "dbg/dbg.h" + +#ifdef __DEBUG +#define DBG2(...) do{ DebugStream::debug("%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); DebugStream::debug(__VA_ARGS__); } while(0); +#else +#define DBG2(...) while(0); +#endif //__DEBUG + +//#define DEBUG + +#ifdef DEBUG +#include "Utils.h" +#define PRINT_FUNC() printf("%p %d:%s\n", this,__LINE__,__PRETTY_FUNCTION__) +#else //DEBUG +#define PRINT_FUNC() +#endif //DEBUG + +int DHCPClient::discover(uint8_t buf[], int size) { + memset(buf, 0x00, size); + const uint8_t headers[] = {0x01,0x01,0x06,0x00, + 0x12,0x34,0x56,0x78}; // xid + memcpy(buf, headers, sizeof(headers)); + int t = clock(); + xid[0] = t<<24; + xid[1] = t<<16; + xid[2] = t<<8; + xid[3] = t; + memcpy(buf+DHCP_OFFSET_XID, xid, 4); + W5100.getMACAddress(buf+DHCP_OFFSET_CHADDR); + const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie + 0x35,0x01,0x01, // DHCP DISCOVER + 0xff}; + memcpy(buf+DHCP_OFFSET_MAGIC_COOKIE, options, sizeof(options)); + uint8_t ip[4] = {0,0,0,0}; + W5100.setIPAddress(ip); + return DHCP_OFFSET_MAGIC_COOKIE + sizeof(options); +} + +int DHCPClient::request(uint8_t buf[], int size) { + memset(buf, 0x00, size); + const uint8_t headers[] = {0x01,0x01,0x06,0x00, + 0x12,0x34,0x56,0x78}; // xid + memcpy(buf, headers, sizeof(headers)); + memcpy(buf+DHCP_OFFSET_XID, xid, 4); + memcpy(buf+DHCP_OFFSET_YIADDR, yiaddr, 4); + W5100.getMACAddress(buf+DHCP_OFFSET_CHADDR); + const uint8_t options[] = {0x63,0x82,0x53,0x63, // magic cookie + 0x35,0x01,0x03, // DHCP REQUEST + 0x32,0x04,0x00,0x00,0x00,0x00, // request IP + 0xff}; + memcpy(buf+DHCP_OFFSET_MAGIC_COOKIE, options, sizeof(options)); + memcpy(buf+DHCP_OFFSET_MAGIC_COOKIE+9, yiaddr, 4); + return DHCP_OFFSET_MAGIC_COOKIE + sizeof(options); +} + +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 DEBUG + char codeStr[24]; + snprintf(codeStr, sizeof(codeStr), "DHCP option: %d", code); + printfBytes(codeStr, p, len); +#endif //DEBUG + 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; +} + +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(UDPSocketEvent e) +{ + PRINT_FUNC(); + uint8_t buf[DHCP_MAX_PACKET_SIZE]; + Host host; + int len = m_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 + m_udp->sendto((char*)buf, 300, &server); + } else if (r == 5) { // ACK + exit_flag = true; + } +} + +int DHCPClient::setup(int timeout_ms) +{ + PRINT_FUNC(); + int interval_ms = 2000; // 2000msec + if (timeout_ms < interval_ms) { + interval_ms = timeout_ms; + } + m_retry = 0; + m_interval.start(); + m_udp = new UDPSocket; + m_udp->setOnEvent(this, &DHCPClient::callback); + Host local(IpAddr(0,0,0,0), 68); + Host server(IpAddr(255,255,255,255), 67); // DHCP broadcast + m_udp->bind(local); + uint8_t buf[300]; + discover(buf, sizeof(buf)); + m_udp->sendto((char*)buf, sizeof(buf), &server); + m_interval.reset(); + exit_flag = false; + int err = 0; + while(1) { + Net::poll(); + if (exit_flag) { + DBG2("m_retry: %d, m_interval: %d\n", m_retry, m_interval.read_ms()); + break; + } + if (m_interval.read_ms() > interval_ms) { + DBG2("m_retry: %d\n", m_retry); + if (++m_retry >= (timeout_ms/interval_ms)) { + err = -1; + break; + } + m_udp->sendto((char*)buf, sizeof(buf), &server); + m_interval.reset(); + } +#ifdef DEBUG + wait_ms(500); +#endif //DEBUG + } + delete m_udp; + return err; +} + +DHCPClient::DHCPClient() { + m_udp = NULL; +}