W5200(WIZ820io) network interface

Committer:
va009039
Date:
Tue Apr 17 12:13:15 2012 +0000
Revision:
1:803123933c5a
Parent:
0:61831b843b44
Child:
2:a8df39b4f3aa

        

Who changed what in which revision?

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