/** *@brief 读取数据 *@param RData:读取数据存放数组 *@return 无 */ void RJ45_2_Read(u8 *RData) { u16 Start_Address; u32 Address; RJ45_2_Read_Buf(Sn_RX_RSR0(0),ReadTem,2); RJ45_2_RLength =ReadTem[0]*256+ReadTem[1]; //获取接收到数据长度 RJ45_2_Read_Buf(Sn_RX_RD0(0),ReadTem,2); Start_Address=ReadTem[0]*256+ReadTem[1]; //获取相对地址 WriteTem[0]=(Start_Address+RJ45_2_RLength)/256; WriteTem[1]=(Start_Address+RJ45_2_RLength)%256; Address=(u32)(Start_Address<<8)+(0<<5)+0x18; //得到绝对地址 RJ45_2_Read_Buf(Address,RData,RJ45_2_RLength); //读取数据 RJ45_2_Write_Buf(Sn_RX_RD0(0),WriteTem,2); //写入读取指针 RJ45_2_Write_Register(Sn_CR(0),Sn_CR_RECV); while(RJ45_2_Read_Register(Sn_CR(0))); /*Wait to process the command*/ }
// return value: // A DNSError_t (DNSSuccess on success, something else otherwise) // in "int" mode: positive on success, negative on error DNSError_t EthernetDNSClass::pollDNSReply(byte ipAddr[4]) { DNSError_t statusCode = DNSSuccess; #if defined(_USE_MALLOC_) DNSHeader_t* dnsHeader = NULL; #else DNSHeader_t dnsHeaderBuf; DNSHeader_t* dnsHeader = &dnsHeaderBuf; #endif uint8_t* buf; uint32_t svr_addr; uint16_t svr_port, udp_len, ptr, qCnt, aCnt; if (DNSStateQuerySent != this->_state) { statusCode = DNSNothingToDo; goto errorReturn; } if (NULL == ipAddr) { statusCode = DNSInvalidArgument; goto errorReturn; } if (0 == (IINCHIP_READ(Sn_RX_RSR0(this->_socket))) && 0 == (IINCHIP_READ(Sn_RX_RSR0(this->_socket) + 1))) { statusCode = DNSTryLater; goto errorReturn; } #if defined(_USE_MALLOC_) dnsHeader = (DNSHeader_t*)malloc(sizeof(DNSHeader_t)); if (NULL == dnsHeader) { statusCode = DNSOutOfMemory; goto errorReturn; } #endif ptr = IINCHIP_READ(Sn_RX_RD0(this->_socket)); ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(this->_socket) + 1); // read UDP header buf = (uint8_t*)dnsHeader; read_data(this->_socket, (vuint8*)ptr, (vuint8*)buf, 8); ptr += 8; memcpy(&svr_addr, buf, sizeof(uint32_t)); *((uint16_t*)&svr_port) = dns_ntohs(*((uint32_t*)(buf+4))); *((uint16_t*)&udp_len) = dns_ntohs(*((uint32_t*)(buf+6))); read_data(this->_socket, (vuint8*)ptr, (vuint8*)dnsHeader, sizeof(DNSHeader_t)); if (0 != dnsHeader->responseCode) { if (3 == dnsHeader->responseCode) statusCode = DNSNotFound; else statusCode = DNSServerError; goto errorReturn; } dnsHeader->xid = dns_ntohs(dnsHeader->xid); qCnt = dns_ntohs(dnsHeader->queryCount); aCnt = dns_ntohs(dnsHeader->answerCount); if (dnsHeader->queryResponse && DNSOpQuery == dnsHeader->opCode && DNS_SERVER_PORT == svr_port && this->_dnsData.lastQueryFirstXid <= dnsHeader->xid && this->_dnsData.xid >= dnsHeader->xid && 0 == memcmp(&svr_addr, this->_dnsData.serverIpAddr, sizeof(uint32_t))) { statusCode = DNSServerError; // if we don't find our A record answer, the server messed up. int i, offset = sizeof(DNSHeader_t); uint8_t* buf = (uint8_t*)dnsHeader; int rLen; // read over the query section and answer section, stop on the first a record for (i=0; i<qCnt+aCnt; i++) { do { read_data(this->_socket, (vuint8*)(ptr+offset), (vuint8*)buf, 1); rLen = buf[0]; if (rLen > 128) // handle DNS name compression offset += 2; else offset += rLen + 1; } while (rLen > 0 && rLen <= 128); // if this is an answer record, there are more fields to it. if (i >= qCnt) { read_data(this->_socket, (vuint8*)(ptr+offset), (vuint8*)buf, 4); offset += 8; // skip over the 4-byte TTL field read_data(this->_socket, (vuint8*)(ptr+offset), (vuint8*)&buf[4], 2); offset += 2; // if class and qtype match, and data length is 4, this is an IP address, and // we're done. if (1 == buf[1] && 1 == buf[3] && 4 == buf[5]) { read_data(this->_socket, (vuint8*)(ptr+offset), (vuint8*)ipAddr, 4); statusCode = DNSSuccess; break; } } else offset += 4; // eat the query type and class fields of a query } } ptr += udp_len; IINCHIP_WRITE(Sn_RX_RD0(this->_socket),(vuint8)((ptr & 0xff00) >> 8)); IINCHIP_WRITE((Sn_RX_RD0(this->_socket) + 1),(vuint8)(ptr & 0x00ff)); IINCHIP_WRITE(Sn_CR(this->_socket),Sn_CR_RECV); while(IINCHIP_READ(Sn_CR(this->_socket))); errorReturn: if (DNSTryLater == statusCode) { unsigned long now = millis(); if (now - this->_lastSendMillis > DNS_TIMEOUT_MILLIS || now < this->_lastSendMillis) { this->_state = DNSStateIdle; statusCode = DNSTimedOut; } } else { this->_closeDNSSession(); this->_state = DNSStateIdle; } #if defined(_USE_MALLOC_) if (NULL != dnsHeader) free(dnsHeader); #endif return statusCode; }