Beispiel #1
0
/**
@brief	This function is an application I/F function which is used to receive the data in other then
	TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well. 
	
@return	This function return received data size for success else -1.
*/ 
uint16 recvfrom(
	SOCKET s,	/**< the socket number */
	uint8 * buf,	/**< a pointer to copy the data to be received */
	uint16 len,		/**< the data size to read */
	uint8 * addr,	/**< a pointer to store the peer's IP address */
	uint16 *port	/**< a pointer to store the peer's port number. */
	)
{
	uint8 head[8];
	uint16 data_len=0;
	uint16 ptr=0;

	if ( len > 0 )
	{
		ptr = wiz_read_word(Sn_RX_RD0(s));
		switch (wiz_read_byte(Sn_MR(s)) & 0x07)
		{
		case Sn_MR_UDP :
			read_data(s, (uint8 *)ptr, head, 0x08);
			ptr += 8;
			// read peer's IP address, port number.
			addr[0] = head[0];
			addr[1] = head[1];
			addr[2] = head[2];
			addr[3] = head[3];
			*port = (head[4] << 8) + head[5];
			data_len = (head[6] << 8) + head[7];
			break;
	
		case Sn_MR_IPRAW :
			read_data(s, (uint8 *)ptr, head, 0x06);
			ptr += 6;
			addr[0] = head[0];
			addr[1] = head[1];
			addr[2] = head[2];
			addr[3] = head[3];
			data_len = (head[4] << 8) + head[5];
			break;

		case Sn_MR_MACRAW :
			read_data(s, (uint8 *)ptr, head, 2);
			ptr += 2;
			data_len = (head[0]<<8) + head[1] - 2;
			break;

		default :
			break;
		}
		read_data(s,(uint8*) ptr,buf,data_len); // Does nothing if data_len = 0
		ptr += data_len;
		wiz_write_word(Sn_RX_RD0(s),ptr);
		wiz_write_byte(Sn_CR(s),Sn_CR_RECV);
		while( wiz_read_byte(Sn_CR(s)) ) 
			;
	}
	return data_len;
}
Beispiel #2
0
/**
*@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*/
}
Beispiel #3
0
// 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;
}