W5200(WIZ820io) network interface

Committer:
va009039
Date:
Thu Apr 19 11:14:43 2012 +0000
Revision:
2:a8df39b4f3aa
Parent:
1:803123933c5a

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 2:a8df39b4f3aa 1 // MyNetDnsRequest.cpp 2012/4/19
va009039 0:61831b843b44 2 #include "mbed.h"
va009039 0:61831b843b44 3 #include "MyNetDnsRequest.h"
va009039 0:61831b843b44 4 #include "UDPSocket.h"
va009039 0:61831b843b44 5 #include <string>
va009039 0:61831b843b44 6 #include "dnsname.h"
va009039 2:a8df39b4f3aa 7 #include "W5200NetIf.h"
va009039 2:a8df39b4f3aa 8 //#define __DEBUG
va009039 2:a8df39b4f3aa 9 #include "dbg/dbg.h"
va009039 2:a8df39b4f3aa 10
va009039 2:a8df39b4f3aa 11 #ifdef __DEBUG
va009039 2:a8df39b4f3aa 12 #define DBG2(...) do{ DebugStream::debug("%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); DebugStream::debug(__VA_ARGS__); } while(0);
va009039 2:a8df39b4f3aa 13 #else
va009039 2:a8df39b4f3aa 14 #define DBG2(...) while(0);
va009039 2:a8df39b4f3aa 15 #endif //__DEBUG
va009039 0:61831b843b44 16
va009039 0:61831b843b44 17 //#define DEBUG
va009039 0:61831b843b44 18
va009039 0:61831b843b44 19 #ifdef DEBUG
va009039 0:61831b843b44 20 #include "Utils.h"
va009039 0:61831b843b44 21 #define PRINT_FUNC() printf("%p %d:%s\n", this,__LINE__,__PRETTY_FUNCTION__)
va009039 0:61831b843b44 22 #else //DEBUG
va009039 0:61831b843b44 23 #define PRINT_FUNC()
va009039 0:61831b843b44 24 #endif //DEBUG
va009039 0:61831b843b44 25
va009039 0:61831b843b44 26
va009039 0:61831b843b44 27 MyNetDnsRequest::MyNetDnsRequest(const char* hostname) : NetDnsRequest(hostname),
va009039 0:61831b843b44 28 m_state(MYNETDNS_START), m_cbFired(false), m_closing(false), m_udp(NULL) {
va009039 0:61831b843b44 29 PRINT_FUNC();
va009039 0:61831b843b44 30 }
va009039 0:61831b843b44 31
va009039 0:61831b843b44 32 MyNetDnsRequest::MyNetDnsRequest(Host* pHost) : NetDnsRequest(pHost),
va009039 0:61831b843b44 33 m_state(MYNETDNS_START), m_cbFired(false), m_closing(false), m_udp(NULL) {
va009039 0:61831b843b44 34 PRINT_FUNC();
va009039 0:61831b843b44 35 }
va009039 0:61831b843b44 36
va009039 0:61831b843b44 37 MyNetDnsRequest::~MyNetDnsRequest() {
va009039 0:61831b843b44 38 PRINT_FUNC();
va009039 0:61831b843b44 39 if (m_udp) {
va009039 0:61831b843b44 40 delete m_udp;
va009039 0:61831b843b44 41 }
va009039 0:61831b843b44 42 }
va009039 0:61831b843b44 43
va009039 0:61831b843b44 44 void MyNetDnsRequest::callback(UDPSocketEvent e)
va009039 0:61831b843b44 45 {
va009039 0:61831b843b44 46 PRINT_FUNC();
va009039 2:a8df39b4f3aa 47 DBG2("m_id[]=%02x:%02x\n", m_id[0], m_id[1]);
va009039 0:61831b843b44 48 uint8_t buf[512];
va009039 0:61831b843b44 49 Host host;
va009039 0:61831b843b44 50 int len = m_udp->recvfrom((char*)buf, sizeof(buf), &host);
va009039 2:a8df39b4f3aa 51 if (memcmp(buf+0, m_id, 2) != 0) { //verify
va009039 0:61831b843b44 52 return;
va009039 0:61831b843b44 53 }
va009039 0:61831b843b44 54 int rcode = response(buf, len);
va009039 0:61831b843b44 55 if (rcode == 0) {
va009039 0:61831b843b44 56 m_state = MYNETDNS_OK;
va009039 0:61831b843b44 57 } else {
va009039 0:61831b843b44 58 m_state = MYNETDNS_NOTFOUND;
va009039 0:61831b843b44 59 }
va009039 0:61831b843b44 60 }
va009039 0:61831b843b44 61
va009039 0:61831b843b44 62 int MyNetDnsRequest::response(uint8_t buf[], int size) {
va009039 0:61831b843b44 63 PRINT_FUNC();
va009039 0:61831b843b44 64 #ifdef DEBUG
va009039 0:61831b843b44 65 printHex(buf, size);
va009039 0:61831b843b44 66 #endif //DEBUG
va009039 0:61831b843b44 67 int rcode = buf[3] & 0x0f;
va009039 0:61831b843b44 68 if (rcode != 0) {
va009039 0:61831b843b44 69 return rcode;
va009039 0:61831b843b44 70 }
va009039 0:61831b843b44 71 int qdcount = buf[4]<<8|buf[5];
va009039 0:61831b843b44 72 int ancount = buf[6]<<8|buf[7];
va009039 0:61831b843b44 73 int pos = 12;
va009039 0:61831b843b44 74 while(qdcount-- > 0) {
va009039 0:61831b843b44 75 dnsname qname(buf);
va009039 0:61831b843b44 76 pos = qname.decode(pos); // qname
va009039 0:61831b843b44 77 pos += 4; // qtype qclass
va009039 0:61831b843b44 78 }
va009039 0:61831b843b44 79 while(ancount-- > 0) {
va009039 0:61831b843b44 80 dnsname name(buf);
va009039 0:61831b843b44 81 pos = name.decode(pos); // name
va009039 0:61831b843b44 82 int type = buf[pos]<<8|buf[pos+1];
va009039 0:61831b843b44 83 pos += 8; // type class TTL
va009039 0:61831b843b44 84 int rdlength = buf[pos]<<8|buf[pos+1]; pos += 2;
va009039 0:61831b843b44 85 int rdata_pos = pos;
va009039 0:61831b843b44 86 pos += rdlength;
va009039 0:61831b843b44 87 if (type == 1) { // A record
va009039 0:61831b843b44 88 m_ip = IpAddr(buf[rdata_pos],buf[rdata_pos+1],buf[rdata_pos+2],buf[rdata_pos+3]);
va009039 0:61831b843b44 89 }
va009039 0:61831b843b44 90 #ifdef DEBUG
va009039 0:61831b843b44 91 printf("%s", name.str.c_str());
va009039 0:61831b843b44 92 if (type == 1) {
va009039 0:61831b843b44 93 printf(" A %d.%d.%d.%d\n",
va009039 0:61831b843b44 94 buf[rdata_pos],buf[rdata_pos+1],buf[rdata_pos+2],buf[rdata_pos+3]);
va009039 0:61831b843b44 95 } else if (type == 5) {
va009039 0:61831b843b44 96 dnsname rdname(buf);
va009039 0:61831b843b44 97 rdname.decode(rdata_pos);
va009039 0:61831b843b44 98 printf(" CNAME %s\n", rdname.str.c_str());
va009039 0:61831b843b44 99 } else {
va009039 0:61831b843b44 100 printf(" TYPE:%d", type);
va009039 0:61831b843b44 101 printfBytes(" RDATA:", &buf[rdata_pos], rdlength);
va009039 0:61831b843b44 102 }
va009039 0:61831b843b44 103 #endif //DEBUG
va009039 0:61831b843b44 104 }
va009039 0:61831b843b44 105 return rcode;
va009039 0:61831b843b44 106 }
va009039 0:61831b843b44 107
va009039 0:61831b843b44 108 int MyNetDnsRequest::query(uint8_t buf[], int size, const char* hostname) {
va009039 0:61831b843b44 109 PRINT_FUNC();
va009039 0:61831b843b44 110 const uint8_t header[] = {
va009039 0:61831b843b44 111 0x00,0x00,0x01,0x00, // id=0x0000 QR=0 rd=1 opcode=0 rcode=0
va009039 0:61831b843b44 112 0x00,0x01,0x00,0x00, // qdcount=1 ancount=0
va009039 0:61831b843b44 113 0x00,0x00,0x00,0x00};// nscount=0 arcount=0
va009039 0:61831b843b44 114 const uint8_t tail[] = {0x00,0x01,0x00,0x01}; // qtype=A qclass=IN
va009039 0:61831b843b44 115 memcpy(buf, header, sizeof(header));
va009039 0:61831b843b44 116 int t = clock();
va009039 0:61831b843b44 117 m_id[0] = t>>8;
va009039 0:61831b843b44 118 m_id[1] = t;
va009039 0:61831b843b44 119 memcpy(buf, m_id, 2);
va009039 0:61831b843b44 120 dnsname qname(buf);
va009039 0:61831b843b44 121 int pos = qname.encode(sizeof(header), (char*)hostname);
va009039 0:61831b843b44 122 memcpy(buf+pos, tail, sizeof(tail));
va009039 0:61831b843b44 123 pos += sizeof(tail);
va009039 0:61831b843b44 124 return pos;
va009039 0:61831b843b44 125 }
va009039 0:61831b843b44 126
va009039 0:61831b843b44 127 void MyNetDnsRequest::resolve(const char* hostname) {
va009039 0:61831b843b44 128 PRINT_FUNC();
va009039 0:61831b843b44 129 if (m_udp == NULL) {
va009039 0:61831b843b44 130 m_udp = new UDPSocket;
va009039 0:61831b843b44 131 }
va009039 0:61831b843b44 132 m_udp->setOnEvent(this, &MyNetDnsRequest::callback);
va009039 1:803123933c5a 133 Host local(IpAddr(0,0,0,0), 1024 + rand()&0x7fff);
va009039 1:803123933c5a 134 IpAddr dns(8,8,8,8);
va009039 1:803123933c5a 135 NetIf* pIf = Net::getDefaultIf();
va009039 1:803123933c5a 136 if (pIf) {
va009039 2:a8df39b4f3aa 137 dns = ((W5200NetIf*)pIf)->m_dns;
va009039 1:803123933c5a 138 }
va009039 1:803123933c5a 139 Host server(dns, 53); // DNS
va009039 0:61831b843b44 140 m_udp->bind(local);
va009039 0:61831b843b44 141 uint8_t buf[256];
va009039 0:61831b843b44 142 int size = query(buf, sizeof(buf), hostname);
va009039 0:61831b843b44 143 #ifdef DEBUG
va009039 0:61831b843b44 144 printf("hostname:[%s]\n", hostname);
va009039 0:61831b843b44 145 printHex(buf, size);
va009039 0:61831b843b44 146 #endif
va009039 0:61831b843b44 147 m_udp->sendto((char*)buf, size, &server);
va009039 2:a8df39b4f3aa 148 m_interval.reset();
va009039 2:a8df39b4f3aa 149 m_interval.start();
va009039 0:61831b843b44 150 }
va009039 0:61831b843b44 151
va009039 0:61831b843b44 152 void MyNetDnsRequest::poll() {
va009039 0:61831b843b44 153 PRINT_FUNC();
va009039 0:61831b843b44 154 #ifdef DEBUG
va009039 0:61831b843b44 155 printf("%p m_state: %d, m_udp: %p\n", this, m_state, m_udp);
va009039 0:61831b843b44 156 wait_ms(400);
va009039 0:61831b843b44 157 #endif //DEBUG
va009039 0:61831b843b44 158 switch(m_state) {
va009039 0:61831b843b44 159 case MYNETDNS_START:
va009039 2:a8df39b4f3aa 160 m_retry = 0;
va009039 0:61831b843b44 161 resolve(m_hostname);
va009039 0:61831b843b44 162 m_state = MYNETDNS_PROCESSING;
va009039 0:61831b843b44 163 break;
va009039 0:61831b843b44 164 case MYNETDNS_PROCESSING:
va009039 0:61831b843b44 165 break;
va009039 0:61831b843b44 166 case MYNETDNS_NOTFOUND:
va009039 0:61831b843b44 167 onReply(NETDNS_FOUND);
va009039 0:61831b843b44 168 break;
va009039 0:61831b843b44 169 case MYNETDNS_ERROR:
va009039 0:61831b843b44 170 onReply(NETDNS_ERROR);
va009039 0:61831b843b44 171 break;
va009039 0:61831b843b44 172 case MYNETDNS_OK:
va009039 2:a8df39b4f3aa 173 DBG2("m_retry=%d, m_interval=%d\n", m_retry, m_interval.read_ms());
va009039 0:61831b843b44 174 onReply(NETDNS_FOUND);
va009039 0:61831b843b44 175 break;
va009039 0:61831b843b44 176 }
va009039 2:a8df39b4f3aa 177 if (m_interval.read_ms() > 1000) {
va009039 2:a8df39b4f3aa 178 m_interval.stop();
va009039 2:a8df39b4f3aa 179 DBG2("timeout m_retry=%d\n", m_retry);
va009039 2:a8df39b4f3aa 180 if (++m_retry > 1) {
va009039 2:a8df39b4f3aa 181 m_state = MYNETDNS_ERROR;
va009039 2:a8df39b4f3aa 182 } else {
va009039 2:a8df39b4f3aa 183 resolve(m_hostname);
va009039 2:a8df39b4f3aa 184 m_state = MYNETDNS_PROCESSING;
va009039 2:a8df39b4f3aa 185 }
va009039 0:61831b843b44 186 }
va009039 0:61831b843b44 187 if(m_closing && (m_state!=MYNETDNS_PROCESSING)) {
va009039 0:61831b843b44 188 NetDnsRequest::close();
va009039 0:61831b843b44 189 }
va009039 0:61831b843b44 190 }
va009039 0:61831b843b44 191
va009039 0:61831b843b44 192 void MyNetDnsRequest::close() {
va009039 0:61831b843b44 193 PRINT_FUNC();
va009039 0:61831b843b44 194 if(m_state != MYNETDNS_PROCESSING) {
va009039 0:61831b843b44 195 NetDnsRequest::close();
va009039 0:61831b843b44 196 } else {
va009039 0:61831b843b44 197 m_closing = true;
va009039 0:61831b843b44 198 }
va009039 0:61831b843b44 199 }