WIZ820io(W5200) network interface、EthernetNetIf compatible.

/media/uploads/va009039/wiz820ionetif.jpg

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();
    }
}
Revision:
0:bdeec5f86894
Child:
1:22b9052d864d
diff -r 000000000000 -r bdeec5f86894 MyNetDnsRequest.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MyNetDnsRequest.cpp	Fri Mar 22 11:51:24 2013 +0000
@@ -0,0 +1,199 @@
+// MyNetDnsRequest.cpp 2012/4/22
+#include "mbed.h"
+#include "MyNetDnsRequest.h"
+#include "UDPSocket.h"
+#include <string>
+#include "dnsname.h"
+#include "W5200NetIf.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
+
+
+MyNetDnsRequest::MyNetDnsRequest(const char* hostname) : NetDnsRequest(hostname), 
+    m_state(MYNETDNS_START), m_cbFired(false), m_closing(false), m_udp(NULL) {
+    PRINT_FUNC();
+}
+
+MyNetDnsRequest::MyNetDnsRequest(Host* pHost) : NetDnsRequest(pHost), 
+    m_state(MYNETDNS_START), m_cbFired(false), m_closing(false), m_udp(NULL) {
+    PRINT_FUNC();
+}
+
+MyNetDnsRequest::~MyNetDnsRequest() {
+    PRINT_FUNC();
+    if (m_udp) {
+        delete m_udp;
+    }
+}
+
+void MyNetDnsRequest::callback(UDPSocketEvent e)
+{
+    PRINT_FUNC();
+    DBG2("m_id[]=%02x:%02x\n", m_id[0], m_id[1]);
+    uint8_t buf[512];
+    Host host;
+    int len = m_udp->recvfrom((char*)buf, sizeof(buf), &host);
+    if (memcmp(buf+0, m_id, 2) != 0) { //verify
+        return;
+    }
+    int rcode = response(buf, len);
+    if (rcode == 0) {
+        m_state = MYNETDNS_OK;
+    } else {
+        m_state = MYNETDNS_NOTFOUND;
+    }
+}
+
+int MyNetDnsRequest::response(uint8_t buf[], int size) {
+    PRINT_FUNC();
+#ifdef DEBUG
+    printHex(buf, size);
+#endif //DEBUG
+    int rcode = buf[3] & 0x0f;
+    if (rcode != 0) {
+        return rcode;
+    }
+    int qdcount = buf[4]<<8|buf[5];
+    int ancount = buf[6]<<8|buf[7];
+    int pos = 12;
+    while(qdcount-- > 0) {
+        dnsname qname(buf);
+        pos = qname.decode(pos); // qname
+        pos += 4; // qtype qclass
+    }
+    while(ancount-- > 0) {
+        dnsname name(buf);
+        pos = name.decode(pos); // name
+        int type = buf[pos]<<8|buf[pos+1];
+        pos += 8; // type class TTL  
+        int rdlength = buf[pos]<<8|buf[pos+1]; pos += 2;
+        int rdata_pos = pos;
+        pos += rdlength;
+        if (type == 1) { // A record
+            m_ip = IpAddr(buf[rdata_pos],buf[rdata_pos+1],buf[rdata_pos+2],buf[rdata_pos+3]);
+        }
+#ifdef DEBUG
+        printf("%s", name.str.c_str());
+        if (type == 1) {
+            printf(" A %d.%d.%d.%d\n", 
+                buf[rdata_pos],buf[rdata_pos+1],buf[rdata_pos+2],buf[rdata_pos+3]);
+        } else if (type == 5) {
+            dnsname rdname(buf);
+            rdname.decode(rdata_pos);
+            printf(" CNAME %s\n", rdname.str.c_str());
+        } else {
+            printf(" TYPE:%d", type);
+            printfBytes(" RDATA:", &buf[rdata_pos], rdlength);
+        }
+#endif //DEBUG
+    }
+    return rcode;
+}
+
+int MyNetDnsRequest::query(uint8_t buf[], int size, const char* hostname) {
+    PRINT_FUNC();
+    const uint8_t header[] = {
+        0x00,0x00,0x01,0x00, // id=0x0000 QR=0 rd=1 opcode=0 rcode=0
+        0x00,0x01,0x00,0x00, // qdcount=1 ancount=0
+        0x00,0x00,0x00,0x00};// nscount=0 arcount=0 
+    const uint8_t tail[] = {0x00,0x01,0x00,0x01}; // qtype=A qclass=IN
+    memcpy(buf, header, sizeof(header));
+    int t = clock();
+    m_id[0] = t>>8;
+    m_id[1] = t;
+    memcpy(buf, m_id, 2); 
+    dnsname qname(buf);
+    int pos = qname.encode(sizeof(header), (char*)hostname);
+    memcpy(buf+pos, tail, sizeof(tail));
+    pos += sizeof(tail);
+    return pos;
+}
+
+void MyNetDnsRequest::resolve(const char* hostname) {
+    PRINT_FUNC();
+    if (m_udp == NULL) {
+        m_udp = new UDPSocket;
+    }
+    m_udp->setOnEvent(this, &MyNetDnsRequest::callback);
+    Host local(IpAddr(0,0,0,0), 1024 + rand()&0x7fff);
+    IpAddr dns(8,8,8,8);
+    NetIf* pIf = Net::getDefaultIf();
+    if (pIf) {
+        dns = ((W5200NetIf*)pIf)->m_dns;
+    }
+    Host server(dns, 53); // DNS
+    m_udp->bind(local);
+    uint8_t buf[256];                
+    int size = query(buf, sizeof(buf), hostname);
+#ifdef DEBUG
+    printf("hostname:[%s]\n", hostname);
+    printHex(buf, size);
+#endif
+    m_udp->sendto((char*)buf, size, &server);
+    m_interval.reset();
+    m_interval.start();
+}
+
+void MyNetDnsRequest::poll() {
+    PRINT_FUNC();
+#ifdef DEBUG
+    printf("%p m_state: %d, m_udp: %p\n", this, m_state, m_udp);
+    wait_ms(400);
+#endif //DEBUG
+    switch(m_state) {
+        case MYNETDNS_START:
+            m_retry = 0;
+            resolve(m_hostname);
+            m_state = MYNETDNS_PROCESSING;
+            break;
+        case MYNETDNS_PROCESSING: 
+            break;
+        case MYNETDNS_NOTFOUND: 
+            onReply(NETDNS_FOUND); 
+            break;
+        case MYNETDNS_ERROR: 
+            onReply(NETDNS_ERROR);
+            break;
+        case MYNETDNS_OK:
+            DBG2("m_retry=%d, m_interval=%d\n", m_retry, m_interval.read_ms());
+            onReply(NETDNS_FOUND); 
+            break;
+    }
+    if (m_interval.read_ms() > 1000) {
+        m_interval.stop();
+        DBG2("timeout m_retry=%d\n", m_retry);
+        if (++m_retry >= 2) {
+            m_state = MYNETDNS_ERROR;
+        } else {
+            resolve(m_hostname);
+            m_state = MYNETDNS_PROCESSING;
+        }
+    }
+    if(m_closing && (m_state!=MYNETDNS_PROCESSING)) {
+        NetDnsRequest::close();
+    }
+}
+
+void MyNetDnsRequest::close() {
+    PRINT_FUNC();
+    if(m_state != MYNETDNS_PROCESSING) {
+        NetDnsRequest::close();
+    } else {
+        m_closing = true;
+    }
+}