W5200(WIZ820io) network interface

Committer:
va009039
Date:
Sat Apr 14 17:21:11 2012 +0000
Revision:
0:61831b843b44
Child:
1:803123933c5a

        

Who changed what in which revision?

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