WIZNet W5500 with additional enhancements

Fork of WIZnetInterface by WIZnet

Committer:
Helmut Tschemernjak
Date:
Thu Oct 12 12:19:11 2017 +0200
Revision:
38:67e763cdde02
Parent:
34:7d44648ec5f2
Enable Interrupts for all sockets by default.
Added a Soft-Reset in the reset() functions which works perfect
when no Reset line is connected.

Who changed what in which revision?

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