コード例 #1
0
ファイル: tcp.c プロジェクト: GerarDZG/Embedded-Systems
uint8_t tcp_socket_init(TCP_CONFIG *config)
{

	static bool startup=false;
	if(!startup)
	{
		GPIO_Configuration();
		Reset_W5200();
		WIZ_SPI_Init();
		Set_network(config->Source_IP, config->Gateway, config->MAC, config->Subnet);
		startup=true;
		while (getSn_SR(config->s) != SOCK_CLOSED);
	}

	if(socket(config->s,Sn_MR_TCP,config->Source_Port,0x00)== 0)    /* reinitialize the socket */
	{
		return 0; //TCP socket failed
	}

	while (getSn_SR(config->s) != SOCK_INIT); // Wait for socket to open

	IINCHIP_WRITE(Sn_CR(config->s), Sn_CR_LISTEN); // Start listening on port specified
	while (IINCHIP_READ(Sn_CR(config->s))); // Check status
	while (getSn_SR(config->s) != SOCK_LISTEN); // Wait for listen
	return 1;
}
コード例 #2
0
ファイル: tcp.c プロジェクト: GerarDZG/Embedded-Systems
uint8_t process_request(TCP_CONFIG *config)
{
	uint16_t bytes_to_send =0;
	uint8_t rets=0;

	if(bytesReceived>tcp_data_buffer_size)
		return 0; // Content overflow

	// Assuming GIT request, read and parse if you with to use urls for anything
	recv_data_processing(config->s, tcp_data_buffer, bytesReceived); // Data from the GIT request
	sprintf(website,"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n\
			<html>\n<head>\n<center><h1>%d</h1></center>\n<meta http-equiv=\"refresh\" content=\"1.5\" >",ADCRead(0));

	bytes_to_send = strlen((char *)website);
	rets = send(config->s, website,bytes_to_send , 0); // Send Response with html
	bytesReceived=0;

	IINCHIP_WRITE(Sn_CR(config->s), Sn_CR_DISCON); 	// Shut down connection
	while (IINCHIP_READ(Sn_CR(config->s)));			//
	IINCHIP_WRITE(Sn_CR(config->s), Sn_CR_CLOSE);	//
	while (IINCHIP_READ(Sn_CR(config->s)));			//
	IINCHIP_WRITE(Sn_IR(config->s), 0xFF);			//

	return 1;
}
コード例 #3
0
ファイル: socket.c プロジェクト: ATMEGA17/tinkerit
/**
@brief	This function established	the connection for the channel in passive (server) mode. This function waits for the request from the peer.
@return	1 for success else 0.
*/ 
uint8 listen(
	SOCKET s /**< the socket number */
	)
{
	uint8 ret;
#ifdef __DEF_IINCHIP_DBG__
	printf("listen()\r\n");
#endif
	if (wiz_read_byte(Sn_SR(s)) == SOCK_INIT)
	{
		wiz_write_byte(Sn_CR(s),Sn_CR_LISTEN);
		/* +20071122[chungs]:wait to process the command... */
		while( wiz_read_byte(Sn_CR(s)) ) 
			;
		/* ------- */
		ret = 1;
	}
	else
	{
		ret = 0;
#ifdef __DEF_IINCHIP_DBG__
	printf("Fail[invalid ip,port]\r\n");
#endif
	}
	return ret;
}
コード例 #4
0
ファイル: socket.c プロジェクト: ATMEGA17/tinkerit
/**
@brief	This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it.
@return	1 for sucess else 0.
*/	 
uint8 socket(
	SOCKET s,		/**< for socket number */
	uint8 protocol,	/**< for socket protocol */
	uint16 port,		/**< the source port for the socket */
	uint8 flag		/**< the option for the socket */
	)
{
	uint8 ret;
#ifdef __DEF_IINCHIP_DBG__
	printf("socket()\r\n");
#endif
	if ((protocol == Sn_MR_TCP) || (protocol == Sn_MR_UDP) || (protocol == Sn_MR_IPRAW) || (protocol == Sn_MR_MACRAW) || (protocol == Sn_MR_PPPOE))
	{
		close(s);
		if (!port) port = local_port++;
		wiz_write_byte(Sn_MR(s),protocol | flag);
		// if don't set the source port, set local_port number.
		wiz_write_word(Sn_PORT0(s),port);
		wiz_write_byte(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR

		/* +20071122[chungs]:wait to process the command... */
		while( wiz_read_byte(Sn_CR(s)) ) 
			;
		/* ------- */
		ret = 1;
	}
	else
	{
		ret = 0;
	}
#ifdef __DEF_IINCHIP_DBG__
	printf("Sn_SR = %.2x , Protocol = %.2x\r\n", wiz_read_byte(Sn_SR(s)), wiz_read_byte(Sn_MR(s)));
#endif
	return ret;
}
コード例 #5
0
ファイル: socket.c プロジェクト: ATMEGA17/tinkerit
/**
@brief	This function established	the connection for the channel in Active (client) mode. 
		This function waits for the untill the connection is established.
		
@return	1 for success else 0.
*/ 
uint8 connect(SOCKET s, uint8 * addr, uint16 port)
{
	uint8 ret;
#ifdef __DEF_IINCHIP_DBG__
	printf("connect()\r\n");
#endif

	if 
		(
			((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
			((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
			(port == 0x00) 
		) 
	{
		ret = 0;
#ifdef __DEF_IINCHIP_DBG__
	printf("Fail[invalid ip,port]\r\n");
#endif
	}
	else
	{
		ret = 1;
		// set destination IP
		wiz_write_buf(Sn_DIPR0(s), addr,4);
		wiz_write_word(Sn_DPORT0(s),port);
		wiz_write_byte(Sn_CR(s),Sn_CR_CONNECT);
		/* m2008.01 [bj] :  wait for completion */
		while ( wiz_read_byte(Sn_CR(s)) ) ;
	}

	return ret;
}
コード例 #6
0
ファイル: socket.c プロジェクト: ATMEGA17/tinkerit
/**
@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;
}
コード例 #7
0
ファイル: W5200.c プロジェクト: DaQi0510/SM2200-Ulimate
/**
*@brief		关闭网络
*@return	无
*/
void CloseSocket_RJ45_2(void)
{
	u8 i;
	RJ45_2_Write_Register(Sn_CR(0),Sn_CR_CLOSE);
	for(i=0;i<20;i++);
	while(RJ45_2_Read_Register(Sn_CR(0)))   	/*Wait to process the command*/
	{
		for(i=0;i<20;i++);       
	}
	RJ45_2_Write_Register(Sn_IR(0),0xFF);					/*All clear*/
}
コード例 #8
0
ファイル: W5200.c プロジェクト: DaQi0510/SM2200-Ulimate
/**
*@brief		TCP模式初始化  客户端   默认连接三次,三次连接不上,返回Fail
*@param   无
*@return	无
*/
u8 RJ45_1_TCP_ClientInit(void)
{
	u8 i,j=0;
	RJ45_1_Write_Register(SIMR,1<<0); //允许SOCKET0产生中断                  
	RJ45_1_Write_Register(Sn_IMR(0) ,Sn_IR_RECV|Sn_IR_DISCON|Sn_IR_CON); //设置中断屏蔽寄存器
	CloseSocket_RJ45_1();
	RJ45_1_Write_Register(Sn_MR(0),Sn_MR_TCP|Sn_MR_ND);      //tcp模式,无延时
	WriteTem[0]=RJ45_1_Loc_Potr/256;
	WriteTem[1]=RJ45_1_Loc_Potr%256;
	RJ45_1_Write_Buf(Sn_PORT0(0),WriteTem,2);      //设置端口号
  WriteTem[0]=RJ45_1_Dir_Port/256;
	WriteTem[1]=RJ45_1_Dir_Port%256;
	RJ45_1_Write_Buf(Sn_DPORT0(0),WriteTem,2);     //设置目标服务器端口号
	RJ45_1_Write_Buf(Sn_DIPR0(0),RJ45_1_DirIP,4);  //目标服务器IP地址
	RJ45_1_Write_Register(Sn_KPALVTR(0),1);        //每5s自动检测一次连接状态
  Init1:	RJ45_1_Write_Register(Sn_CR(0),Sn_CR_OPEN);
	for(i=0;i<20;i++);
	while(RJ45_1_Read_Register(Sn_CR(0)))   	/*Wait to process the command*/
	{
		for(i=0;i<20;i++);       
	}
	if(RJ45_1_Read_Register(Sn_SR(0))!=SOCK_INIT)   //检测网口开启状态
	{
		j++;
		if(j<10)
		{
			CloseSocket_RJ45_1();
			goto Init1;
		}
		else
		{
			CloseSocket_RJ45_1();
			return Fail;
		}
	}
	
	RJ45_1_Write_Register(Sn_CR(0),Sn_CR_CONNECT);   //开启连接
	RJ45_1_Read_Buf(Sn_DIPR0(0),RJ45_1_DirIP,4);
	while(RJ45_1_Read_Register(Sn_CR(0)))   	/*Wait to process the command*/
	{ 
	}
	while(RJ45_1_Read_Register(Sn_SR(0))!=SOCK_SYNSENT)
	{
		if(RJ45_1_Read_Register(Sn_SR(0))==SOCK_ESTABLISHED)
		{
			return Success;
		}
		if(RJ45_1_Read_Register(Sn_IR(0))& Sn_IR_TIMEOUT)
		{
			RJ45_1_Write_Register(Sn_IR(0),Sn_IR_TIMEOUT);
			return Fail;
		}
	}
}
コード例 #9
0
ファイル: socket.c プロジェクト: ATMEGA17/tinkerit
/**
@brief	This function used for disconnect the socket and parameter is "s" which represent the socket number
@return	1 for success else 0.
*/ 
void disconnect(SOCKET s)
{
#ifdef __DEF_IINCHIP_DBG__
	printf("disconnect()\r\n");
#endif
	wiz_write_byte(Sn_CR(s),Sn_CR_DISCON);

	/* +20071122[chungs]:wait to process the command... */
	while( wiz_read_byte(Sn_CR(s)) ) 
		;
	/* ------- */
}
コード例 #10
0
ファイル: W5200.c プロジェクト: DaQi0510/SM2200-Ulimate
/**
*@brief		发送数据
*@param   WData:发送数组
*@param   Len:  发送数据长度,Len<=8K
*@return	无
*/
void RJ45_2_Write(u8 *WData,u16 Len)
{
	u16 Start_Address;
	u32 Address;
	RJ45_2_Read_Buf(Sn_TX_WR0(0),ReadTem,2);
	Start_Address=ReadTem[0]*256+ReadTem[1];      //获取写入地址指针
	Address=(u32)(Start_Address<<8)+(0<<5)+0x10;  //计算绝对地址
	RJ45_2_Write_Buf(Address,WData,Len);          //写入缓存
	Start_Address+=Len;
	WriteTem[0]=Start_Address/256;
	WriteTem[1]=Start_Address%256;
	RJ45_2_Write_Buf(Sn_TX_WR0(0),WriteTem,2);    //更新指针
	RJ45_2_Write_Register(Sn_CR(0),Sn_CR_SEND);   //发送
	while(RJ45_2_Read_Register(Sn_CR(0)));   	/*Wait to process the command*/
}
コード例 #11
0
ファイル: W5200.c プロジェクト: DaQi0510/SM2200-Ulimate
/**
*@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*/
}
コード例 #12
0
ファイル: W5200.c プロジェクト: DaQi0510/SM2200-Ulimate
//TCP模式初始化        服务器
u8 RJ45_2_TCP_ServiceInit(void)
{
	u8 i,j=0;
	RJ45_2_Write_Register(SIMR,1<<0); //允许SOCKET0产生中断                  
	RJ45_2_Write_Register(Sn_IMR(0) ,Sn_IR_RECV|Sn_IR_TIMEOUT|Sn_IR_DISCON|Sn_IR_CON); //设置中断屏蔽寄存器
	CloseSocket_RJ45_2();
	RJ45_2_Write_Register(Sn_MR(0),Sn_MR_TCP|Sn_MR_ND);      //tcp模式,无延时
	WriteTem[0]=RJ45_2_Loc_Potr/256;
	WriteTem[1]=RJ45_2_Loc_Potr%256;
	RJ45_2_Write_Buf(Sn_PORT0(0),WriteTem,2);      //设置端口号
	RJ45_2_Write_Register(Sn_KPALVTR(0),1);        //每5s自动检测一次连接状态
  Init1:	RJ45_2_Write_Register(Sn_CR(0),Sn_CR_OPEN);
	for(i=0;i<20;i++);
	while(RJ45_2_Read_Register(Sn_CR(0)))   	/*Wait to process the command*/
	{
		for(i=0;i<20;i++);       
	}
	if(RJ45_2_Read_Register(Sn_SR(0))!=SOCK_INIT)   //检测网口开启状态
	{
		j++;
		if(j<10)
		{
			CloseSocket_RJ45_2();
			goto Init1;
		}
		else
		{
			CloseSocket_RJ45_2();
			return Fail;
		}
	}
	RJ45_2_Write_Register(Sn_CR(0),Sn_CR_LISTEN);   //开启监听状态
	for(i=0;i<20;i++);
	while(RJ45_2_Read_Register(Sn_CR(0)))   	/*Wait to process the command*/
	{
		for(i=0;i<20;i++);       
	}
	return Success;
}
コード例 #13
0
ファイル: socket.c プロジェクト: ATMEGA17/tinkerit
/**
@brief	This function close the socket and parameter is "s" which represent the socket number
*/ 
void close(SOCKET s)
{
#ifdef __DEF_IINCHIP_DBG__
	printf("close()\r\n");
#endif
	
	wiz_write_byte(Sn_CR(s),Sn_CR_CLOSE);

	/* +20071122[chungs]:wait to process the command... */
	while( wiz_read_byte(Sn_CR(s)) ) 
		;
	/* ------- */

	/* +2008.01 [hwkim]: clear interrupt */	
	#ifdef __DEF_IINCHIP_INT__
		/* m2008.01 [bj] : all clear */
		putISR(s, 0x00);
	#else
		/* m2008.01 [bj] : all clear */
		wiz_write_byte(Sn_IR(s), 0xFF);
	#endif
}
コード例 #14
0
ファイル: EthernetDNS.cpp プロジェクト: aiwku1277/beerbug
// 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;
}
コード例 #15
0
ファイル: w5300.c プロジェクト: simahell/HTTPServer
uint8    getSn_CR(SOCKET s)
{
   return IINCHIP_READ(Sn_CR(s));
}
コード例 #16
0
ファイル: w5300.c プロジェクト: simahell/HTTPServer
void     setSn_CR(SOCKET s, uint16 com)
{
   IINCHIP_WRITE(Sn_CR(s),com);
   while(IINCHIP_READ(Sn_CR(s))); // wait until Sn_CR is cleared.
}
コード例 #17
0
ファイル: EthernetDNS.cpp プロジェクト: aiwku1277/beerbug
// return value:
// A DNSError_t (DNSSuccess on success, something else otherwise)
// in "int" mode: positive on success, negative on error
DNSError_t EthernetDNSClass::_sendDNSQueryPacket(const char* hostName)
{
   DNSError_t statusCode = DNSSuccess;
   uint16_t ptr = 0;
#if defined(_USE_MALLOC_)
   DNSHeader_t* dnsHeader = NULL;
#else
   DNSHeader_t dnsHeaderBuf;
   DNSHeader_t* dnsHeader = &dnsHeaderBuf;
#endif
   const char* p1, *p2;
   char* p3;
   uint8_t* buf;
   int c, i, bsize, len;

   if (NULL == hostName || 0 == *hostName) {
      statusCode = DNSInvalidArgument;
      goto errorReturn;
   }
   
   ptr = IINCHIP_READ(Sn_TX_WR0(this->_socket));
 	ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_TX_WR0(this->_socket) + 1);

#if defined(_USE_MALLOC_)
   dnsHeader = (DNSHeader_t*)malloc(sizeof(DNSHeader_t));
   if (NULL == dnsHeader) {
      statusCode = DNSOutOfMemory;
      goto errorReturn;
   }
#endif
          
   memset(dnsHeader, 0, sizeof(DNSHeader_t));
   
   dnsHeader->xid = dns_htons(++this->_dnsData.xid);
   dnsHeader->recursionDesired = 1;
   dnsHeader->queryCount = dns_htons(1);
   dnsHeader->opCode = DNSOpQuery;
   
   write_data(this->_socket, (vuint8*)dnsHeader, (vuint8*)ptr, sizeof(DNSHeader_t));
   ptr += sizeof(DNSHeader_t);
   
   p1 = hostName;
   bsize = sizeof(DNSHeader_t);
   buf = (uint8_t*)dnsHeader;
   while(*p1) {
      c = 1;
      p2 = p1;
      while (0 != *p2 && '.' != *p2) { p2++; c++; };

      p3 = (char*)buf;
      i = c;
      len = bsize-1;
      *p3++ = (uint8_t)--i;
      while (i-- > 0) {
         *p3++ = *p1++;
         
         if (--len <= 0) {
            write_data(this->_socket, (vuint8*)buf, (vuint8*)ptr, bsize);
            ptr += bsize;
            len = bsize;
            p3 = (char*)buf;
         }
      }
      
      while ('.' == *p1)
         ++p1;
      
      if (len != bsize) {
         write_data(this->_socket, (vuint8*)buf, (vuint8*)ptr, bsize-len);
         ptr += bsize-len;
      }
   }
      
   // first byte is the query string's zero termination, then qtype and class follow.
   buf[0] = buf[1] = buf[3] = 0;
   buf[2] = buf[4] = 1;

   write_data(this->_socket, (vuint8*)buf, (vuint8*)ptr, 5);
   ptr += 5;

   IINCHIP_WRITE(Sn_TX_WR0(this->_socket), (vuint8)((ptr & 0xff00) >> 8));
   IINCHIP_WRITE((Sn_TX_WR0(this->_socket) + 1), (vuint8)(ptr & 0x00ff));
   
   IINCHIP_WRITE(Sn_CR(this->_socket), Sn_CR_SEND);

   while(IINCHIP_READ(Sn_CR(this->_socket)));
   
   if (_state == DNSStateIdle) {
      this->_dnsData.lastQueryFirstXid = this->_dnsData.xid;
   }
   
   this->_state = DNSStateQuerySent;

   statusCode = DNSSuccess;

errorReturn:
   this->_lastSendMillis = millis();

#if defined(_USE_MALLOC_)
   if (NULL != dnsHeader)
      free(dnsHeader);
#endif

   return statusCode;
}