Пример #1
0
/*****************************************************************************
  Function:
	int recv( SOCKET s, char* buf, int len, int flags )

  Summary:
	The recv() function is used to receive incoming data that has
	been queued for a socket.

  Description:
	The recv() function is used to receive incoming data that has
	been queued for a socket. This function can be used with both 
	datagram and stream socket. If the available data
	is too large to fit in the supplied application buffer buf,
	excess bytes are discarded in case of SOCK_DGRAM type
	sockets.  For SOCK_STREAM types, the data is buffered
	internally so the application can retreive all data by
	multiple calls of recvfrom.

  Precondition:
	connect function should be called for TCP and UDP sockets.
	Server side, accept function should be called.

  Parameters:
	s - Socket descriptor returned from a previous call to socket.
	buf - application data receive buffer.
	len - buffer length in bytes.
	flags - no significance in this implementation

  Returns:
	If recv is successful, the number of bytes copied to
	application buffer buf is returned. A value of zero indicates
	no data available. A return value of SOCKET_ERROR (-1)
	indicates an error condition. A return value of SOCKET_DISCONNECTED
	indicates the connection no longer exists.

  Remarks:
	None.
  ***************************************************************************/
int recv( SOCKET s, char* buf, int len, int flags )
{
	struct BSDSocket *socket;

	if( s >= BSD_SOCKET_COUNT )
		return SOCKET_ERROR;

	socket = &BSDSocketArray[s];

	if(socket->SocketType == SOCK_STREAM) //TCP
	{
		if(socket->bsdState != SKT_EST)
			return SOCKET_ERROR;

		if(HandlePossibleTCPDisconnection(s))
			return SOCKET_ERROR;

		return TCPGetArray(socket->SocketID, (BYTE*)buf, len);
	}
	else if(socket->SocketType == SOCK_DGRAM) //UDP
	{
		if(socket->bsdState != SKT_BOUND)
			return SOCKET_ERROR;

		if(UDPIsGetReady(socket->SocketID))
			return UDPGetArray((BYTE*)buf, len);
	}

	return 0;
}
Пример #2
0
Файл: HTTP.c Проект: sonite/mGit
static char HTTP_GetBuf(void)
{
	char ch;

retry:
	while(ch = *HTTP_Buffer.read++, !ch)
	{
		unsigned space;

		if(!HTTP_Buffer.remaining)
			break;

		space = &HTTP_Data[HTTP_MAX_DATA_LEN] - HTTP_Buffer.write;

		if(space >= HTTP_Buffer.remaining)
			space = HTTP_Buffer.remaining;

		HTTP_Buffer.read = &HTTP_Data[HTTP_MAX_DATA_LEN] - space;
		HTTP_Buffer.remaining -= space;

		TCPGetArray(HTTP.socket, (BYTE *) HTTP_Buffer.read, space);
	}

	return ch;
}
Пример #3
0
/****************************************************************************
  Function:
    unsigned int ChipKITClientGetBuff(TCP_SOCKET hTCP, BYTE * rgBuff, unsigned short cbRead)

  Description:
    This routine reads a buffer from the specified socket, if any data is available.

  Precondition:
    hTCP must be open and valid.

  Parameters:
    hTCP - The socket to check
	rgbBuff - a pointer to a buffer to receive the data.
	cbRead - the size of the buffer.

  Returns:
    The number of byte read, 0 if none.

  Remarks:
	This is to match functionality of the Arduino Client class Read method
  ***************************************************************************/
unsigned int ChipKITClientGetBuff(TCP_SOCKET hTCP, BYTE * rgBuff, unsigned short cbRead)
{
	WORD cb = 0;
	WORD cbCur = 0;

	// run our tasks
	ChipKITPeriodicTasks();

	// if there is anything to read
	// we don't even have to be connected for this to
	// return what is in the buffer.
	// we will return when we empty the buffer so we will not 
	// have an infinite loop problem waiting for data.
	while(cbRead > 0 && (cb = TCPIsGetReady(hTCP)) > 0)
	{
		// get as much as we want or can read
		cb = cb > cbRead ? cbRead : cb;

		// read it
		cb = TCPGetArray(hTCP, &rgBuff[cbCur], cb);

		cbCur += cb;
		cbRead -= cb;

		// run our tasks so everything is updated after the read
		ChipKITPeriodicTasks();
	}

	// return what we read
	return(cbCur);
}
Пример #4
0
/// @cond debug
//****************************************************************************
//	Only internal use:
//	cTCPRead callback function
//****************************************************************************
int cTCPRead()
{
	WORD resbool;
	resbool = TCPGetArray(xSocket , xByte , xInt); 
	*(xByte+xInt)='\0';
	return (int) resbool;
}
/***	int TcpClient::readStream(byte *rgbRead, size_t cbReadMax)
**
**	Synopsis:   
**      Reads an array of bytes from the socket buffer (and removes the bytes from the socket)
**
**	Parameters:
**      rgbRead     A pointer to a buffer to receive the bytes.
**
**      cbReadMax   The maximum size of rgbPeek
**
**      pStatus A pointer to receive the status of the call, usually the connection status.
**
**	Return Values:
**      The actual number of bytes read. 0 is returned if no bytes were read or an error occured.
**
**	Errors:
**      No bytes to read, or a connection error.
**
**  Notes:
**
**      This call is safe to make without checking the connection status.
**
*/
size_t TcpClient::readStream(byte *rgbRead, size_t cbReadMax)
{
    size_t cbReady = 0;

    if( (cbReady = available()) > 0 )
    {
        cbReady = cbReady < cbReadMax ? cbReady : cbReadMax;
         return(TCPGetArray(_hTCP, rgbRead, cbReady));
    }

    return(0);
}
Пример #6
0
static void HTTPHeaderParseAuthorization(void)
{
    WORD len;
    BYTE buf[40];
	BYTE *ptrBuf;
	
	// If auth processing is not required, return
	if(curHTTP.isAuthorized & 0x80)
		return;

	// Clear the auth type ("BASIC ")
	TCPGetArray(sktHTTP, NULL, 6);

	// Find the terminating CRLF and make sure it's a multiple of four
	len = TCPFindROMArray(sktHTTP, HTTP_CRLF, HTTP_CRLF_LEN, 0, FALSE);
	len += 3;
	len &= 0xfc;
	len = mMIN(len, sizeof(buf)-4);
	
	// Read in 4 bytes at a time and decode (slower, but saves RAM)
	for(ptrBuf = buf; len > 0; len-=4, ptrBuf+=3)
	{
		TCPGetArray(sktHTTP, ptrBuf, 4);
		Base64Decode(ptrBuf, 4, ptrBuf, 3);
	}

	// Null terminate both, and make sure there's at least two terminators
	*ptrBuf = '\0';
	for(len = 0, ptrBuf = buf; len < sizeof(buf); len++, ptrBuf++)
		if(*ptrBuf == ':')
			break;
	*(ptrBuf++) = '\0';
	
	// Verify credentials
	curHTTP.isAuthorized = HTTPAuthenticate(buf, ptrBuf, NULL);

	return;
}
Пример #7
0
static void HTTPHeaderParseContentLength(void)
{
	WORD len;
	BYTE buf[10];

	// Read up to the CRLF (max 9 bytes or ~1GB)
	len = TCPFindROMArray(sktHTTP, HTTP_CRLF, HTTP_CRLF_LEN, 0, FALSE);
	len = TCPGetArray(sktHTTP, buf, len);
	buf[len] = '\0';
	
	curHTTP.byteCount = atol((char*)buf);
	
	return;

}
Пример #8
0
void ModbusTcpRxHandle(TCP_SOCKET MySocket)
{
	BYTE RX_Buffer[TCP_MODBUS_RX_MAX_LEN];
	WORD wMaxPut, wMaxGet;
	wMaxGet = TCPIsGetReady(MySocket);	// Get TCP RX FIFO byte count
	if(wMaxGet == 0) {
		return ;
	}
	wMaxGet = (sizeof(RX_Buffer) >= wMaxGet)?wMaxGet:sizeof(RX_Buffer);
	if(wMaxGet > 0) {
	    TCPGetArray(MySocket, &RX_Buffer[0], wMaxGet);
		wMaxGet = ModbusCmdPrase((void *)RX_Buffer,(unsigned int)wMaxGet); //解析和TCP包,返回一定长度的应答包,然后返回给客户端
    	wMaxPut = TCPIsPutReady(MySocket);	// Get TCP TX FIFO space
	    if(wMaxGet > 0 && wMaxPut >= wMaxGet) {
			TCPPutArray(MySocket, RX_Buffer, wMaxGet);
			TCPFlush(MySocket);
		}
	}
}
Пример #9
0
static void HTTPHeaderParseCookie(void)
{
	WORD lenA, lenB;

	// Verify there's enough space
	lenB = TCPFindROMArray(sktHTTP, HTTP_CRLF, HTTP_CRLF_LEN, 0, FALSE);
	if(lenB >= curHTTP.data + HTTP_MAX_DATA_LEN - curHTTP.ptrData - 2)
	{// If not, overflow
		curHTTP.httpStatus = HTTP_OVERFLOW;
		smHTTP = SM_HTTP_SERVE_HEADERS;
		return;
	}

	// While a CRLF is not immediate, grab a cookie value
	while(lenB != 0)
	{
		// Look for a ';' and use the shorter of that or a CRLF
		lenA = TCPFind(sktHTTP, ';', 0, FALSE);
		
		// Read to the terminator
		curHTTP.ptrData += TCPGetArray(sktHTTP, curHTTP.ptrData, mMIN(lenA, lenB));
		
		// Insert an & to anticipate another cookie
		*(curHTTP.ptrData++) = '&';
		
		// If semicolon, trash it and whitespace
		if(lenA < lenB)
		{
			TCPGet(sktHTTP, NULL);
			while(TCPFind(sktHTTP, ' ', 0, FALSE) == 0)
				TCPGet(sktHTTP, NULL);
		}
		
		// Find the new distance to the CRLF
		lenB = TCPFindROMArray(sktHTTP, HTTP_CRLF, HTTP_CRLF_LEN, 0, FALSE);
	}

	return;

}
Пример #10
0
/*****************************************************************************
*
*  exoHAL_SocketRecv
*
*  \param  socket - socket handle; buffer - string buffer to put info we
*          receive; len - size of buffer in bytes;
*
*  \return Number of bytes received
*
*  \brief  Receives data from the internet
*
*****************************************************************************/
unsigned char
exoHAL_SocketRecv(long socket, char * buffer, unsigned char len)
{
  WORD w, wGetLen;

  if (GenericTCPState == EX_PACKAGE_SEND && send_count >= 4)
  {
    TCPFlush((TCP_SOCKET)exSocket);
    GenericTCPState++;
  }

  if (GenericTCPState == EX_PROCESS_RESPONSE)
  {
    if (!TCPIsConnected(socket))
    {
      return 0;
    }

    w = TCPIsGetReady((TCP_SOCKET)exSocket);
    if (!w)
        return 0;
    buffer[0] = 0;
    if (w)
    {
      wGetLen = w;
      TCPGetArray((TCP_SOCKET)exSocket, (BYTE *)buffer, len);
      if (send_count >= 4 && w < len)
      {
        GenericTCPState = EX_DISCONNECT;
      }
      socket = (long)exSocket;
      return len;
    }
  }

  return 0;
}
Пример #11
0
/*****************************************************************************
*
* Cloud_GetCmd
*
*  \param  pbuf - string buffer containing data to be sent
*          bufsize - number of bytes to send
*
*  \return 1 success; 0 failure
*
*  \brief  Writes data to Exosite cloud
*
*****************************************************************************/
int
Cloud_GetCmd()
{
  int length;
  char DataLen[10];
//  int http_status = 0;
  char *cmp_ss = "Content-Length:";
  char *cmp = cmp_ss;
  DWORD serverip = 0;
  const unsigned char server[6] = SERVERIP ;
  serverip = (server[3] << 24 & 0xff000000) | (server[2] << 16 & 0xff0000)
          | (server[1] << 8 & 0xff00) | (server[0] & 0xff);
  long w, r;
  char rev[300];
  unsigned char len;
  char *p;
  unsigned char crlf = 0;
  int  time_out = 0;
  int tx_buff_size = 250;

  int  tmp_len =0 ;

  if(status_code == STATUS_INIT||status_code == STATUS_END){

      if (sock == INVALID_SOCKET)
      {
        sock = TCPOpen(serverip, TCP_OPEN_IP_ADDRESS, HTTP_PORT, TCP_PURPOSE_TCP_CLIENT);

      // TCP_OPEN_RAM_HOST for using dns name as server name
     //  TCPOpen(serverip, TCP_OPEN_IP_ADDRESS, server_port, TCP_PURPOSE_GENERIC_TCP_CLIENT);

       if (sock  == INVALID_SOCKET) {
             status_code = STATUS_INIT;
       //      LEDS_OFF();
        //     LEDS_ON();
            return 0;
         }
       status_code = STATUS_READY;

      }
      else  status_code == STATUS_READY;
  }
  else if(status_code == STATUS_READY)
  {
       if(sent_header) DelayMs(20);
        w = TCPIsPutReady(sock);

       if(w<=250ul) {
              return 0; }

       if(sent_header){

             memset(header, 0, sizeof(header));
             length = PostHeaderGenerate("/sendcmd.php", command, 0, 0);
             remain_count =0 ;
             sent_header = FALSE;
             sent_count = 0;
       }
    //    LED2_ON(); LED1_OFF();

       int send_len = strlen(&header[remain_count]);

   //   LED2_ON(); LED1_OFF();
      //if(send_len > 254)  {LED2_ON(); LED1_OFF()};
      /*  The max size of sliding window for TCP packet is 254? after testing.
       *  Don't know the reason, but if we set the number of sending data to 250,
       * the program works fine.
       *
       */
      tmp_len = send_len>250? 250:send_len;
  //    int tmp_len = IHMS_SocketSend(sock, &header[sent_count], send_len );

      tmp_len = TCPPutArray(sock, (BYTE *) &header[remain_count], tmp_len);

      TCPFlush((TCP_SOCKET)sock);

      LED2_ON(); LED1_OFF();

     if(tmp_len<send_len)
     {
         remain_count += tmp_len;
         return 0;
     }
     memset(header, 0, sizeof(header));
     sent_count = 0;
     remain_count = 0;
     status_code = STATUS_RCV;

  }
   else if(status_code == STATUS_RCV)
  {
     DelayMs(20);
     r = TCPIsGetReady((TCP_SOCKET) sock);

     if(r<200u){ LED2_ON();  return 0;}
     // now read all data in RX buffer

    int count = 0;
    do
    {
        r = TCPGetArray((TCP_SOCKET)sock, (BYTE *)&rev[count], 300);
        count  = count + r;
        rev[count]=0;

        r = TCPIsGetReady((TCP_SOCKET) sock);

     }while(r>0u);

    rev[count] = 0 ;

    TCPClose((TCP_SOCKET)sock);
    status_code = STATUS_END;
    sock = INVALID_SOCKET;
    status_code = STATUS_END;

    sent_header = TRUE;
    //now it's time to read time

    command = GetServerCmd(rev, "cmd=");
    cmd_no = GetServerCmd(rev, "no=");

    return 1;

  }

  return 0;
}
Пример #12
0
/*****************************************************************************
*
* Cloud_Activate
*
*  \param  None
*
*  \return 1  - activation success
*          0  - activation failure
*
*  \brief  Called after Init has been run in the past, but maybe comms were
*          down and we have to keep trying
*
*****************************************************************************/
int
Cloud_Activate(void)
{
  int length;
  char DataLen[5];
  int newcik = 0;
//  int http_status = 0;
  char *cmp_ss = "Content-Length:";
  char *cmp = cmp_ss;
  DWORD serverip = 0;
  const unsigned char server[6] = SERVERIP;
  serverip = (server[3] << 24 & 0xff000000) | (server[2] << 16 & 0xff0000)
          | (server[1] << 8 & 0xff00) | (server[0] & 0xff);
  long w, r;
  char rev[300];
  unsigned char strLen, len;
  unsigned char cik_len_valid = 0;
  char *p;
  unsigned char crlf = 0;
  unsigned char ciklen = 0;
  int   time_out = 0;
  // Flag cloud_initialized is set by Cloud_Init()
  /*
  if (!cloud_initialized) {
    status_code = STATUS_INIT;
    return newcik;
  }
    */

  // clean the content of http header array

  if(status_code == STATUS_INIT||status_code == STATUS_END){

      //to launch a new HTTP POST operation, clean the content of header at first

      if (sock == INVALID_SOCKET)
      {
        sock = TCPOpen(serverip, TCP_OPEN_IP_ADDRESS, HTTP_PORT, TCP_PURPOSE_TCP_CLIENT);

      // TCP_OPEN_RAM_HOST for using dns name as server name
     //  TCPOpen(serverip, TCP_OPEN_IP_ADDRESS, server_port, TCP_PURPOSE_GENERIC_TCP_CLIENT);

       if (sock  == INVALID_SOCKET) {
             status_code = STATUS_INIT;
       //      LEDS_OFF();
        //     LEDS_ON();
            return 0;
         }
       status_code = STATUS_READY;

      }
      status_code == STATUS_READY;
  }
  else if(status_code == STATUS_READY)
  {
      // Get activation Serial Number
        DelayMs(20);
        w = TCPIsPutReady(sock);

        if(w<2000ul) {
           //   StackTask();
          //  TCPFlush((TCP_SOCKET)sock);
              return 0; }

  //      LED1_ON(); LED2_OFF();

       // if(w>2000ul) { LED2_ON(); LED1_OFF();}

     //   DelayMs(100);
        length = strlen(provision_info);

        IHMS_itoa(DataLen, length, 10); //make a string for length

        sendLine(sock, POSTDATA_LINE, "/activate.php");
        sendLine(sock, HOST_LINE, NULL);
        sendLine(sock, CONTENT_LINE, NULL);
     //   IHMS_SocketSend(sock, "Connection: close\r\n", sizeof("Connection: close\r\n")-1);

        sendLine(sock, LENGTH_LINE, DataLen);

        IHMS_SocketSend(sock, provision_info, length);

        status_code = STATUS_RCV;
  }
  else if(status_code == STATUS_RCV)
  {
     DelayMs(20);
     r = TCPIsGetReady((TCP_SOCKET) sock);

     if(r<234u){ LED2_ON();  return 0;}
     // now read all data in RX buffer

    int count = 0;
    do
    {
        r = TCPGetArray((TCP_SOCKET)sock, (BYTE *)&rev[count], 300);
        count  = count + r;
        rev[count]=0;

        r = TCPIsGetReady((TCP_SOCKET) sock);

     }while(r>0u);

     rev[count] = 0 ;
      strLen = strlen(rev);
      len = strLen;
      p = rev;
      // Find 4 consecutive \r or \n - should be: \r\n\r\n
      while (0 < len && 4 > crlf)
      {
        if ('\r' == *p || '\n' == *p)
        {
          ++crlf;
        }
        else
        {
          crlf = 0;
          if (*cmp == *p)
          {
            // check the cik length from http response
            cmp++;
            if (cmp > cmp_ss + strlen(cmp_ss) - 1)
              cik_len_valid = 1;
          }
          else
            cmp = cmp_ss;
        }
        ++p;
        --len;
      }

     if(len>0)
     {
         LED1_ON();
         LED2_OFF();
     }



      // The body is the cik
        // TODO, be more robust - match Content-Length header value to CIK_LENGTH
      strncpy(CIK, p, CIK_LENGTH);

      CIK[40] = 0;
      newcik = 1;

    //IHMS_SocketClose(sock);

    TCPClose((TCP_SOCKET)sock);
    status_code = STATUS_END;
    sock = INVALID_SOCKET;

    return newcik;
  }

 // status_code = STATUS_INIT;
  return newcik;

}
Пример #13
0
/*********************************************************************
 * Function:        void GenericTCPServer(void)
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void GenericTCPServer(void)
{
	BYTE i;
	WORD w, w2;
	BYTE AppBuffer[32];
	WORD wMaxGet, wMaxPut, wCurrentChunk;
	static TCP_SOCKET	MySocket;
	static enum _TCPServerState
	{
		SM_HOME = 0,
		SM_LISTENING,
	} TCPServerState = SM_HOME;

	switch(TCPServerState)
	{
		case SM_HOME:
			// Allocate a socket for this server to listen and accept connections on
			MySocket = TCPOpen(0, TCP_OPEN_SERVER, SERVER_PORT, TCP_PURPOSE_GENERIC_TCP_SERVER);
			if(MySocket == INVALID_SOCKET)
			{
#ifdef USE_LCD
				strcpypgm2ram((char*)LCDText, "Error: Increase MAX_TCP_SOCKETS");
				LCDUpdate();
#endif
				return;
			}

			TCPServerState = SM_LISTENING;
			break;

		case SM_LISTENING:
			// See if anyone is connected to us
			if(!TCPIsConnected(MySocket))
				return;


			// Figure out how many bytes have been received and how many we can transmit.
			wMaxGet = TCPIsGetReady(MySocket);	// Get TCP RX FIFO byte count
			wMaxPut = TCPIsPutReady(MySocket);	// Get TCP TX FIFO free space

			// Make sure we don't take more bytes out of the RX FIFO than we can put into the TX FIFO
			if(wMaxPut < wMaxGet)
				wMaxGet = wMaxPut;

			// Process all bytes that we can
			// This is implemented as a loop, processing up to sizeof(AppBuffer) bytes at a time.  
			// This limits memory usage while maximizing performance.  Single byte Gets and Puts are a lot slower than multibyte GetArrays and PutArrays.
			wCurrentChunk = sizeof(AppBuffer);
			for(w = 0; w < wMaxGet; w += sizeof(AppBuffer))
			{
				// Make sure the last chunk, which will likely be smaller than sizeof(AppBuffer), is treated correctly.
				if(w + sizeof(AppBuffer) > wMaxGet)
					wCurrentChunk = wMaxGet - w;

				// Transfer the data out of the TCP RX FIFO and into our local processing buffer.
				TCPGetArray(MySocket, AppBuffer, wCurrentChunk);
				
				// Perform the "ToUpper" operation on each data byte
				for(w2 = 0; w2 < wCurrentChunk; w2++)
				{
					i = AppBuffer[w2];
					if(i >= 'a' && i <= 'z')
					{
						i -= ('a' - 'A');
						AppBuffer[w2] = i;
					}
				}
				
				// Transfer the data out of our local processing buffer and into the TCP TX FIFO.
				TCPPutArray(MySocket, AppBuffer, wCurrentChunk);
			}

			// No need to perform any flush.  TCP data in TX FIFO will automatically transmit itself after it accumulates for a while.  If you want to decrease latency (at the expense of wasting network bandwidth on TCP overhead), perform and explicit flush via the TCPFlush() API.

			break;
	}
}
Пример #14
0
/****************************************************************************
  Function:
    void DDNSTask(void)

  Summary:
    Dynamic DNS client task/state machine.

  Description:
  	This function performs the background tasks of the Dynamic DNS Client.
  	Once the DDNSPointers structure is configured, this task attempt to 
  	update the Dynamic DNS hostname on a periodic schedule.
  	
  	The task first accesses the CheckIP server to determine the device's
  	current external IP address.  If the IP address has changed, it 
  	issues an update command to the dynamic DNS service to propagate the
  	change.  This sequence executes whenever dwUpdateAt elapses, which by
  	default is every 10 minutes, or when an update is forced.
    
  Precondition:
    DDNSInit() has been called.

  Parameters:
	None
	
  Returns:
    None

  Remarks:
	This function acts as a task (similar to one in an RTOS).  It
	performs its task in a co-operative manner, and the main application
	must call this function periodically to ensure that its tasks get 
	executed in a timely fashion.
  ***************************************************************************/
void DDNSTask(void)
{
	BYTE 				i;
	static TICK			Timer;
	static TCP_SOCKET	MySocket = INVALID_SOCKET;
	static char ROM * 	ROMStrPtr;
	static char * 		RAMStrPtr;

	static BYTE vBuffer[16];
	WORD wPos;
	static IP_ADDR ipParsed;
	
	static enum
	{
		SM_IDLE = 0u,
		SM_BEGIN_CHECKIP,				//0x1
		SM_CHECKIP_SKT_OBTAINED,		//0x2
		SM_CHECKIP_FIND_DELIMITER,		//0x3
		SM_CHECKIP_FIND_ADDRESS,		//0x4
		SM_CHECKIP_DISCONNECT,			//0x5
		SM_IP_UPDATE_HOME,				//0x6
		SM_IP_UPDATE_SKT_OBTAINED,		//0x7

		/*  
			HTTP request msg is divided into 6 parts 
			SM_IP_UPDATE_REQ_A,B,C,D,E,F as the tcp ip tx
			buffer is only able to carry 200 bytes at a time.
		*/
		
		SM_IP_UPDATE_REQ_A,				//0x8
		SM_IP_UPDATE_REQ_B,				//0x9
		SM_IP_UPDATE_REQ_C,				//0xa	
		SM_IP_UPDATE_REQ_D,				//0xb
		SM_IP_UPDATE_REQ_E,				//0xc
		SM_IP_UPDATE_REQ_F,				//0xd

		SM_IPUPDATE_FIND_RESPONSE,		//0xe
		SM_IPUPDATE_PARSE_RESPONSE,		//0xf
		SM_IPUDATE_DISCONNECT,			//0x10
		SM_DONE,						// Done, try again in 10 minutes
		SM_SOFT_ERROR,					// Soft error, try again in 30 seconds
		SM_SYSTEM_ERROR 				// System error, try again in 30 minutes
	} smDDNS = SM_IDLE;

	switch(smDDNS)
	{
		case SM_IDLE:

			// Wait for timeout to begin IP check
			if((LONG)(TickGet() - dwUpdateAt) < 0)
				break;
			
			// Otherwise, continue to next state
			smDDNS = SM_BEGIN_CHECKIP;
				
		case SM_BEGIN_CHECKIP:
			
			// If a fatal error has occurred, abort to the SM_DONE state and keep
			// the error message.
			if(lastStatus >= DDNS_STATUS_ABUSE && lastStatus <= DDNS_STATUS_911)
			{
				smDDNS = SM_DONE;
				break;
			}

			// If DDNSClient is not properly configured, abort
			if( 
				// Verify that each pointer is not null, and is not empty
				(DDNSClient.ROMPointers.Host && (!DDNSClient.Host.szROM || *DDNSClient.Host.szROM == '\0') ) ||
				(!DDNSClient.ROMPointers.Host && (!DDNSClient.Host.szRAM || *DDNSClient.Host.szRAM == '\0') ) ||
				(DDNSClient.ROMPointers.Username && (!DDNSClient.Username.szROM || *DDNSClient.Username.szROM == '\0') ) ||
				(!DDNSClient.ROMPointers.Username && (!DDNSClient.Username.szRAM || *DDNSClient.Username.szRAM == '\0') ) ||
				(DDNSClient.ROMPointers.Password && (!DDNSClient.Password.szROM || *DDNSClient.Password.szROM == '\0') ) ||
				(!DDNSClient.ROMPointers.Password && (!DDNSClient.Password.szRAM || *DDNSClient.Password.szRAM == '\0') ) ||
				(DDNSClient.ROMPointers.CheckIPServer && (!DDNSClient.CheckIPServer.szROM || *DDNSClient.CheckIPServer.szROM == '\0') ) ||
				(!DDNSClient.ROMPointers.CheckIPServer && (!DDNSClient.CheckIPServer.szRAM || *DDNSClient.CheckIPServer.szRAM == '\0') ) ||
				(DDNSClient.ROMPointers.UpdateServer && (!DDNSClient.UpdateServer.szROM || *DDNSClient.UpdateServer.szROM == '\0') ) ||
				(!DDNSClient.ROMPointers.UpdateServer && (!DDNSClient.UpdateServer.szRAM || *DDNSClient.UpdateServer.szRAM == '\0') )
			)
			{
				smDDNS = SM_SOFT_ERROR;
				lastStatus = DDNS_STATUS_INVALID;
				break;
			}
			
			// Start with an invalidated IP String
			vBuffer[0] = '\0';
	
			// Connect a socket to the remote server
			if(DDNSClient.ROMPointers.CheckIPServer)
			{	
				MySocket = TCPOpen((DWORD)(ROM_PTR_BASE)DDNSClient.CheckIPServer.szROM, TCP_OPEN_ROM_HOST,
					DDNSClient.CheckIPPort, TCP_PURPOSE_DEFAULT);
			}
			else
			{
				MySocket = TCPOpen((DWORD)(PTR_BASE)DDNSClient.CheckIPServer.szRAM, TCP_OPEN_RAM_HOST,
					DDNSClient.CheckIPPort, TCP_PURPOSE_DEFAULT);						
			}
			
			// If no socket available, try again on next loop
			if(MySocket == INVALID_SOCKET)
				break;

			smDDNS++;
			Timer = TickGet();
			break;

		case SM_CHECKIP_SKT_OBTAINED:

			// Wait for the remote server to accept our connection request
			if(!TCPIsConnected(MySocket))
			{
				// Time out if too much time is spent in this state
				if(TickGet()-Timer > 6*TICK_SECOND)
				{
					// Close the socket so it can be used by other modules
					// We will retry soon
					TCPDisconnect(MySocket);
					MySocket = INVALID_SOCKET;
					lastStatus = DDNS_STATUS_CHECKIP_ERROR;
					smDDNS = SM_SOFT_ERROR;
				}
				break;
			}

			Timer = TickGet();

			// Make certain the socket can be written to
			if(TCPIsPutReady(MySocket) < 125)//125 = size of TCP Tx buffer
				break;
			
			// Transmit the request to the server
			TCPPutROMString(MySocket, (ROM BYTE*)"GET / HTTP/1.0\r\nHost: ");

			if(DDNSClient.ROMPointers.CheckIPServer)
			{
				TCPPutROMString(MySocket, DDNSClient.CheckIPServer.szROM);
			}
			else
			{
				TCPPutString(MySocket, DDNSClient.CheckIPServer.szRAM);
			}

			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nConnection: close\r\n\r\n");

			// Send the packet
			TCPFlush(MySocket);
			smDDNS++;
			break;

		case SM_CHECKIP_FIND_DELIMITER:

			// Check if remote node is still connected.  If not, force to the disconnect state,
			// but don't break because data may still be waiting.
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 6*TICK_SECOND)
				smDDNS = SM_CHECKIP_DISCONNECT;

			// Search out the "Address: " delimiter in the response
			wPos = TCPFindROMArray(MySocket, (ROM BYTE*)"Address: ", 9, 0, FALSE);
			
			// If not yet found, clear as much as possible and break
			if(wPos == 0xffff)
			{
				wPos = TCPIsGetReady(MySocket);
				if(wPos > 9)
					TCPGetArray(MySocket, NULL, wPos - 9);
				break;
			}
				
			// Clear up to and past that string
			TCPGetArray(MySocket, NULL, wPos + 9);
		
			// Continue on to read the IP
			Timer = TickGet();
			smDDNS++;
		
		case SM_CHECKIP_FIND_ADDRESS:
			
			// Check if remote node is still connected.  If not, force to the disconnect state,
			// but don't break because data may still be waiting.
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 6*TICK_SECOND)
				smDDNS = SM_CHECKIP_DISCONNECT;

			// Search out the "</body>" delimiter in the response
			wPos = TCPFindROMArray(MySocket, (ROM BYTE*)"</body>", 7, 0, FALSE);
			
			// If not yet found, break
			if(wPos == 0xffff)
				break;
				
			// Read and terminate that string as the IP address (preventing buffer overflows)
			if(wPos > 15)
				wPos = 15;
			TCPGetArray(MySocket, vBuffer, wPos);
			vBuffer[wPos] = '\0';
			
			// Parse the IP address that was read, invalidating on failure
			if(!StringToIPAddress(vBuffer, &ipParsed))
				vBuffer[0] = '\0';

			// Continue on to close the socket			
			
		case SM_CHECKIP_DISCONNECT:

			// Close the socket
			TCPDisconnect(MySocket);
			MySocket = INVALID_SOCKET;

			// Determine if an update is necessary
			if(vBuffer[0] == '\0')
			{// CheckIP Failed
				lastStatus = DDNS_STATUS_CHECKIP_ERROR;
				smDDNS = SM_SOFT_ERROR;
				break;
			}

			if( (ipParsed.Val ==lastKnownIP.Val) && (!bForceUpdate))
			{
				// IP address has not changed and no update is forced
				lastStatus = DDNS_STATUS_UNCHANGED;
				smDDNS = SM_DONE;
				break;
			}
			
			// Need to perform an update
			lastKnownIP = ipParsed;
			bForceUpdate = FALSE;
			smDDNS++;
			break;
			 
		case SM_IP_UPDATE_HOME:

			// Connect a socket to the remote server
			if(DDNSClient.ROMPointers.UpdateServer)
			{
				MySocket = TCPOpen((DWORD)(ROM_PTR_BASE)DDNSClient.UpdateServer.szROM, TCP_OPEN_ROM_HOST, 
					DDNSClient.UpdatePort, TCP_PURPOSE_DEFAULT);
			}
			else
			{
				MySocket = TCPOpen((DWORD)(PTR_BASE)DDNSClient.UpdateServer.szRAM, TCP_OPEN_RAM_HOST,
					DDNSClient.UpdatePort, TCP_PURPOSE_DEFAULT);
			}
	
			// If no socket is available, try again on the next loop
			if(MySocket == INVALID_SOCKET)
				break;
			
			// Move on to the next state
			smDDNS++;
			Timer = TickGet();
			break;

		case SM_IP_UPDATE_SKT_OBTAINED:
		
			// Wait for the remote server to accept our connection request
			if(!TCPIsConnected(MySocket))
			{
				// Time out if too much time is spent in this state
				if(TickGet() - Timer > 6*TICK_SECOND)
				{
					// Close the socket so it can be used by other modules
					// We will try again immediately
					TCPDisconnect(MySocket);
					MySocket = INVALID_SOCKET;
					lastStatus = DDNS_STATUS_UPDATE_ERROR;
					smDDNS--;
				}
				break;
			}
			
			// Reset timer and begin sending the request
			Timer = TickGet();
			smDDNS++;
			// No break needed...try to send first bit immediately.

		case SM_IP_UPDATE_REQ_A:
	
			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || (TickGet() - Timer > 10*TICK_SECOND))
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break;
			}
			
			if(TCPIsPutReady(MySocket) < 25u)  // 25 =~ 16+9
				break;

			TCPPutROMString(MySocket, (ROM BYTE*)"GET /nic/update?hostname=");
			smDDNS++;
			// No break needed...try to send next bit immediately.
			
		case SM_IP_UPDATE_REQ_B:

			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || (TickGet() - Timer > 10*TICK_SECOND))
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break; 
			}

			// Try to write, verifying that space is available first
			if(DDNSClient.ROMPointers.Host)
			{
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)DDNSClient.Host.szROM))
					break;
				TCPPutROMString(MySocket,DDNSClient.Host.szROM);
			}
			else
			{
				if(TCPIsPutReady(MySocket) < strlen((char*)DDNSClient.Host.szRAM))
					break;
				TCPPutString(MySocket,DDNSClient.Host.szRAM);
			}

			smDDNS++;
			// No break needed...try to send next bit immediately.
			
		case SM_IP_UPDATE_REQ_C:

			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 10*TICK_SECOND)
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break; 
			}

			if(TCPIsPutReady(MySocket) < 70u)
				break;
	
			TCPPutROMString(MySocket, (ROM BYTE*)"&myip=");
			TCPPutString(MySocket, vBuffer);
			TCPPutROMString(MySocket, (ROM BYTE*)"&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG HTTP/1.0");	

			TCPFlush(MySocket);
			smDDNS++;
			// No break needed...try to send next bit immediately.

		case SM_IP_UPDATE_REQ_D:

			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 10*TICK_SECOND)
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break; 
			}
			
			if(TCPIsPutReady(MySocket) < 131u) // 131 =~ 8+23 + dynamic dns server hostname
				break;

			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nHost: ");//8
			
			if(DDNSClient.ROMPointers.UpdateServer)
				TCPPutROMString(MySocket,DDNSClient.UpdateServer.szROM);
			else
				TCPPutString(MySocket,DDNSClient.UpdateServer.szRAM);
			
			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nAuthorization: Basic ");//23

			TCPFlush(MySocket);
			smDDNS++;
			// No break needed...try to send the next bit immediately.

		case SM_IP_UPDATE_REQ_E:

			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 6*TICK_SECOND)
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break; 
			}
			
			// User name and passwords for DynDNS.org can each be up to 24 characters
			// Base64 encoded data is always at least 25% bigger than the original
			if(TCPIsPutReady(MySocket) < 100u)
				break;	

			if(DDNSClient.ROMPointers.Username)
			{
				ROMStrPtr = (ROM char*)DDNSClient.Username.szROM;
				wPos = strlenpgm(ROMStrPtr);
			}
			else
			{
				RAMStrPtr = (char*)DDNSClient.Username.szRAM;
				wPos = strlen((char*)RAMStrPtr);
			}

			i = 0;
			while(wPos)
			{
				while(i < wPos && i < 3u)
				{
					if(DDNSClient.ROMPointers.Username)
						vBuffer[i] = *ROMStrPtr++;
					else
						vBuffer[i] = *RAMStrPtr++;
					i++;
				}
				wPos -= i; 				
										
				if(i == 3u)
				{
					Base64Encode(vBuffer, i, vBuffer, 4);
					TCPPutArray(MySocket, vBuffer, 4);
					i = 0;
				}
			}

			if(DDNSClient.ROMPointers.Password)
			{		
				ROMStrPtr = (ROM char*)DDNSClient.Password.szROM;
				wPos = strlenpgm(ROMStrPtr);
			}
			else
			{
				RAMStrPtr = (char*)DDNSClient.Password.szRAM;
				wPos = strlen((char*)RAMStrPtr);
			}

		  	// Increment for the ':' separator and i for bytes left in username
		  	wPos += i + 1;
			
			vBuffer[i++] = ':';

			while(wPos)
			{
				while(i < wPos && i < 3u)
				{
					if(DDNSClient.ROMPointers.Password)
						vBuffer[i] = *ROMStrPtr++;
					else
						vBuffer[i] = *RAMStrPtr++;
					i++;
				}
				wPos -= i; 				
				Base64Encode(vBuffer, i, vBuffer, 4);
				TCPPutArray(MySocket, vBuffer, 4);
				i = 0;
			}
			
			TCPFlush(MySocket);
			smDDNS++;
			break;

			
		case SM_IP_UPDATE_REQ_F:

			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 10*TICK_SECOND)
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break; 
			}
			
			if(TCPIsPutReady(MySocket) < 50)
				break;
			
			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nUser-Agent: Microchip - TCPIPSTACK - "VERSION"\r\n\r\n");
			TCPFlush(MySocket);
			smDDNS++;
			
			// Reset the timer to wait for a response
			Timer = TickGet();
			break;
								
		case SM_IPUPDATE_FIND_RESPONSE:
			// Locate the response string

			// Wait up to 10 seconds for a response
			if(TickGet() - Timer > 10*TICK_SECOND)
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break;
			}
		
			// According to HTTP, the response will start after the two CRLFs
			wPos = TCPFindROMArray(MySocket, (ROM BYTE*)"\r\n\r\n", 4, 0, FALSE);

			// If not yet found, eliminate everything up to
			if(wPos == 0xffff)
			{
				wPos = TCPIsGetReady(MySocket);
				if(wPos > 4)
					TCPGetArray(MySocket, NULL, wPos - 4);
				break;
			}
				
			TCPGetArray(MySocket, NULL, wPos+4);
			smDDNS++;
			// No break...continue to next state immediately
			
		case SM_IPUPDATE_PARSE_RESPONSE:
			// Try to parse the response text
			
			// Wait up to 10 seconds for the remote server to disconnect
			// so we know all data has been received
			if(TCPIsConnected(MySocket) && TickGet() - Timer < 10*TICK_SECOND)
				break;
			
			// Read the response code
		 	wPos = TCPIsGetReady(MySocket);
		 	if(wPos > sizeof(vBuffer) - 1)
		 		wPos = sizeof(vBuffer) - 1;

			wPos = TCPGetArray(MySocket, vBuffer, wPos);
			vBuffer[wPos] = '\0';
			for(i = 0; i < sizeof(vBuffer); i++)
				if(vBuffer[i] == ' ')
					vBuffer[i] = '\0';

			for(lastStatus = 0; lastStatus <= DDNS_STATUS_UPDATE_ERROR; lastStatus++)
				if(!strcmppgm2ram((char*)vBuffer, (ROM char*)_updateIpSrvrResponse[lastStatus]))
					break;
		
			smDDNS++;
			// No break...continue to finalization

		case SM_IPUDATE_DISCONNECT:
			// Close the socket so it can be used by other modules.
			if(MySocket != INVALID_SOCKET)
			{
				TCPDisconnect(MySocket);
				MySocket = INVALID_SOCKET;
			}
			
			// Determine what to do based on status
			if(lastStatus <= DDNS_STATUS_NUMHOST || lastStatus == DDNS_STATUS_UNCHANGED)
				smDDNS = SM_DONE;
			else if(lastStatus == DDNS_STATUS_911 || lastStatus == DDNS_STATUS_DNSERR)
				smDDNS = SM_SYSTEM_ERROR;
			else
				smDDNS = SM_SOFT_ERROR;
			
			smDDNS++;
			break;
			
		case SM_DONE:
			dwUpdateAt = TickGet() + 10*60*TICK_SECOND;	// 10 minutes
			smDDNS = SM_IDLE;
			break;
			
		case SM_SOFT_ERROR:
			dwUpdateAt = TickGet() + 30*TICK_SECOND; 		// 30 seconds
			smDDNS = SM_IDLE;
			break;
					
		case SM_SYSTEM_ERROR:
			dwUpdateAt = TickGet() + 30*60*TICK_SECOND;		// 30 minutes
			smDDNS = SM_IDLE;
			break;
	}
}
Пример #15
0
/*********************************************************************
 * Function:        void TelnetTask(void)
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void TelnetTask(void)
{
	BYTE 		i;
	BYTE		vTelnetSession;
	WORD		w, w2;
	TCP_SOCKET	MySocket;
	enum
	{
		SM_HOME = 0,
		SM_PRINT_LOGIN,
		SM_GET_LOGIN,
		SM_GET_PASSWORD,
		SM_GET_PASSWORD_BAD_LOGIN,
		SM_AUTHENTICATED,
		SM_REFRESH_VALUES
	} TelnetState;
	static TCP_SOCKET hTelnetSockets[MAX_TELNET_CONNECTIONS];
	static BYTE vTelnetStates[MAX_TELNET_CONNECTIONS];
	static BOOL bInitialized = FALSE;

	// Perform one time initialization on power up
	if(!bInitialized)
	{
		for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++)
		{
			hTelnetSockets[vTelnetSession] = INVALID_SOCKET;
			vTelnetStates[vTelnetSession] = SM_HOME;
		}
		bInitialized = TRUE;
	}


	// Loop through each telnet session and process state changes and TX/RX data
	for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++)
	{
		// Load up static state information for this session
		MySocket = hTelnetSockets[vTelnetSession];
		TelnetState = vTelnetStates[vTelnetSession];

		// Reset our state if the remote client disconnected from us
		if(MySocket != INVALID_SOCKET)
		{
			if(TCPWasReset(MySocket))
				TelnetState = SM_PRINT_LOGIN;
		}
	
		// Handle session state
		switch(TelnetState)
		{
			case SM_HOME:
				// Connect a socket to the remote TCP server
				MySocket = TCPOpen(0, TCP_OPEN_SERVER, TELNET_PORT, TCP_PURPOSE_TELNET);
				
				// Abort operation if no TCP socket of type TCP_PURPOSE_TELNET is available
				// If this ever happens, you need to go add one to TCPIPConfig.h
				if(MySocket == INVALID_SOCKET)
					break;
	
				TelnetState++;
				break;
	
			case SM_PRINT_LOGIN:
				// Make certain the socket can be written to
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strTitle))
					break;
				
				// Place the application protocol data into the transmit buffer.
				TCPPutROMString(MySocket, strTitle);
	
				// Send the packet
				TCPFlush(MySocket);
				TelnetState++;
	
			case SM_GET_LOGIN:
				// Make sure we can put the password prompt
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strPassword))
					break;
	
				// See if the user pressed return
				w = TCPFind(MySocket, '\n', 0, FALSE);
				if(w == 0xFFFFu)
				{
					if(TCPGetRxFIFOFree(MySocket) == 0u)
					{
						TCPPutROMString(MySocket, (ROM BYTE*)"\r\nToo much data.\r\n");
						TCPDisconnect(MySocket);
					}
	
					break;
				}
			
				// Search for the username -- case insensitive
				w2 = TCPFindROMArray(MySocket, (ROM BYTE*)TELNET_USERNAME, sizeof(TELNET_USERNAME)-1, 0, TRUE);
				if((w2 != 0u) || !((sizeof(TELNET_USERNAME)-1 == w) || (sizeof(TELNET_USERNAME) == w)))
				{
					// Did not find the username, but let's pretend we did so we don't leak the user name validity
					TelnetState = SM_GET_PASSWORD_BAD_LOGIN;	
				}
				else
				{
					TelnetState = SM_GET_PASSWORD;
				}
	
				// Username verified, throw this line of data away
				TCPGetArray(MySocket, NULL, w + 1);
	
				// Print the password prompt
				TCPPutROMString(MySocket, strPassword);
				TCPFlush(MySocket);
				break;
	
			case SM_GET_PASSWORD:
			case SM_GET_PASSWORD_BAD_LOGIN:
				// Make sure we can put the authenticated prompt
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strAuthenticated))
					break;
	
				// See if the user pressed return
				w = TCPFind(MySocket, '\n', 0, FALSE);
				if(w == 0xFFFFu)
				{
					if(TCPGetRxFIFOFree(MySocket) == 0u)
					{
						TCPPutROMString(MySocket, (ROM BYTE*)"Too much data.\r\n");
						TCPDisconnect(MySocket);
					}
	
					break;
				}
	
				// Search for the password -- case sensitive
				w2 = TCPFindROMArray(MySocket, (ROM BYTE*)TELNET_PASSWORD, sizeof(TELNET_PASSWORD)-1, 0, FALSE);
				if((w2 != 3u) || !((sizeof(TELNET_PASSWORD)-1 == w-3) || (sizeof(TELNET_PASSWORD) == w-3)) || (TelnetState == SM_GET_PASSWORD_BAD_LOGIN))
				{
					// Did not find the password
					TelnetState = SM_PRINT_LOGIN;	
					TCPPutROMString(MySocket, strAccessDenied);
					TCPDisconnect(MySocket);
					break;
				}
	
				// Password verified, throw this line of data away
				TCPGetArray(MySocket, NULL, w + 1);
	
				// Print the authenticated prompt
				TCPPutROMString(MySocket, strAuthenticated);
				TelnetState = SM_AUTHENTICATED;
				// No break
		
			case SM_AUTHENTICATED:
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strDisplay) + 4)
					break;
	
				TCPPutROMString(MySocket, strDisplay);
				TelnetState++;
	
				// All future characters will be bold
				TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[1m");
	
			case SM_REFRESH_VALUES:
				if(TCPIsPutReady(MySocket) >= 78u)
				{
					//[10;1]
					//"SNTP Time:    (disabled)\r\n"
					//"Analog:             1023\r\n"
					//"Buttons:         3 2 1 0\r\n"
					//"LEDs:    7 6 5 4 3 2 1 0\r\n"
		
					// Write current UTC seconds from SNTP module, if it is enable 
					// and has changed.  Note that conversion from a DWORD to an 
					// ASCII string can take a lot of CPU power, so we only print 
					// this if the value has changed.
					#if defined(STACK_USE_SNTP_CLIENT)
					{
						static DWORD dwTime;
						BYTE vTime[11];
						
						if(dwTime != SNTPGetUTCSeconds())
						{
							
							// Position cursor at Line 10, Col 15
							TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[10;15f");
							dwTime = SNTPGetUTCSeconds();
							ultoa(dwTime, vTime);
							TCPPutROMArray(MySocket, (ROM BYTE*)strSpaces, 10-strlen((char*)vTime));							
							TCPPutString(MySocket, vTime);
						}
					}
					#endif
	
					// Position cursor at Line 11, Col 21
					TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[11;21f");
	
					// Put analog value with space padding on right side for 4 characters
					TCPPutROMArray(MySocket, (ROM BYTE*)strSpaces, 4-strlen((char*)AN0String));
					TCPPutString(MySocket, AN0String);
	
					// Put Buttons
					TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[12;18f");
					TCPPut(MySocket, BUTTON3_IO ? '1':'0');
					TCPPut(MySocket, ' ');
					TCPPut(MySocket, BUTTON2_IO ? '1':'0');
					TCPPut(MySocket, ' ');
					TCPPut(MySocket, BUTTON1_IO ? '1':'0');
					TCPPut(MySocket, ' ');
					TCPPut(MySocket, BUTTON0_IO ? '1':'0');
		
		
					// Put LEDs
					TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[13;10f");
					TCPPut(MySocket, LED1_IO ? '1':'0');
					TCPPut(MySocket, ' ');
					TCPPut(MySocket, LED0_IO ? '1':'0');
		
					// Put cursor at beginning of next line
					TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[14;1f");
	
					// Send the data out immediately
					TCPFlush(MySocket);
				}
	
				if(TCPIsGetReady(MySocket))
				{
					TCPGet(MySocket, &i);
					switch(i)
					{
						case '\r':
						case 'q':
						case 'Q':
							if(TCPIsPutReady(MySocket) >= strlenpgm((ROM char*)strGoodBye))
								TCPPutROMString(MySocket, strGoodBye);
							TCPDisconnect(MySocket);
							TelnetState = SM_PRINT_LOGIN;							
							break;
					}
				}
	
				break;
		}


		// Save session state back into the static array
		hTelnetSockets[vTelnetSession] = MySocket;
		vTelnetStates[vTelnetSession] = TelnetState;
	}
}
Пример #16
0
/*********************************************************************
 * Function:        void CAN2TCPBridgeTask(void)
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void CAN2TCPBridgeTask(void)
{
	static enum _BridgeState
	{
		SM_HOME = 0,
		SM_SOCKET_OBTAINED
	} BridgeState = SM_HOME;
	static TCP_SOCKET MySocket = INVALID_SOCKET;
	WORD wMaxPut, wMaxGet, w;
	BYTE *RXHeadPtrShadow, *RXTailPtrShadow;
	BYTE *TXHeadPtrShadow, *TXTailPtrShadow;


	switch(BridgeState)
	{
		case SM_HOME:
			#if defined(USE_REMOTE_TCP_SERVER)
				// Connect a socket to the remote TCP server
				MySocket = TCPOpen((DWORD)USE_REMOTE_TCP_SERVER, TCP_OPEN_ROM_HOST, CAN2TCPBRIDGE_PORT, TCP_PURPOSE_CAN_2_TCP_BRIDGE);
			#else
			MySocket = TCPOpen(0, TCP_OPEN_SERVER, CAN2TCPBRIDGE_PORT, TCP_PURPOSE_CAN_2_TCP_BRIDGE);
			#endif

			
			// Abort operation if no TCP socket of type TCP_PURPOSE_CAN_2_TCP_BRIDGE is available
			// If this ever happens, you need to go add one to TCPIPConfig.h
			if(MySocket == INVALID_SOCKET)
				break;

			// Eat the first TCPWasReset() response so we don't 
			// infinitely create and reset/destroy client mode sockets
			TCPWasReset(MySocket);
			
			// We have a socket now, advance to the next state
			BridgeState = SM_SOCKET_OBTAINED;
			break;

		case SM_SOCKET_OBTAINED:
			// Reset all buffers if the connection was lost
			if(TCPWasReset(MySocket))
			{
				// Optionally discard anything in the CAN FIFOs
				RXHeadPtr = vCANRXFIFO;
				RXTailPtr = vCANRXFIFO;
				TXHeadPtr = vCANTXFIFO;
				TXTailPtr = vCANTXFIFO;
				
				// If we were a client socket, close the socket and attempt to reconnect
				#if defined(USE_REMOTE_TCP_SERVER)
					TCPDisconnect(MySocket);
					MySocket = INVALID_SOCKET;
					BridgeState = SM_HOME;
					break;
				#endif
			}
		
			// Don't do anything if nobody is connected to us
			if(!TCPIsConnected(MySocket))
				break;
			

			// Read FIFO pointers into a local shadow copy.  Some pointers are volatile 
			// (modified in the ISR), so we must do this safely by disabling interrupts
			RXTailPtrShadow = (BYTE*)RXTailPtr;
			TXHeadPtrShadow = (BYTE*)TXHeadPtr;
				

			CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, FALSE);
			CANEnableChannelEvent(CAN1, CAN_CHANNEL0, CAN_TX_CHANNEL_ANY_EVENT, FALSE);

			RXHeadPtrShadow = (BYTE*)RXHeadPtr;
			TXTailPtrShadow = (BYTE*)TXTailPtr;
			

			CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, TRUE);		
			if(TXHeadPtrShadow != TXTailPtrShadow)
				CANEnableChannelEvent(CAN1, CAN_CHANNEL0, CAN_TX_CHANNEL_ANY_EVENT, TRUE);
			//
			// Transmit pending data that has been placed into the CAN RX FIFO (in the ISR)
			//
			wMaxPut = TCPIsPutReady(MySocket);	// Get TCP TX FIFO space
			wMaxGet = RXHeadPtrShadow - RXTailPtrShadow;	// Get CAN RX FIFO byte count
			if(RXHeadPtrShadow < RXTailPtrShadow)
				wMaxGet += sizeof(vCANRXFIFO);
			if(wMaxPut > wMaxGet)				// Calculate the lesser of the two
				wMaxPut = wMaxGet;
			if(wMaxPut)							// See if we can transfer anything
			{
				// Transfer the data over.  Note that a two part put 
				// may be needed if the data spans the vCANRXFIFO 
				// end to start address.
				w = vCANRXFIFO + sizeof(vCANRXFIFO) - RXTailPtrShadow;
				if(wMaxPut >= w)
				{
					TCPPutArray(MySocket, RXTailPtrShadow, w);
					RXTailPtrShadow = vCANRXFIFO;
					wMaxPut -= w;
				}
				TCPPutArray(MySocket, RXTailPtrShadow, wMaxPut);
				RXTailPtrShadow += wMaxPut;

				// No flush.  The stack will automatically flush and do 
				// transmit coallescing to minimize the number of TCP 
				// packets that get sent.  If you explicitly call TCPFlush()
				// here, latency will go down, but so will max throughput 
				// and bandwidth efficiency.
			
			}

			//
			// Transfer received TCP data into the CAN TX FIFO for future transmission (in the ISR)
			//
			wMaxGet = TCPIsGetReady(MySocket);	// Get TCP RX FIFO byte count
			wMaxPut = TXTailPtrShadow - TXHeadPtrShadow - 1;// Get CAN TX FIFO free space
			if(TXHeadPtrShadow >= TXTailPtrShadow)
				wMaxPut += sizeof(vCANTXFIFO);
			if(wMaxPut > wMaxGet)				// Calculate the lesser of the two
				wMaxPut = wMaxGet;
			if(wMaxPut)							// See if we can transfer anything
			{
				// Transfer the data over.  Note that a two part put 
				// may be needed if the data spans the vCANTXFIFO 
				// end to start address.
				w = vCANTXFIFO + sizeof(vCANTXFIFO) - TXHeadPtrShadow;
				if(wMaxPut >= w)
				{
					TCPGetArray(MySocket, TXHeadPtrShadow, w);
					TXHeadPtrShadow = vCANTXFIFO;
					wMaxPut -= w;
				}
				TCPGetArray(MySocket, TXHeadPtrShadow, wMaxPut);
				TXHeadPtrShadow += wMaxPut;
			}
			
			// Write local shadowed FIFO pointers into the volatile FIFO pointers.
			
			CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, FALSE);
			CANEnableChannelEvent(CAN1, CAN_CHANNEL0, CAN_TX_CHANNEL_ANY_EVENT, FALSE);
			
			RXTailPtr = (volatile BYTE*)RXTailPtrShadow;
			TXHeadPtr = (volatile BYTE*)TXHeadPtrShadow;
			
			CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, TRUE);
			if(TXHeadPtrShadow != TXTailPtrShadow)
				CANEnableChannelEvent(CAN1, CAN_CHANNEL0, CAN_TX_CHANNEL_ANY_EVENT, TRUE);

			break;
	}
}
Пример #17
0
static void HTTPProcess(HTTP_HANDLE h) {
	char bafs[26], r;

	BOOL lbContinue;
	static HTTP_INFO* ph;
	WORD w;
	static BYTE *p, *t;

	ph = &HCB[h];
    do {
		lbContinue = FALSE;
        if(!TCPIsConnected(ph->socket)) { 	ph->smHTTP = SM_HTTP_IDLE;  break; }

        switch(ph->smHTTP) {
        case SM_HTTP_IDLE:
			w = TCPGetArray(ph->socket, httpData, MAX_HTML_CMD_LEN);
			if(!w) {
				if(TCPGetRxFIFOFree(ph->socket) == 0) TCPDisconnect(ph->socket); // Request is too big, we can't support it.
				break;
			}
			httpData[w] = 0;
			t = p = httpData;
			while(*p)	if(*p=='%') { *t++ = hex2bin(p+1); p += 3; } else *t++ = *p++;	*t = 0;
			r = httpData[150];  httpData[150]=0;

			lbContinue = TRUE;
			ph->smHTTP = SM_HTTP_NOT_FOUND;
			if(strstrrampgm(httpData,"POST"))	ph->smHTTP = SM_HTTP_POST;
			if(strstrrampgm(httpData,"GET")) {
				ph->smHTTP = SM_HTTP_HEADER;
#ifndef _FAVICON_
				if(strstrrampgm(httpData,(ROM void*)"favicon"))		{ TCPDisconnect(ph->socket);  ph->smHTTP = SM_HTTP_IDLE; }
#else
				if(strstrrampgm(httpData,"favicon"))		ph->smHTTP = SM_ICO_HEADER;
#endif
				if(strstrrampgm(httpData, "Sw_Pool"))		AppConfig.who ^= 0x81;
				if(strstrrampgm(httpData, "Sw_Mode"))		AppConfig.sw_mode ^= 1;
				if(strstrrampgm(httpData, "Sw_Clock"))		AppConfig.CkSel ^= 1;
				if(strstrrampgm(httpData, "Sw_LEDs"))		bLEDs ^= 1;
			}
			httpData[150]=r;
			break;
            
        case SM_HTTP_POST:
			exoit(ph->socket);
			memcpypgm2ram(spwrk,rMinPool,SZ_ROMS );
			for(r=0;r<SZ_SRCH;r++) {
				BYTE *s;
				p = strstrrampgm(httpData,(ROM BYTE*)(DWORD)sComa[r]);
				if(p) {
					p+=5;
					t=strstrrampgm(p,ampa);
					if(t) {
						*t=0; s=p;
						switch(r) {
//							case C_JMAC:	Hex2Mac(p); break; //S2Mac(p);	break;
							case C_JMIP:	StringToIPAddress(p,&AppConfig.MyIPAddr); break;
							case C_JMSK:	StringToIPAddress(p,&AppConfig.MyMask); break;
							case C_JGTW:	StringToIPAddress(p,&AppConfig.MyGateway); break;
							case C_PDNS:	StringToIPAddress(p,&AppConfig.PrimaryDNSServer); break;
							case C_SDNS:	StringToIPAddress(p,&AppConfig.SecondaryDNSServer); break;
							case C_WPRT:	AppConfig.MyPort = atoi(p); break;
							case C_MPRT:	while(*p) if((*p) == ',')	{ *p=0; AppConfig.MinPort[0] = atoi(s); break; } else p++;
											AppConfig.MinPort[1] = atoi(++p); *--p = ',';
											break;
							case C_MURL:	while(*p) if((*p) == ',')	{ *p=0; strcpy(&spwrk[0],s); break; } else p++;
											strcpy(&spwrk[sizeof(rMinPool)/2],++p); *--p = ',';
											break;
							case C_USPA:	while(*p) if((*p) == ',')	{ *p=0; strcpy(&spwrk[sizeof(rMinPool)],s); break; } else p++;
											strcpy(&spwrk[sizeof(rMinPool)+sizeof(rUsrPass)/2],++p); *--p = ',';
											break;
						}
						*t='&';
					}
				}
			}
			ph->smHTTP = SM_HTTP_IDLE; 		SetUPS();
	       	break;

        case SM_HTTP_NOT_FOUND:
			if(TCPIsPutReady(ph->socket) >= sizeof(hdrErr)) {
				TCPPutROMString(ph->socket, hdrErr); TCPFlush(ph->socket);
				TCPDisconnect(ph->socket);
				ph->smHTTP = SM_HTTP_IDLE;
            }
            break;
#ifdef _FAVICON_
        case SM_ICO_HEADER:
			if ( TCPIsPutReady(ph->socket) ) {
                lbContinue = TRUE;
				if(TCPIsPutReady(ph->socket) >= sizeof(hdrICO)+198) {
                	TCPPutROMString(ph->socket, hdrICO);
					TCPPutROMArray(ph->socket, favicon,198);
					TCPFlush(ph->socket);
					TCPDisconnect(ph->socket);
                	ph->smHTTP = SM_HTTP_IDLE;
				}
			}
			break;
#endif
        case SM_HTTP_HEADER:
            if ( TCPIsPutReady(ph->socket) ) {
                lbContinue = TRUE;
				if(TCPIsPutReady(ph->socket) >= sizeof(hdrOK)) {
                	TCPPutROMString(ph->socket, hdrOK);
					TCPFlush(ph->socket);
                	ph->smHTTP = SM_HTTP_GET;
                	ph->Pos = Page;
            	}
            }
            break;

        case SM_HTTP_GET:
			TCPDiscard(ph->socket);
			if(TCPIsPutReady(ph->socket) >= 400) {
				ph->Pos = TCPPutROMString(ph->socket, ph->Pos);
				ph->Pos++;
				switch (*ph->Pos) {
					case  0: TCPDisconnect(ph->socket); ph->smHTTP = SM_HTTP_IDLE; ph->Pos = Page; break;
					case  1: DoStic(ph->socket, 1); break;
					case  2: DoStic(ph->socket, 2); break;
					case  3: DoStic(ph->socket, 3); break;
//					case  4: MAC2Hex(bafs); TCPPutString(ph->socket, bafs); break;
					case  5: IP2String(AppConfig.MyIPAddr,bafs); TCPPutString(ph->socket, bafs); break;
					case  6: IP2String(AppConfig.MyMask,bafs); TCPPutString(ph->socket, bafs); break;
					case  7: IP2String(AppConfig.MyGateway,bafs); TCPPutString(ph->socket, bafs); break;
					case  8: uitoa(AppConfig.MyPort,bafs); TCPPutString(ph->socket, bafs); break;
					case  9: IP2String(AppConfig.PrimaryDNSServer,bafs); TCPPutString(ph->socket, bafs); break;
					case 10: IP2String(AppConfig.SecondaryDNSServer,bafs); TCPPutString(ph->socket, bafs); break;
					case 11: uitoa(AppConfig.MinPort[0],bafs); TCPPutString(ph->socket, bafs); TCPPut(ph->socket,','); uitoa(AppConfig.MinPort[1],bafs); TCPPutString(ph->socket, bafs); break;
					case 12: TCPPutROMString(ph->socket, rMinPool[0]); TCPPut(ph->socket,','); TCPPutROMString(ph->socket, rMinPool[1]); break;
					case 13: TCPPutROMString(ph->socket, rUsrPass[0]); TCPPut(ph->socket,','); TCPPutROMString(ph->socket, rUsrPass[1]); break;
				}
				ph->Pos++;
			}
			TCPFlush(ph->socket);
			break;
		default:	break;
        }
    } while( lbContinue );
}
Пример #18
0
/* POST method is used only for 
   setting the WiFi parameters in the board 
*/
HTTP_IO_RESULT HTTPExecutePost(void)
{
	BYTE name[20];
	WORD len;
	char buf[100];

	// Load the file name
	// Make sure BYTE filename[] above is large enough for your longest name
	MPFSGetFilename(curHTTP.file, name, 20);
	
	if(strcmppgm2ram((char*)name, (ROM char*)"connecting.htm") != 0)
		return HTTP_IO_DONE;
		
	// Loop while data remains
	while(curHTTP.byteCount)
	{
		// Check for a complete variable
		len = TCPFind(sktHTTP, '&', 0, FALSE);
		if(len == 0xffff)
		{// Check if this is the last one
			if(TCPIsGetReady(sktHTTP) == curHTTP.byteCount)
				len = curHTTP.byteCount - 1;
			else // Wait for more data
			{
				return HTTP_IO_NEED_DATA;
			}
		}
		
		// Make sure we don't overflow
		if(len > HTTP_MAX_DATA_LEN-2)
		{
			curHTTP.byteCount -= TCPGetArray(sktHTTP, NULL, len+1);
			continue;
		}

		// Read the next variable and parse
		HTTPReadPostValue((BYTE*)buf,100);
		
		// Figure out which variable it is
		if(memcmppgm2ram(buf, (ROM void*)"host", 4) == 0)
		{
			strcpy(config_parms.MyHost,&buf[5]);
		}
		else if(memcmppgm2ram(buf, (ROM void*)"ssid", 4) == 0)
		{
			strcpy(config_parms.MySSID,&buf[5]);
		}
		else if(memcmppgm2ram(buf, (ROM void*)"select1", 7) == 0)
		{
			if (memcmppgm2ram(&buf[8],(ROM void*)"adhoc", 5) == 0)
			{
				config_parms.networkType = (BYTE)'A';
			}
			else if (memcmppgm2ram(&buf[8],(ROM void*)"infra", 5) == 0)
			{
				config_parms.networkType = (BYTE)'I';
			}
		}
		else if(memcmppgm2ram(buf, (ROM void*)"select2", 7) == 0)
		{
			if (memcmppgm2ram(&buf[8],(ROM void*)"auto", 4) == 0)
			{
				config_parms.SecurityMode = WF_SECURITY_WPA_AUTO_WITH_KEY;
			}
			else if (memcmppgm2ram(&buf[8],(ROM void*)"open", 4) == 0)
			{
				config_parms.SecurityMode = WF_SECURITY_OPEN;
			}
		}
		else if(memcmppgm2ram(buf, (ROM void*)"pphrase", 7) == 0)
		{
			strcpy((char *)config_parms.SecurityPhrase,&buf[8]);
		}
		else if(memcmppgm2ram(buf, (ROM void*)"chkbx", 5) == 0)
		{
			if (memcmppgm2ram(&buf[6],(ROM void*)"on", 2) == 0)
			{
				config_parms.UseKey = TRUE;
			}
			else
			{
				config_parms.UseKey = FALSE;
			}
		}
		else if(memcmppgm2ram(buf, (ROM void*)"pkey", 4) == 0)
		{
			strcpy((char *)config_parms.SecurityKey, &buf[5]);
		}
		else if(memcmppgm2ram(buf, (ROM void*)"ip", 2) == 0)
		{
			strcpy(config_parms.MyIPAddr,&buf[3]);
		}
		else if(memcmppgm2ram(buf, (ROM void*)"subnetmask", 10) == 0)
		{
			strcpy(config_parms.MyMask,&buf[11]);
		}
		else if(memcmppgm2ram(buf, (ROM void*)"gateway", 7) == 0)
		{
			strcpy(config_parms.MyGateway,&buf[8]);
		}
		else if(memcmppgm2ram(buf, (ROM void*)"pdns", 4) == 0)
		{
			strcpy(config_parms.PrimaryDNSServer,&buf[5]);
		}
		else if(memcmppgm2ram(buf, (ROM void*)"sdns", 4) == 0)
		{
			strcpy(config_parms.SecondaryDNSServer,&buf[5]);
		}
		else if(memcmppgm2ram(buf, (ROM void*)"submit", 6) == 0)			// see which button was pressed
		{
			config_parms.flag = 1;
		}
		else if(memcmppgm2ram(buf, (ROM void*)"connect", 7) == 0)			// see which button was pressed
		{
			config_parms.flag = 2;
		}

	}
		
	if (config_parms.flag == 1)
	{
		SaveWiFiStateToFlash();
		CheckAndWriteCustom();
		config_parms.DoConnectFlag = FALSE;
		config_parms.flag = 0;
	}
	else if (config_parms.flag == 2)
	{
		SaveWiFiStateToFlash();
		CheckAndWriteCustom();
		config_parms.DoConnectFlag = TRUE;
		config_parms.flag = 0;
	}

	return HTTP_IO_DONE;
}
Пример #19
0
/*********************************************************************
 * Function:        void UART2TCPBridgeTask(void)
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void UART2TCPBridgeTask(void)
{
	static enum _BridgeState
	{
		SM_HOME = 0,
		SM_SOCKET_OBTAINED
	} BridgeState = SM_HOME;
	static TCP_SOCKET MySocket = INVALID_SOCKET;
	WORD wMaxPut, wMaxGet, w;
	BYTE *RXHeadPtrShadow, *RXTailPtrShadow;
	BYTE *TXHeadPtrShadow, *TXTailPtrShadow;


	switch(BridgeState)
	{
		case SM_HOME:
			#if defined(USE_REMOTE_TCP_SERVER)
				// Connect a socket to the remote TCP server
				MySocket = TCPOpen((DWORD)USE_REMOTE_TCP_SERVER, TCP_OPEN_ROM_HOST, UART2TCPBRIDGE_PORT, TCP_PURPOSE_UART_2_TCP_BRIDGE);
			#else
				MySocket = TCPOpen(0, TCP_OPEN_SERVER, UART2TCPBRIDGE_PORT, TCP_PURPOSE_UART_2_TCP_BRIDGE);
			#endif
			
			// Abort operation if no TCP socket of type TCP_PURPOSE_UART_2_TCP_BRIDGE is available
			// If this ever happens, you need to go add one to TCPIPConfig.h
			if(MySocket == INVALID_SOCKET)
				break;

			// Eat the first TCPWasReset() response so we don't 
			// infinitely create and reset/destroy client mode sockets
			TCPWasReset(MySocket);
			
			// We have a socket now, advance to the next state
			BridgeState = SM_SOCKET_OBTAINED;
			break;

		case SM_SOCKET_OBTAINED:
			// Reset all buffers if the connection was lost
			if(TCPWasReset(MySocket))
			{
				// Optionally discard anything in the UART FIFOs
				//RXHeadPtr = vUARTRXFIFO;
				//RXTailPtr = vUARTRXFIFO;
				//TXHeadPtr = vUARTTXFIFO;
				//TXTailPtr = vUARTTXFIFO;
				
				// If we were a client socket, close the socket and attempt to reconnect
				#if defined(USE_REMOTE_TCP_SERVER)
					TCPDisconnect(MySocket);
					MySocket = INVALID_SOCKET;
					BridgeState = SM_HOME;
					break;
				#endif
			}
		
			// Don't do anything if nobody is connected to us
			if(!TCPIsConnected(MySocket))
				break;
			
			
			// Make sure to clear UART errors so they don't block all future operations
			#if defined(__18CXX)
			if(RCSTAbits.OERR)
			{
				RCSTAbits.CREN = 0;
				RCSTAbits.CREN = 1;
				LED1_IO ^= 1;
			}
			if(RCSTAbits.FERR)
			{
				BYTE dummy = RCREG;
				LED2_IO ^= 1;
			}
			#else
			if(U2STAbits.OERR)
				U2STAbits.OERR = 0;
			#endif
			

			// Read FIFO pointers into a local shadow copy.  Some pointers are volatile 
			// (modified in the ISR), so we must do this safely by disabling interrupts
			RXTailPtrShadow = (BYTE*)RXTailPtr;
			TXHeadPtrShadow = (BYTE*)TXHeadPtr;
			#if defined(__18CXX)
			PIE1bits.RCIE = 0;
			PIE1bits.TXIE = 0;
			#else
			IEC1bits.U2RXIE = 0;
			IEC1bits.U2TXIE = 0;
			#endif
			RXHeadPtrShadow = (BYTE*)RXHeadPtr;
			TXTailPtrShadow = (BYTE*)TXTailPtr;
			#if defined(__18CXX)
			PIE1bits.RCIE = 1;
			if(TXHeadPtrShadow != TXTailPtrShadow)
				PIE1bits.TXIE = 1;
			#else
			IEC1bits.U2RXIE = 1;
			if(TXHeadPtrShadow != TXTailPtrShadow)
				IEC1bits.U2TXIE = 1;
			#endif

			//
			// Transmit pending data that has been placed into the UART RX FIFO (in the ISR)
			//
			wMaxPut = TCPIsPutReady(MySocket);	// Get TCP TX FIFO space
			wMaxGet = RXHeadPtrShadow - RXTailPtrShadow;	// Get UART RX FIFO byte count
			if(RXHeadPtrShadow < RXTailPtrShadow)
				wMaxGet += sizeof(vUARTRXFIFO);
			if(wMaxPut > wMaxGet)				// Calculate the lesser of the two
				wMaxPut = wMaxGet;
			if(wMaxPut)							// See if we can transfer anything
			{
				// Transfer the data over.  Note that a two part put 
				// may be needed if the data spans the vUARTRXFIFO 
				// end to start address.
				w = vUARTRXFIFO + sizeof(vUARTRXFIFO) - RXTailPtrShadow;
				if(wMaxPut >= w)
				{
					TCPPutArray(MySocket, RXTailPtrShadow, w);
					RXTailPtrShadow = vUARTRXFIFO;
					wMaxPut -= w;
				}
				TCPPutArray(MySocket, RXTailPtrShadow, wMaxPut);
				RXTailPtrShadow += wMaxPut;

				// No flush.  The stack will automatically flush and do 
				// transmit coallescing to minimize the number of TCP 
				// packets that get sent.  If you explicitly call TCPFlush()
				// here, latency will go down, but so will max throughput 
				// and bandwidth efficiency.
			}

			//
			// Transfer received TCP data into the UART TX FIFO for future transmission (in the ISR)
			//
			wMaxGet = TCPIsGetReady(MySocket);	// Get TCP RX FIFO byte count
			wMaxPut = TXTailPtrShadow - TXHeadPtrShadow - 1;// Get UART TX FIFO free space
			if(TXHeadPtrShadow >= TXTailPtrShadow)
				wMaxPut += sizeof(vUARTTXFIFO);
			if(wMaxPut > wMaxGet)				// Calculate the lesser of the two
				wMaxPut = wMaxGet;
			if(wMaxPut)							// See if we can transfer anything
			{
				// Transfer the data over.  Note that a two part put 
				// may be needed if the data spans the vUARTTXFIFO 
				// end to start address.
				w = vUARTTXFIFO + sizeof(vUARTTXFIFO) - TXHeadPtrShadow;
				if(wMaxPut >= w)
				{
					TCPGetArray(MySocket, TXHeadPtrShadow, w);
					TXHeadPtrShadow = vUARTTXFIFO;
					wMaxPut -= w;
				}
				TCPGetArray(MySocket, TXHeadPtrShadow, wMaxPut);
				TXHeadPtrShadow += wMaxPut;
			}
			
			// Write local shadowed FIFO pointers into the volatile FIFO pointers.
			#if defined(__18CXX)
			PIE1bits.RCIE = 0;
			PIE1bits.TXIE = 0;
			#else
			IEC1bits.U2RXIE = 0;
			IEC1bits.U2TXIE = 0;
			#endif
			RXTailPtr = (volatile BYTE*)RXTailPtrShadow;
			TXHeadPtr = (volatile BYTE*)TXHeadPtrShadow;
			#if defined(__18CXX)
			PIE1bits.RCIE = 1;
			if(TXHeadPtrShadow != TXTailPtrShadow)
				PIE1bits.TXIE = 1;
			#else
			IEC1bits.U2RXIE = 1;
			if(TXHeadPtrShadow != TXTailPtrShadow)
				IEC1bits.U2TXIE = 1;
			#endif

			break;
	}
}
Пример #20
0
/*****************************************************************************
  Function:
	int recv( SOCKET s, char* buf, int len, int flags )

  Summary:
	The recv() function is used to receive incoming data that has
    been queued for a socket.

  Description:
	The recv() function is used to receive incoming data that has
    been queued for a socket. This function can be used with both 
    datagram and stream socket. If the available data is too large
    to fit in the supplied application buffer buf, the data is
    buffered internally so the application can retreive all data
    by multiple calls of recv.

  Precondition:
	connect function should be called for TCP and UDP sockets.
	Server side, accept function should be called.

  Parameters:
	s - Socket descriptor returned from a previous call to socket.
    buf - application data receive buffer.
    len - buffer length in bytes.
    flags - no significance in this implementation

  Returns:
	If recv is successful, the number of bytes copied to
    application buffer buf is returned. A value of zero indicates
    no data available. A return value of SOCKET_ERROR (-1)
    indicates an error condition. A return value of SOCKET_DISCONNECTED
    indicates the connection no longer exists.

  Remarks:
	None.
  ***************************************************************************/
int recv( SOCKET s, char* buf, int len, int flags )
{
    struct BSDSocket *socket;
    NODE_INFO remoteInfo;
    static DWORD startTick;
    
    if( s >= BSD_SOCKET_COUNT )
        return SOCKET_ERROR;

    socket = &BSDSocketArray[s];

    if( socket->bsdState < SKT_BOUND )
            return SOCKET_ERROR;
   
    if(socket->SocketType == SOCK_STREAM) //TCP
    {
        if(!TCPIsConnected(socket->SocketID))
        {
            return SOCKET_DISCONNECTED;
        }
        
        if(TCPIsGetReady(socket->SocketID))
        {
            return TCPGetArray(socket->SocketID, (BYTE*)buf, len);
        }
    }
    else if(socket->SocketType == SOCK_DGRAM) //UDP
    {
        if((socket->bsdState >= SKT_READY) && (socket->bsdState != SKT_EST))//making sure that connect function is called
        {
            if(socket->bsdState != SKT_ARP_VERIFY)
            {
                remoteInfo.IPAddr.Val = socket->remoteIP;
                ARPResolve(&remoteInfo.IPAddr);
                startTick = TickGet();
                socket->bsdState = SKT_ARP_VERIFY;
            }
            else if(socket->bsdState == SKT_ARP_VERIFY)
            {
                // Wait for the MAC address to finish being obtained
                remoteInfo.IPAddr.Val = socket->remoteIP;
                if(!ARPIsResolved(&remoteInfo.IPAddr, &remoteInfo.MACAddr))
                {
                    // Time out if too much time is spent in this state
    			    if(TickGet()- startTick > 1*TICK_SECOND)
    			    {
                        // Retransmit ARP request
                        socket->bsdState = SKT_ARP_RESOLVE;
    			    }
                 }
                 socket->SocketID = UDPOpen(socket->localPort, &remoteInfo, socket->remotePort);
                 socket->bsdState = SKT_EST;
            }
        }
        
        if(socket->bsdState == SKT_EST)
        {
            if(UDPIsGetReady(socket->SocketID) > 0)
            {
                return UDPGetArray((BYTE*)buf, len);
            }
        }
    }
    
    return 0;
}
Пример #21
0
void
NIST_DAYTIME_Client(void)
{
    WORD w;
    char NistRspBuffer[31];
    BCD_RTCC rtc_time;
   

    static DWORD NistIP_addr =0;
    static DWORD Timer;
    static TCP_SOCKET sock = INVALID_SOCKET;
    

    switch (ThisState)
    {
        case SM_START:
            if (NistIP_addr == 0)                               // initialize the IP address for the time server to call
                NistIP_addr = WX.TimeServer.NIST1.Val;
            else if (NistIP_addr == WX.TimeServer.NIST1.Val)    // toggle server address every time we try to call
                NistIP_addr = WX.TimeServer.NIST2.Val;
            else
                NistIP_addr = WX.TimeServer.NIST1.Val;

            // Connect a socket to the remote TCP server
            //sock = TCPOpen((DWORD) NIST_TIME_URL, TCP_OPEN_ROM_HOST, NIST_DAYTIME_PORT, TCP_PURPOSE_DEFAULT);
            // or with IP address ( faster, and uses less space in eeprom)
            // sock = TCPOpen((DWORD) "128.138.140.44", TCP_OPEN_ROM_HOST, NIST_DAYTIME_PORT, TCP_PURPOSE_DEFAULT);
            sock = TCPOpen( NistIP_addr, TCP_OPEN_IP_ADDRESS, NIST_DAYTIME_PORT, TCP_PURPOSE_DEFAULT);

            // Abort operation if no socket of proper type is available
            // If this ever happens, you need to go add one to TCPIPConfig.h
            if (sock == INVALID_SOCKET)
            {
        
                putrsUART((ROM char*) "NIST ERROR: no Socket of proper type defined in .h file\r\n");

                ThisState = SM_IDLE;
                break;
            }

            ThisState++;
            Timer = TickGet();

            putrsUART((ROM char*) "NIST waiting for socket connect on ");
            DisplayIPValue((IP_ADDR) NistIP_addr);
            putsUART(" Port 13\r\n");

            break;

        case SM_SOCKET_OBTAINED:

            // Wait for the remote server to accept our connection request
            if (!TCPIsConnected(sock))
            {

                // Time out if too much time is spent in this state
                if (TickGet() - Timer > NIST_TIMEOUT * TICK_SECOND)
                {

                    putrsUART((ROM char*) "NIST connection timed out,aborting\r\n");

                    // Close the socket so it can be used by other modules
                    ThisState = SM_DISCONNECT;
                }
                break;
            }

            Timer = TickGet();
            ThisState++;
            break;

        case SM_PROCESS_RESPONSE:
            // collect the time data output from the sever and/or react to a Disconnect from the server
            // The Server automatically disconnects from the client after it outputs the data
            w = sizeof (NistRspBuffer) - 1;
            if (TCPIsGetReady(sock) >= w)
            {
                NistRspBuffer[28] = 0xff;
                w = TCPGetArray(sock, (unsigned char *)NistRspBuffer, w);

                if (NistRspBuffer[28] - '0' < 2)  // The time servers health status
                {

                    putrsUART((ROM char*) "NIST got good time\r\n");

                    //extracting the time from the response and setting the RTC clock

                    rtc_time.yr = ((NistRspBuffer[7] - '0') << 4) + (NistRspBuffer[8] - '0');
                    rtc_time.mth = ((NistRspBuffer[10] - '0') << 4) + (NistRspBuffer[11] - '0');
                    rtc_time.day = ((NistRspBuffer[13] - '0') << 4) + (NistRspBuffer[14] - '0');
                    rtc_time.hr = ((NistRspBuffer[16] - '0') << 4) + (NistRspBuffer[17] - '0');
                    rtc_time.min = ((NistRspBuffer[19] - '0') << 4) + (NistRspBuffer[20] - '0');
                    rtc_time.sec = ((NistRspBuffer[22] - '0') << 4) + (NistRspBuffer[23] - '0');
                    // TT field ==0 indicates Standard time in efect, NOTE sotred in decimal format
                    rtc_time.TT = ((NistRspBuffer[25] - '0') *10) + (NistRspBuffer[26] - '0');


                    RTC_Set_BCD_time(&rtc_time);           // SET THE RTC with the current time
                    NistGotGoodTime = TRUE;

                    // set flag that we got good time
                }
                else
                     putrsUART((ROM char*) "NIST server has healt issues\r\n");

                ThisState = SM_DISCONNECT;
            }
            else
            {
                // wait to get data and abort if it takes too long
                if (TickGet() - Timer > NIST_TIMEOUT * TICK_SECOND)
                {

                    putrsUART((ROM char*) "Nist data timeout, aborting\r\n");

                    ThisState = SM_DISCONNECT;
                    break;
                }
            }

            if (!TCPIsConnected(sock))
            {   // If the Server disconnects before we do 
                putrsUART((ROM char*) "NIST Server disconnected\r\n");
                ThisState = SM_DISCONNECT;
            }
            break;

        case SM_DISCONNECT:
            // Close the socket so it can be used by other modules
            putrsUART((ROM char*) "NIST Client disconnected\r\n");
            TCPDisconnect(sock);        // This sends a "RST"
            TCPDisconnect(sock);        // This sends a "FIN"
            sock = INVALID_SOCKET;
            if (NistGotGoodTime )
            {
                ThisState = SM_IDLE;
            }
            else
                ThisState = SM_RETRY;
            break;

        case SM_RETRY:
            Timer = TickGet();
            ThisState++;
            break;

        case SM_RETRY_DELAY:
             if (TickGet() - Timer > NIST_TIMEOUT * TICK_SECOND)
                 ThisState = SM_START;
             break;

        case SM_IDLE:
        default:
            break;

    }
}
Пример #22
0
/*****************************************************************************
  Function:
	HTTP_IO_RESULT HTTPExecutePost(void)

  	This function processes every POST request from the pages. 
  ***************************************************************************/
HTTP_IO_RESULT HTTPExecutePost(void)
{
// Resolve which function to use and pass along
	BYTE filename[20];
	int len;
	// Load the file name
	// Make sure BYTE filename[] above is large enough for your longest name
	MPFSGetFilename(curHTTP.file, filename, sizeof(filename));
	while(curHTTP.byteCount)
	{
		// Check for a complete variable
		len = TCPFind(sktHTTP, '&', 0, FALSE);
		if(len == 0xffff)
		{
			// Check if is the last post, otherwise continue in the loop
			if( TCPIsGetReady(sktHTTP) == curHTTP.byteCount)
				len = curHTTP.byteCount - 1;
			else 
			{	
				return HTTP_IO_NEED_DATA; // No last post, we need more data
			}
		}

	 
		if(len > HTTP_MAX_DATA_LEN - 2)
		{
			// Make sure we don't overflow
			curHTTP.byteCount -= TCPGetArray(sktHTTP, (BYTE*)String_post, len+1);
			continue;
		}

		len = TCPGetArray(sktHTTP,curHTTP.data, len+1);

		curHTTP.byteCount -= len;
		curHTTP.data[len] = '\0';
		HTTPURLDecode(curHTTP.data);
		
		//	NETWORK TYPE SELECTION: ADHOC/INFRASTRUCTURE/SOFTAP(WIFI G only)
		if(memcmppgm2ram(curHTTP.data,(ROM void*)"NETTYPE", 7) == 0)
		{
			memcpy(String_post,(void*)&curHTTP.data[8], len-8);			
			WFSetParam(NETWORK_TYPE, String_post);
		}		  
		
		//	DHCP CLIENT ENABLING/DISABLING
		else if(memcmppgm2ram(curHTTP.data,(ROM void*)"DHCPCL", 6) == 0)
		{
			memcpy(String_post,(void*)&curHTTP.data[7], len-7);
			if (String_post [0] == 'd')
				WFSetParam(DHCP_ENABLE , DISABLED);
			else 
				WFSetParam(DHCP_ENABLE , ENABLED);
		}	
			
		//	IP ADDRESS OF THE DEVICE
		else if(memcmppgm2ram(curHTTP.data,(ROM void*)"IPADDR", 6) == 0)
		{
			memcpy(String_post,(void*)&curHTTP.data[7], len-7);
			WFSetParam(MY_IP_ADDR, String_post);
		}			
				
		//	SUBNET MASK
		else if(memcmppgm2ram(curHTTP.data,(ROM void*)"SUBNET", 6) == 0)
		{
			memcpy(String_post,(void*)&curHTTP.data[7], len-7);
			WFSetParam(SUBNET_MASK, String_post);
		}		
				
		//	DEFAULT GATEWAY 
		else if(memcmppgm2ram(curHTTP.data,(ROM void*)"GATEWAY", 7) == 0)
		{
			memcpy(String_post,(void*)&curHTTP.data[8], len-8);
			WFSetParam(MY_GATEWAY, String_post); 
		}	
					
		//	DNS SERVER #1
		else if(memcmppgm2ram(curHTTP.data,(ROM void*)"DNS1", 4) == 0)
		{
			memcpy(String_post,(void*)&curHTTP.data[5], len-5);
			WFSetParam(PRIMARY_DNS, String_post);
		}
						
		//	DNS SERVER #2
		else if(memcmppgm2ram(curHTTP.data,(ROM void*)"DNS2", 4) == 0)
		{
			memcpy(String_post,(void*)&curHTTP.data[5], len-5);
			WFSetParam(SECONDARY_DNS, String_post);
		}
									
		//	SSID 
		else if(memcmppgm2ram(curHTTP.data,(ROM void*)"SSID", 4) == 0)
		{
			memcpy(String_post,(void*)&curHTTP.data[5], len-5);
			WFSetParam(SSID_NAME, String_post); 
		}
								
		//	SECURITY TYPE
		else if(memcmppgm2ram(curHTTP.data,(ROM void*)"SECTYPE", 7) == 0)
		{
			memcpy(String_post,(void*)&curHTTP.data[8], len-8);
			
			if (String_post[2] == 'E')
			{
				security = 0;
				WFSetSecurity(WF_SECURITY_OPEN, "", 0, 0);
				ParamSet = TRUE;
			}
			else if (String_post[2] == 'A')
			{
				if (String_post[3] == '2')
					security = 5;
				else 
					security = 3;
			}
			else if (String_post[2] == 'P') 
			{
				if (String_post[3] == '4')
					security = 1;
				else 
					security = 2;
			}			
		}
		
		//	----------	SECURITY KEY AND PASSWORD	----------	
		
		//	WEP40 KEY
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WEP40KEY4", 9) == 0)
		{
			if (security == 1)
			{
				if (len > 10)
				{
					int j = 0, j1 = 0;
					WORD_VAL dummy;
					for ( j=0; j<40; j=j+2)
					{
						memcpy(String_post,(void*)&curHTTP.data[10+j], 2);
					
						dummy.v[1] =  String_post[0];
						dummy.v[0] =  String_post[1];
						PassKey[j1] = hexatob(dummy);
						j1++;
					}
					PassKey[j1]= '\0';
					security = 1;
				}
			}
		}
		
		//	WEP40 KEY INDEX
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WEP40KEYID", 10) == 0)
		{	
			memcpy(String_post,(void*)&curHTTP.data[11], len-11);
			
			int k_index;
			k_index = atoi(String_post);
			k_index--;
			if (security == 1)
			{
				WFSetSecurity(WF_SECURITY_WEP_40, PassKey, 20, k_index);
				ParamSet = TRUE;
			}
		}
		
		//	WEP104 KEY INDEX
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WEP104KEY", 9) == 0)
		{
			if (security == 2)
			{
				int j = 0, j1 = 0;
				WORD_VAL dummy;
				for ( j=0; j<32; j=j+2)
				{
					memcpy(String_post,(void*)&curHTTP.data[10+j], 2);
					
					dummy.v[1] =  String_post[0];
					dummy.v[0] =  String_post[1];
					PassKey[j1] = hexatob(dummy);
					j1++;
				}
				PassKey[j1]= '\0';
				WFSetSecurity(WF_SECURITY_WEP_104, PassKey, 16, 0);	
				ParamSet = TRUE;
			}
			
		}
		
		//	WPA WITH PASSPHRASE
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WPAPASS", 7) == 0)
		{	
			if (security == 3)
			{
				if (len > 10)
				{
					memcpy(String_post,(void*)&curHTTP.data[8], len-8);									
					WFSetSecurity(WF_SECURITY_WPA_WITH_PASS_PHRASE, String_post, len-9, 0);
					ParamSet = TRUE;
				}
			}
		}

		//	WPA WITH PASSKEY
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WPAKEY", 6) == 0)
		{	
			if (security == 3)
			{
				if (len > 10)
				{
					int j = 0, j1 = 0;
					WORD_VAL dummy;
					for ( j=0; j<64; j=j+2)
					{
						memcpy(String_post,(void*)&curHTTP.data[7+j], 2);
						
						dummy.v[1] =  String_post[0];
						dummy.v[0] =  String_post[1];
						PassKey[j1] = hexatob(dummy);
						j1++;
					}
					PassKey[j1]= '\0';
					WFSetSecurity(WF_SECURITY_WPA_WITH_KEY, PassKey, 32, 0);
					ParamSet = TRUE;
				}
			}
		}
		
		//	WPA2 WITH PASSPHRASE
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WPA2PASS", 8) == 0)
		{	
			if (len > 10)
			{
				memcpy(String_post,(void*)&curHTTP.data[9], len-9);
							
				WFSetSecurity(WF_SECURITY_WPA2_WITH_PASS_PHRASE, String_post, len-9, 0);
				ParamSet = TRUE;
			}
		}
		
		//	WPA2 WITH PASSKEY
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WPA2KEY", 7) == 0)
		{	
			if (len > 10)
			{
				int j = 0, j1 = 0;
				WORD_VAL dummy;
				for ( j=0; j<64; j=j+2)
				{
					memcpy(String_post,(void*)&curHTTP.data[8+j], 2);

					dummy.v[1] =  String_post[0];
					dummy.v[0] =  String_post[1];
					PassKey[j1] = hexatob(dummy);
					j1++;
				}
				PassKey[j1]= '\0';
				WFSetSecurity(WF_SECURITY_WPA2_WITH_KEY, PassKey, 32, 0);
				ParamSet = TRUE;
			}
		}

		/* EMAIL */
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"TXEMAIL", 7) == 0)
		{	
			memcpy(MY_EMAIL,(void*)&curHTTP.data[8], len-8);
		}
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"USEREMAIL", 9) == 0)
		{	
			memcpy(MY_EMAIL_USER,(void*)&curHTTP.data[10], len-10);
		}
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"PASSEMAIL", 9) == 0)
		{	
			memcpy(MY_EMAIL_PASS,(void*)&curHTTP.data[10], len-10);
		}
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"SERVER", 6) == 0)
		{	
			memcpy(MY_SMTP,(void*)&curHTTP.data[7], len-7);
		}
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"PORT", 4) == 0)
		{	
			memcpy(MY_SMTP_PORT,(void*)&curHTTP.data[5], len-5);
		}
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"SUBJ", 4) == 0)
		{	
			memcpy(EMAIL_SUBJECT,(void*)&curHTTP.data[5], len-5);
		}
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"TEXT", 4) == 0)
		{	
			memcpy(EMAIL_BODY,(void*)&curHTTP.data[5], len-5);
		}
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"RXEMAIL", 7) == 0)
		{	
			memcpy(EMAIL_DEST,(void*)&curHTTP.data[8], len-8);
		}	
		
		/* ALARM */
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"GMT", 3) == 0)
		{	
			memcpy(GMT,(void*)&curHTTP.data[4], len-4);
		}
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"START", 5) == 0)
		{	
			memcpy(start_string,(void*)&curHTTP.data[6], len-6);
		}
		else if (memcmppgm2ram(curHTTP.data,(ROM void*)"STOP", 4) == 0)
		{	
			memcpy(stop_string,(void*)&curHTTP.data[5], len-5);
		}
	}
	
	return HTTP_IO_DONE;
}
/*****************************************************************************
  Function:
	void GenericTCPServer(void)

  Summary:
	Implements a simple ToUpper TCP Server.

  Description:
	This function implements a simple TCP server.  The function is invoked
	periodically by the stack to listen for incoming connections.  When a 
	connection is made, the server reads all incoming data, transforms it
	to uppercase, and echos it back.
	
	This example can be used as a model for many TCP server applications.

  Precondition:
	TCP is initialized.

  Parameters:
	None

  Returns:
  	None
  ***************************************************************************/
void GenericTCPServer(void)
{
	BYTE i,j;
	WORD w, w2;
	BYTE AppBuffer[32];
	WORD wMaxGet, wMaxPut, wCurrentChunk;
	static TCP_SOCKET	MySocket;
	static enum _TCPServerState
	{
		SM_HOME = 0,
		SM_LISTENING,
        SM_CLOSING,
	} TCPServerState = SM_HOME;

	switch(TCPServerState)
	{
		case SM_HOME:
			// Allocate a socket for this server to listen and accept connections on
			MySocket = TCPOpen(0, TCP_OPEN_SERVER, SERVER_PORT, TCP_PURPOSE_GENERIC_TCP_SERVER);
			if(MySocket == INVALID_SOCKET)
				return;
			tcptxbuffer[0]=0;tcptxbufferpoint=0;

			TCPServerState = SM_LISTENING;
			break;

		case SM_LISTENING:
			// See if anyone is connected to us
			if(!TCPIsConnected(MySocket))
			{
				setspeed(0,0);
				LED0_IO=1; LED1_IO=0;
				return;
			}

			// Figure out how many bytes have been received and how many we can transmit.
			wMaxGet = TCPIsGetReady(MySocket);	// Get TCP RX FIFO byte count
			wMaxPut = TCPIsPutReady(MySocket);	// Get TCP TX FIFO free space

			// Make sure we don't take more bytes out of the RX FIFO than we can put into the TX FIFO
//			if(wMaxPut < wMaxGet)
//				wMaxGet = wMaxPut;

			// Process all bytes that we can
			// This is implemented as a loop, processing up to sizeof(AppBuffer) bytes at a time.  
			// This limits memory usage while maximizing performance.  Single byte Gets and Puts are a lot slower than multibyte GetArrays and PutArrays.
			wCurrentChunk = sizeof(AppBuffer);
			if (!wMaxGet)
				{
					w=tcptxbufferpoint;
					if (w>wMaxPut)
                        {
                          w=wMaxPut;
                        }
					if (w)
						{
						TCPPutArray(MySocket,  (BYTE*)&tcptxbuffer[0], w);
						if (tcptxbufferpoint!=w)
							{
		                        tcptxbufferpoint-=w;
								memcpy((BYTE*)&tcptxbuffer[0],(BYTE*)&tcptxbuffer[w],tcptxbufferpoint);
							}
							else   tcptxbufferpoint=0;

						}
				}
			for(w = 0; w < wMaxGet; w += sizeof(AppBuffer))
			{
				// Make sure the last chunk, which will likely be smaller than sizeof(AppBuffer), is treated correctly.
				if(w + sizeof(AppBuffer) > wMaxGet)
					wCurrentChunk = wMaxGet - w;

				// Transfer the data out of the TCP RX FIFO and into our local processing buffer.
				TCPGetArray(MySocket, AppBuffer, wCurrentChunk);
				
				j=0;
				for(w2 = 0; w2 < wCurrentChunk; w2++)
				{
					i = AppBuffer[w2];
					putcomsdata(i);
				}
				
				// Transfer the data out of our local processing buffer and into the TCP TX FIFO.
//				TCPPutArray(MySocket, AppBuffer, wCurrentChunk);
			}
TCPFlush(MySocket);

			// No need to perform any flush.  TCP data in TX FIFO will automatically transmit itself after it accumulates for a while.  If you want to decrease latency (at the expense of wasting network bandwidth on TCP overhead), perform and explicit flush via the TCPFlush() API.

			break;

		case SM_CLOSING:
			// Close the socket connection.
            TCPClose(MySocket);

			TCPServerState = SM_HOME;
			break;
	}
}
Пример #24
0
/*****************************************************************************
  Function:
	void GenericTCPClient(void)

  Summary:
	Implements a simple HTTP client (over TCP).

  Description:
	This function implements a simple HTTP client, which operates over TCP.
	The function is called periodically by the stack, and waits for BUTTON1
	to be pressed.  When the button is pressed, the application opens a TCP
	connection to an Internet search engine, performs a search for the word
	"Microchip" on "microchip.com", and prints the resulting HTML page to
	the UART.

	This example can be used as a model for many TCP and HTTP client
	applications.

  Precondition:
	TCP is initialized.

  Parameters:
	None

  Returns:
  	None
  ***************************************************************************/
void GenericTCPClient(void)
{
    BYTE 				i;
    WORD				w;
    BYTE				vBuffer[9];
    static DWORD		Timer;
    static TCP_SOCKET	MySocket = INVALID_SOCKET;
    static enum _GenericTCPExampleState
    {
        SM_HOME = 0,
        SM_SOCKET_OBTAINED,
        SM_PROCESS_RESPONSE,
        SM_DISCONNECT,
        SM_DONE
    } GenericTCPExampleState = SM_DONE;

    switch(GenericTCPExampleState)
    {
    case SM_HOME:
        // Connect a socket to the remote TCP server
        MySocket = TCPOpen((DWORD)&ServerName[0], TCP_OPEN_RAM_HOST, ServerPort, TCP_PURPOSE_GENERIC_TCP_CLIENT);

        // Abort operation if no TCP socket of type TCP_PURPOSE_GENERIC_TCP_CLIENT is available
        // If this ever happens, you need to go add one to TCPIPConfig.h
        if(MySocket == INVALID_SOCKET)
            break;

#if defined(STACK_USE_UART)
        putrsUART((ROM char*)"\r\n\r\nConnecting using Microchip TCP API...\r\n");
#endif

        GenericTCPExampleState++;
        Timer = TickGet();
        break;

    case SM_SOCKET_OBTAINED:
        // Wait for the remote server to accept our connection request
        if(!TCPIsConnected(MySocket))
        {
            // Time out if too much time is spent in this state
            if(TickGet()-Timer > 5*TICK_SECOND)
            {
                // Close the socket so it can be used by other modules
                TCPDisconnect(MySocket);
                MySocket = INVALID_SOCKET;
                GenericTCPExampleState--;
            }
            break;
        }

        Timer = TickGet();

        // Make certain the socket can be written to
        if(TCPIsPutReady(MySocket) < 125u)
            break;

        // Place the application protocol data into the transmit buffer.  For this example, we are connected to an HTTP server, so we'll send an HTTP GET request.
        TCPPutROMString(MySocket, (ROM BYTE*)"GET ");
        TCPPutROMString(MySocket, RemoteURL);
        TCPPutROMString(MySocket, (ROM BYTE*)" HTTP/1.0\r\nHost: ");
        TCPPutString(MySocket, ServerName);
        TCPPutROMString(MySocket, (ROM BYTE*)"\r\nConnection: close\r\n\r\n");

        // Send the packet
        TCPFlush(MySocket);
        GenericTCPExampleState++;
        break;

    case SM_PROCESS_RESPONSE:
        // Check to see if the remote node has disconnected from us or sent us any application data
        // If application data is available, write it to the UART
        if(!TCPIsConnected(MySocket))
        {
            GenericTCPExampleState = SM_DISCONNECT;
            // Do not break;  We might still have data in the TCP RX FIFO waiting for us
        }

        // Get count of RX bytes waiting
        w = TCPIsGetReady(MySocket);

        // Obtian and print the server reply
        i = sizeof(vBuffer)-1;
        vBuffer[i] = '\0';
        while(w)
        {
            if(w < i)
            {
                i = w;
                vBuffer[i] = '\0';
            }
            w -= TCPGetArray(MySocket, vBuffer, i);
#if defined(STACK_USE_UART)
            putsUART((char*)vBuffer);
#endif

            // putsUART is a blocking call which will slow down the rest of the stack
            // if we shovel the whole TCP RX FIFO into the serial port all at once.
            // Therefore, let's break out after only one chunk most of the time.  The
            // only exception is when the remote node disconncets from us and we need to
            // use up all the data before changing states.
            if(GenericTCPExampleState == SM_PROCESS_RESPONSE)
                break;
        }

        break;

    case SM_DISCONNECT:
        // Close the socket so it can be used by other modules
        // For this application, we wish to stay connected, but this state will still get entered if the remote server decides to disconnect
        TCPDisconnect(MySocket);
        MySocket = INVALID_SOCKET;
        GenericTCPExampleState = SM_DONE;
        break;

    case SM_DONE:
        // Do nothing unless the user pushes BUTTON1 and wants to restart the whole connection/download process
        if(BUTTON1_IO == 0u)
            GenericTCPExampleState = SM_HOME;
        break;
    }
}
Пример #25
0
/*****************************************************************************
  Function:
    void GenericTCPClient(void)

  Summary:
    Implements a simple HTTP client (over TCP).

  Description:
    This function implements a simple HTTP client, which operates over TCP.
    The function is called periodically by the stack, and waits for BUTTON1
    to be pressed.  When the button is pressed, the application opens a TCP
    connection to an Internet search engine, performs a search for the word
    "Microchip" on "microchip.com", and prints the resulting HTML page to
    the UART.

    This example can be used as a model for many TCP and HTTP client
    applications.

  Precondition:
    TCP is initialized.

  Parameters:
    None

  Returns:
      None
  ***************************************************************************/
void GenericTCPClient(void)
{
    uint8_t                 i;
    uint16_t                w;
    DNS_RESULT          dnsRes;
    uint8_t                vBuffer[9];
    static TCPIP_NET_HANDLE    netH;
    static uint32_t        clientTimer;
    static TCP_SOCKET    MySocket = INVALID_SOCKET;
    static uint32_t nAttempts =0;

    static enum _GenericTCPExampleState
    {
        SM_HOME = 0,
        SM_WAIT_DNS,
        SM_DNS_RESOLVED,
        SM_SOCKET_OBTAINED,
        SM_PROCESS_RESPONSE,
        SM_DISCONNECT,
        SM_DONE
    } GenericTCPExampleState = SM_DONE;

    //DBPRINTF("    Starting TCP client\n");

    switch(GenericTCPExampleState)
    {

        case SM_HOME:

            DBPRINTF("  SM_HOME\n");
            netH = TCPIP_STACK_GetDefaultNet();
            if(DNSBeginUsage(netH) != DNS_RES_OK)
            {
                break;
            }
            DNSResolve(ServerName, DNS_TYPE_A); 
            GenericTCPExampleState++;
            break;

        case SM_WAIT_DNS:

            DBPRINTF("  SM_WAIT_DNS\n");
            dnsRes = DNSIsResolved(ServerName, &serverIP);
            if(dnsRes == DNS_RES_PENDING)
            {   // ongoing operation;
                break;
            }
            else if(dnsRes < 0)
            {   // some DNS error occurred; retry
                DBPRINTF((const char*)"\r\n\r\nGeneric TCP client: DNS name resolving failed...\r\n");
                TCPClose(MySocket);
                MySocket = INVALID_SOCKET;
                GenericTCPExampleState = SM_HOME;
                nAttempts++;
                if(nAttempts>8) // After 8 attempts give-up
                {
                    GenericTCPExampleState = SM_DONE;
                    nAttempts=0;
                }
            }
            else
            {
                clientTimer = SYS_TICK_Get();
                GenericTCPExampleState++;
            }
            DNSEndUsage(netH);
            break;

        case SM_DNS_RESOLVED:
            DBPRINTF("  SM_DNS_RESOLVED\n");
            // Connect the socket to the remote TCP server
            MySocket = TCPOpenClient(IP_ADDRESS_TYPE_IPV4, ServerPort, (IP_MULTI_ADDRESS*)&serverIP);

			// Abort operation if no TCP socket could be opened.
			// If this ever happens, you need to update your tcp_config.h
            if(MySocket == INVALID_SOCKET)
            {   // retry
                break;
            }

            GenericTCPExampleState++;
            clientTimer = SYS_TICK_Get();
            break;

        case SM_SOCKET_OBTAINED:

            DBPRINTF("  SM_SOCKET_OBTAINED\n");
            // Wait for the remote server to accept our connection request
            if(!TCPIsConnected(MySocket))
            {
                // Time out if more than 5 seconds is spent in this state
                if((SYS_TICK_Get()-clientTimer) > 5 * SYS_TICK_TicksPerSecondGet() )
                {
                    // Close the socket so it can be used by other modules
                    TCPClose(MySocket);
                    MySocket = INVALID_SOCKET;
                    GenericTCPExampleState--;
                    DBPRINTF((const char*)"\r\n\r\nGeneric TCP client: Failed connecting to the remote server...\r\n");
                }
                break;
            }

            clientTimer = SYS_TICK_Get();

            // Make certain the socket can be written to
            if(TCPIsPutReady(MySocket) < 125u)
                break;

            // Place the application protocol data into the transmit buffer.  For this example, we are connected to an HTTP server, so we'll send an HTTP GET request.
            TCPPutString(MySocket, (const uint8_t*)"GET ");
            TCPPutString(MySocket, RemoteURL);
            TCPPutString(MySocket, (const uint8_t*)" HTTP/1.0\r\nHost: ");
            TCPPutString(MySocket, (const uint8_t*)ServerName);
            TCPPutString(MySocket, (const uint8_t*)"\r\nConnection: close\r\n\r\n");

            // Send the packet
            TCPFlush(MySocket);
            GenericTCPExampleState++;
            break;

        case SM_PROCESS_RESPONSE:
            //DBPRINTF("  SM_PROCESS_RESPONSE\n");
            // Check to see if the remote node has disconnected from us or sent us any application data
            // If application data is available, write it to the UART
            if(!TCPIsConnected(MySocket))
            {
                GenericTCPExampleState = SM_DISCONNECT;
                // Do not break;  We might still have data in the TCP RX FIFO waiting for us
            }

            // Get count of RX bytes waiting
            w = TCPIsGetReady(MySocket);

            // Obtian and print the server reply
            i = sizeof(vBuffer)-1;
            vBuffer[i] = '\0';
            while(w)
            {
                if(w < i)
                {
                    i = w;
                    vBuffer[i] = '\0';
                }
                w -= TCPGetArray(MySocket, vBuffer, i);
#if defined(GENERIC_TCP_CLIENT_ENABLE_UART_DUMP)
                DBPRINTF((char*)vBuffer);
#endif
                // SYS_CONSOLE_MESSAGE is a blocking call which will slow down the rest of the stack
                // if we shovel the whole TCP RX FIFO into the serial port all at once.
                // Therefore, let's break out after only one chunk most of the time.  The
                // only exception is when the remote node disconncets from us and we need to
                // use up all the data before changing states.
                if(GenericTCPExampleState == SM_PROCESS_RESPONSE)
                    break;
            }

            break;

        case SM_DISCONNECT:
            DBPRINTF("  SM_DISCONNECT\n");
            // Close the socket so it can be used by other modules
            // For this application, we wish to stay connected, but this state will still get entered if the remote server decides to disconnect
            TCPClose(MySocket);
            MySocket = INVALID_SOCKET;
            GenericTCPExampleState = SM_DONE;
            break;

        case SM_DONE:
            //DBPRINTF("  SM_DONE\n");
            // Do nothing unless the user pushes BUTTON1 and wants to restart the whole connection/download process
            // On many boards, SYS_USERIO_BUTTON_0 is assigned to sw1
            // SYS_USERIO_BUTTON_1=sw2 and SYS_USERIO_BUTTON_2=sw3
            if(SYS_USERIO_ButtonGet((SYS_USERIO_BUTTON_1),SYS_USERIO_BUTTON_ASSERTED))
                GenericTCPExampleState = SM_HOME;
            break;
    }
}
Пример #26
0
/*****************************************************************************
  Function:
	int recv( SOCKET s, char* buf, int len, int flags )

  Summary:
	The recv() function is used to receive incoming data that has
	been queued for a socket.

  Description:
	The recv() function is used to receive incoming data that has
	been queued for a socket. This function can be used with both
	datagram and stream socket. If the available data
	is too large to fit in the supplied application buffer buf,
	excess bytes are discarded in case of SOCK_DGRAM type
	sockets.  For SOCK_STREAM types, the data is buffered
	internally so the application can retreive all data by
	multiple calls of recvfrom.

  Precondition:
	connect function should be called for TCP and UDP sockets.
	Server side, accept function should be called.

  Parameters:
	s - Socket descriptor returned from a previous call to socket.
	buf - application data receive buffer.
	len - buffer length in bytes.
	flags - no significance in this implementation

  Returns:
	If recv is successful, the number of bytes copied to
	application buffer buf is returned.
    A return value of SOCKET_ERROR (-1)
	indicates an error condition (and errno set accordingly).
    A value of zero indicates socket has been shutdown by the peer.

  Remarks:
	None.
  ***************************************************************************/
int recv( SOCKET s, char* buf, int len, int flags )
{
    struct BSDSocket *socket;
    int     nBytes;

    if( s >= BSD_SOCKET_COUNT )
    {
        errno = EBADF;
        return SOCKET_ERROR;
    }

    socket = &BSDSocketArray[s];

    if(socket->SocketType == SOCK_STREAM) //TCP
    {
        if(socket->bsdState != SKT_EST)
        {
            errno = ENOTCONN;
            return SOCKET_ERROR;
        }

        if(HandlePossibleTCPDisconnection(s))
        {
            errno = ECONNRESET;
            return SOCKET_ERROR;
        }

        nBytes = TCPGetArray(socket->SocketID, (uint8_t*)buf, len);
        if(nBytes)
        {
            return nBytes;
        }
        errno = EWOULDBLOCK;
        return SOCKET_ERROR;
    }
    else if(socket->SocketType == SOCK_DGRAM) //UDP
    {
        if(socket->bsdState != SKT_BOUND)
        {
            errno = EINVAL;
            return SOCKET_ERROR;
        }

        if(UDPIsGetReady(socket->SocketID))
        {
            nBytes =  UDPGetArray(socket->SocketID, (uint8_t*)buf, len);
        }
        else
        {
            nBytes = 0;
        }
        if(nBytes)
        {
            return nBytes;
        }
        errno = EWOULDBLOCK;
        return SOCKET_ERROR;
    }

    return 0;
}
void twatchTasks(char frameAdvance){ //this state machine services the #twatch

   static enum _twatchState
	{
		TWATCH_INIT=0,
		TWATCH_IDLE,
		TWATCH_TRENDS_TCP_START,
		TWATCH_TRENDS_TCP_SOCKET_OBTAINED,
		TWATCH_TRENDS_TCP_PROCESS_RESPONSE,
		TWATCH_TRENDS_TCP_DISCONNECT,
		TWATCH_SEARCH_TCP_START,
		TWATCH_SEARCH_TCP_SOCKET_OBTAINED,
		TWATCH_SEARCH_TCP_PROCESS_RESPONSE,
		TWATCH_SEARCH_TCP_DISCONNECT,
	} twatchState = TWATCH_INIT; //massive twitter parsing state machine

   static enum _HTTPstatus
	{
		UNKNOWN=0,
		OK,
		ERROR,
	} HTTPstatus = UNKNOWN; //get and track HTTP status and handle errors
	static unsigned char HTTPheaderBuf[20]; //used to store HTTP headers 
	static unsigned char HTTPheaderBufCnt; //pointer

	static BYTE refreshFeeds=0, HTTPretry=0, URLencode[]="%20";//extra static vars for twitter parser

	BYTE 				i,k;
	WORD				w;
	BYTE				vBuffer[51];
	BYTE				cnt;
	static TICK			Timer;
	static TCP_SOCKET	MySocket = INVALID_SOCKET;
	
	if(frameAdvance==1) refreshFeeds++; //counts the minutes

	switch(twatchState)
	{
		case TWATCH_INIT:
			trendParser.success=0; //clear these flag on first run
			searchParser.success=0;//display IP address and info until valid connection
			twatchState=TWATCH_TRENDS_TCP_START; //start TCP data grabber next cycle
			break;
		case TWATCH_IDLE:	//if this variable set, then start the refresh process		
			if(refreshFeeds>TWATCH_REFRESH_INTERVAL){ //if it has been at least 5 minutes, get new trends and tweet search results
				refreshFeeds=0;
				HTTPretry=0; //reset the number of retries
				twatchState=TWATCH_TRENDS_TCP_START; //start TCP data grabber next cycle
			}
			break;
		case TWATCH_TRENDS_TCP_START:
			//connect to twitter server
			MySocket = TCPOpen((DWORD)&ServerName[0], TCP_OPEN_RAM_HOST, ServerPort, TCP_PURPOSE_GENERIC_TCP_CLIENT);
			
			if(MySocket == INVALID_SOCKET) break; //abort if error, try again next time
			
			trendParser.updatingData=1; //updating data flag (probably not used anywhere)
			displayMode=UPDATE; //next LCD refresh will draw the update screen and then idle
			twatchState=TWATCH_TRENDS_TCP_SOCKET_OBTAINED;
			Timer = TickGet();
			break;

		case TWATCH_TRENDS_TCP_SOCKET_OBTAINED:
			// Wait for the remote server to accept our connection request
			if(!TCPIsConnected(MySocket))
			{
				// Time out if too much time is spent in this state
				if(TickGet()-Timer > 5*TICK_SECOND)
				{
					// Close the socket so it can be used by other modules
					TCPDisconnect(MySocket);
					MySocket = INVALID_SOCKET;
					twatchState--;
				}
				break;
			}

			Timer = TickGet();

			if(TCPIsPutReady(MySocket) < 125u) break; //if socket error, break and wait
	
			//form our trending topics JSON datafeed request
			TCPPutROMString(MySocket, (ROM BYTE*)"GET ");
			TCPPutROMString(MySocket, TrendURL); //use the trend URL
			TCPPutROMString(MySocket, (ROM BYTE*)" HTTP/1.0\r\nHost: ");
			TCPPutString(MySocket, ServerName);
			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nConnection: close\r\n\r\n");

			TCPFlush(MySocket); //send HTTP request to Twitter
			
			//setup/clear the parser struct
			trendParser.bufWritePointer=0;
			trendParser.foundTag=0;
			trendParser.tagCharMatchCnt=0;
			trendParser.tagTotalCnt=0;
			trendParser.bufWritePointer=0;
			searchParser.bufWritePointer=0;//reset the tweet buffer write pointer
			searchParser.term=0; //reset the number of terns in the tweet search parser structure
			for(i=0; i<MAX_TREND_TERMS; i++) searchParser.bufValueEndPosition[i]=0;//reset all buffer positions to 0
			HTTPstatus = UNKNOWN; //reset the http status checker
			HTTPheaderBufCnt=0; //status checker buffer counter

			twatchState=TWATCH_TRENDS_TCP_PROCESS_RESPONSE; //next time process any incoming data
			break;

		case TWATCH_TRENDS_TCP_PROCESS_RESPONSE:

			if(!TCPIsConnected(MySocket)) twatchState = TWATCH_TRENDS_TCP_DISCONNECT; //check if we're still connected // Do not break;  We might still have data in the TCP RX FIFO waiting for us
	
			w = TCPIsGetReady(MySocket);//how many bytes waiting?	
	
			//process the server reply
			i = sizeof(vBuffer)-1;
			vBuffer[i] = '\0';
			while(w){
				if(w < i){
					i = w;
					vBuffer[i] = '\0';
				}
				w -= TCPGetArray(MySocket, vBuffer, i);

				for(cnt=0;cnt<i;cnt++){
					//---------------//
					switch(HTTPstatus){ //check the first few bytes for HTTP/1.1 200 OK
						case UNKNOWN: //cache until a line break, then check header for response code before extracting tags
							HTTPheaderBuf[HTTPheaderBufCnt]=vBuffer[cnt];//add to the headerbuf array
							if(HTTPheaderBufCnt<19) HTTPheaderBufCnt++; //if it won't overrun the array, increment the counter
						
							if(vBuffer[cnt]==0x0d){//if current character is a line break, examine the header for the response code
								//is it HTTP?
								if(HTTPheaderBuf[0]=='H' &&	HTTPheaderBuf[1]=='T' && 
								HTTPheaderBuf[2]=='T' && HTTPheaderBuf[3]=='P' ){						
									//loop past /1.x and space
									HTTPheaderBufCnt=4;
									while(HTTPheaderBuf[HTTPheaderBufCnt]!=' '){
										HTTPheaderBufCnt++;
										if(HTTPheaderBufCnt>19) break; //buffer overrun
									}
									HTTPheaderBufCnt++;
									//is it 200? (should be a ASCII->int loop that gets the actual value for error handling.... check for overrun
									if( (HTTPheaderBufCnt <=17 ) && HTTPheaderBuf[HTTPheaderBufCnt]=='2' &&	HTTPheaderBuf[HTTPheaderBufCnt+1]=='0' && 
										HTTPheaderBuf[HTTPheaderBufCnt+2]=='0'){
										HTTPstatus=OK;//200 OK
									}else{
										HTTPstatus=ERROR; //other status, error
									}
								}
							}
							break;
						case OK: //HTTP is OK, process the byte
							procTrend(vBuffer[cnt]); //json parsing state maching
							break;
						case ERROR://do nothing because we need to clear the buffer
							break;
					}
					//------------------//
				}//for loop
				
				if(twatchState == TWATCH_TRENDS_TCP_PROCESS_RESPONSE) break;
			}//while
	
			break;
	
		case TWATCH_TRENDS_TCP_DISCONNECT:
			TCPDisconnect(MySocket); //close the socket
			MySocket = INVALID_SOCKET;
	
			//did not get valid HTML, retry, got no tags, retry
			if(HTTPstatus!=OK || trendParser.tagTotalCnt==0 ){
				HTTPretry++;
				if(HTTPretry>HTTP_MAX_RETRY){//retry 3 times, then wait a minute....
					twatchState = TWATCH_IDLE;
					LCD_CursorPosition(21); //display waiting error
					LCD_WriteString("*Error, waiting 5min");
					break;
				}
				LCD_CursorPosition(21); //display retry error
				LCD_WriteString("*Error, reconnecting");
				twatchState = TWATCH_TRENDS_TCP_START;
				break;
			}
			HTTPretry=0;
		
			addToTrendBuffer(' ');//add trailing space
			
			trendParser.updatingData=0; //data update complete, clear update flag
			if(trendParser.success==0){ //if this is the first time throuigh, set the success flag
				trendParser.success=1; //set success flag, used to identify the very first successful xfer and clear IP address screen
				LCD_refresh(); //clear IP, show update screen
			}
			displayMode=NEWSCROLL;//start scrolling the terms, tweets will show when available in the parser struct
			twatchState = TWATCH_SEARCH_TCP_START; //will start searching on each term next time. searchParser.term set to 0 above...
			break;

		case TWATCH_SEARCH_TCP_START: //begins searching for recent tweets for each trending term
			
			//don't continue if there's no more term, an error, or overrun
			if(searchParser.term>=trendParser.tagTotalCnt || searchParser.term>=MAX_TREND_TERMS ){//don't continue if there's no more terms left to search
				twatchState = TWATCH_IDLE; //go back to idle
				break;
			}
			
			//skip if 0 length term
			if(trendParser.bufValueStartPosition[searchParser.term]==trendParser.bufValueEndPosition[searchParser.term]) {
				searchParser.term++; //increment to next trend term
				twatchState = TWATCH_SEARCH_TCP_START; //try again with the next trend term
				break;
			}
		
			//connect to twitter
			MySocket = TCPOpen((DWORD)&ServerName[0], TCP_OPEN_RAM_HOST, ServerPort, TCP_PURPOSE_GENERIC_TCP_CLIENT);

			if(MySocket == INVALID_SOCKET) break; //abort on error

			twatchState=TWATCH_SEARCH_TCP_SOCKET_OBTAINED;
			Timer = TickGet();
			break;

		case TWATCH_SEARCH_TCP_SOCKET_OBTAINED:
			// Wait for the remote server to accept our connection request
			if(!TCPIsConnected(MySocket)){
				// Time out if too much time is spent in this state
				if(TickGet()-Timer > 5*TICK_SECOND){
					// Close the socket so it can be used by other modules
					TCPDisconnect(MySocket);
					MySocket = INVALID_SOCKET;
					twatchState--;
					//searchParser.term++; //increment to next trend term, don't get stuck in loop
										//should add retries
				}
				break;
			}

			Timer = TickGet();

			if(TCPIsPutReady(MySocket) < 125u) break; //socket ready for writes?

			
			TCPPutROMString(MySocket, (ROM BYTE*)"GET "); //setup the HTTP GET request 
			TCPPutROMString(MySocket, SearchURL);	//JSON search datafeed URL
			#ifndef JSON_DEBUG
			//add the search term to the JSON search URL. Requires urlencoding
			i=trendParser.bufValueStartPosition[searchParser.term]; //get the starting position of the term in the trend term buffer
			k=trendParser.bufValueEndPosition[searchParser.term]-1; //end position is one less because of auto increment
			//add each character of the trend term to the search URL
			while((i<k) && i<TREND_PARSER_BUFFER ){ //append each byte to the URL until the end position
				//URLencode anything not a-zA-Z0-9 -_.!~*'()
				if(URLencodeChar(trendParser.buf[i], &URLencode[0])==0){
					TCPPut(MySocket, trendParser.buf[i]); //no URLencode required;
				}else{
					TCPPutString(MySocket, URLencode); //use the URLencoded character now in URLencode array
				}
				i++;
			}
			#endif
			//form the rest of the HTTP request
			TCPPutROMString(MySocket, (ROM BYTE*)" HTTP/1.0\r\nHost: ");
			TCPPutString(MySocket, ServerName);
			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nConnection: close\r\n\r\n");

			TCPFlush(MySocket); //send the HTTP request to the Twitter server

			//setup the search parser struct
			searchParser.foundTag=0;
			searchParser.tagCharMatchCnt=0;
			searchParser.tagTotalCnt=0;
			searchParser.escape=0;
			HTTPstatus = UNKNOWN; //clear the HTTP status checker
			HTTPheaderBufCnt=0;

			addToSearchBuffer(0xff); //add beginning block to the text

			twatchState=TWATCH_SEARCH_TCP_PROCESS_RESPONSE;
			break;

		case TWATCH_SEARCH_TCP_PROCESS_RESPONSE:
			if(!TCPIsConnected(MySocket)) twatchState = TWATCH_SEARCH_TCP_DISCONNECT; //check for connection // Do not break;  We might still have data in the TCP RX FIFO waiting for us
	
			w = TCPIsGetReady(MySocket);	//how many bytes waiting?
	
			i = sizeof(vBuffer)-1;
			vBuffer[i] = '\0'; //add trailing 0 to array.

			while(w){ //process server reply
				if(w < i){
					i = w;
					vBuffer[i] = '\0';
				}
				w -= TCPGetArray(MySocket, vBuffer, i);

				for(cnt=0;cnt<i;cnt++){
					//---------------//
					switch(HTTPstatus){
						case UNKNOWN: //check header for response code before extracting tags
							HTTPheaderBuf[HTTPheaderBufCnt]=vBuffer[cnt];//add to the headerbuf array
							if(HTTPheaderBufCnt<19) HTTPheaderBufCnt++; //if it won't overrun the array, increment the counter
						
							if(vBuffer[cnt]==0x0d){//current character is a line break, examine the header for the response code
								//is it HTTP?
								if(HTTPheaderBuf[0]=='H' &&	HTTPheaderBuf[1]=='T' && 
								HTTPheaderBuf[2]=='T' && HTTPheaderBuf[3]=='P' ){						
									//loop past /1.x and space
									HTTPheaderBufCnt=4;
									while(HTTPheaderBuf[HTTPheaderBufCnt]!=' '){
										HTTPheaderBufCnt++;
										if(HTTPheaderBufCnt>19) break; //buffer overrun
									}
									HTTPheaderBufCnt++;
									//is it 200? (should be a ASCII->int loop that gets the actual value for error handling....
									if( ((HTTPheaderBufCnt+2) < 20) && HTTPheaderBuf[HTTPheaderBufCnt]=='2' &&	HTTPheaderBuf[HTTPheaderBufCnt+1]=='0' && 
										HTTPheaderBuf[HTTPheaderBufCnt+2]=='0'){
										HTTPstatus=OK;
									}else{
										HTTPstatus=ERROR;
									}
								}
							}
							break;
						case OK:
							procSearch(vBuffer[cnt]);
							break;
						case ERROR://do nothing because we need to clear the buffer
							break;
					}
					//------------------//
				}//for loop
				
				if(twatchState == TWATCH_SEARCH_TCP_PROCESS_RESPONSE) break;
			}//while
	
			break;
	
		case TWATCH_SEARCH_TCP_DISCONNECT:
			TCPDisconnect(MySocket); //close the socket
			MySocket = INVALID_SOCKET;

			//did not get valid HTML, retry, got no tags, retry once if no tags
			if(HTTPstatus!=OK ){
				HTTPretry++;
				if(HTTPretry>HTTP_MAX_RETRY){//retry, then wait till next time...
					twatchState = TWATCH_IDLE;
					break;
				}
				twatchState = TWATCH_SEARCH_TCP_START;
				break;
			}
			HTTPretry=0; //success, clear number or retries

			//repeat for each trend term
			searchParser.success=1;
			searchParser.term++;
			twatchState = TWATCH_SEARCH_TCP_START;
			break;

	}//switch
	
}//function
Пример #28
0
/*********************************************************************
 * Function:        void TelnetTask(void)
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void TelnetTask(void)
{
	BYTE 				i;
	WORD				w, w2;
	static TCP_SOCKET	MySocket = INVALID_SOCKET;
	static enum _TelnetState
	{
		SM_HOME = 0,
		SM_PRINT_LOGIN,
		SM_GET_LOGIN,
		SM_GET_PASSWORD,
		SM_GET_PASSWORD_BAD_LOGIN,
		SM_AUTHENTICATED,
		SM_REFRESH_VALUES,
	} 					TelnetState = SM_HOME;

	// Reset our state if the remote client disconnected from us
	if(MySocket != INVALID_SOCKET)
	{
		if(TCPWasReset(MySocket))
			TelnetState = SM_PRINT_LOGIN;
	}


	switch(TelnetState)
	{
		case SM_HOME:
			// Connect a socket to the remote TCP server
			MySocket = TCPOpen(0, TCP_OPEN_SERVER, TELNET_PORT, TCP_PURPOSE_TELNET);
			
			// Abort operation if no TCP socket of type TCP_PURPOSE_TELNET is available
			// If this ever happens, you need to go add one to TCPIPConfig.h
			if(MySocket == INVALID_SOCKET)
				break;

			TelnetState++;
			break;

		case SM_PRINT_LOGIN:
			// Make certain the socket can be written to
			if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strTitle))
				break;
			
			// Place the application protocol data into the transmit buffer.
			TCPPutROMString(MySocket, strTitle);

			// Send the packet
			TCPFlush(MySocket);
			TelnetState++;

		case SM_GET_LOGIN:
			// Make sure we can put the password prompt
			if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strPassword))
				break;

			// See if the user pressed return
			w = TCPFind(MySocket, '\n', 0, FALSE);
			if(w == 0xFFFFu)
			{
				if(TCPGetRxFIFOFree(MySocket) == 0u)
				{
					TCPPutROMString(MySocket, (ROM BYTE*)"\r\nToo much data.\r\n");
					TCPDisconnect(MySocket);
				}

				break;
			}
		
			// Search for the username -- case insensitive
			w2 = TCPFindROMArray(MySocket, (ROM BYTE*)USERNAME, sizeof(USERNAME)-1, 0, TRUE);
			if((w2 != 0) || !((sizeof(USERNAME)-1 == w) || (sizeof(USERNAME) == w)))
			{
				// Did not find the username, but let's pretend we did so we don't leak the user name validity
				TelnetState = SM_GET_PASSWORD_BAD_LOGIN;	
			}
			else
			{
				TelnetState = SM_GET_PASSWORD;
			}

			// Username verified, throw this line of data away
			TCPGetArray(MySocket, NULL, w + 1);

			// Print the password prompt
			TCPPutROMString(MySocket, strPassword);
			TCPFlush(MySocket);
			break;

		case SM_GET_PASSWORD:
		case SM_GET_PASSWORD_BAD_LOGIN:
			// Make sure we can put the authenticated prompt
			if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strAuthenticated))
				break;

			// See if the user pressed return
			w = TCPFind(MySocket, '\n', 0, FALSE);
			if(w == 0xFFFFu)
			{
				if(TCPGetRxFIFOFree(MySocket) == 0u)
				{
					TCPPutROMString(MySocket, (ROM BYTE*)"Too much data.\r\n");
					TCPDisconnect(MySocket);
				}

				break;
			}

			// Search for the password -- case sensitive
			w2 = TCPFindROMArray(MySocket, (ROM BYTE*)PASSWORD, sizeof(PASSWORD)-1, 0, FALSE);
			if((w2 != 3) || !((sizeof(PASSWORD)-1 == w-3) || (sizeof(PASSWORD) == w-3)) || (TelnetState == SM_GET_PASSWORD_BAD_LOGIN))
			{
				// Did not find the password
				TelnetState = SM_PRINT_LOGIN;	
				TCPPutROMString(MySocket, strAccessDenied);
				TCPDisconnect(MySocket);
				break;
			}

			// Password verified, throw this line of data away
			TCPGetArray(MySocket, NULL, w + 1);

			// Print the authenticated prompt
			TCPPutROMString(MySocket, strAuthenticated);
			TelnetState = SM_AUTHENTICATED;
			// No break
	
		case SM_AUTHENTICATED:
			if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strDisplay) + 4)
				break;

			TCPPutROMString(MySocket, strDisplay);
			TelnetState++;

			// All future characters will be bold
			TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[1m");

		case SM_REFRESH_VALUES:
			if(TCPIsPutReady(MySocket) >= 60u)
			{
				//[10;1]
				//"Analog:             1023\r\n"
				//"Buttons:         3 2 1 0\r\n"
				//"LEDs:    7 6 5 4 3 2 1 0\r\n"
	
				// Position cursor at Line 10, Col 21
				TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[10;21f");

				// Put analog value with space padding on right side for 4 characters
				TCPPutROMArray(MySocket, (ROM BYTE*)"    ", 4-strlen((char*)AN0String));
				TCPPutString(MySocket, AN0String);

				// Put Buttons
				TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[11;18f");
				TCPPut(MySocket, BUTTON3_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, BUTTON2_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, BUTTON1_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, BUTTON0_IO ? '1':'0');
	
	
				// Put LEDs
				TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[12;10f");
				TCPPut(MySocket, LED7_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED6_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED5_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED4_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED3_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED2_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED1_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED0_IO ? '1':'0');
	
	
				// Put cursor at beginning of next line
				TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[13;1f");

				// Send the data out immediately
				TCPFlush(MySocket);
			}

			if(TCPIsGetReady(MySocket))
			{
				TCPGet(MySocket, &i);
				switch(i)
				{
					case '\r':
					case 'q':
					case 'Q':
						if(TCPIsPutReady(MySocket) >= strlenpgm((ROM char*)strGoodBye))
							TCPPutROMString(MySocket, strGoodBye);
						TCPDisconnect(MySocket);
						TelnetState = SM_PRINT_LOGIN;							
						break;
				}
			}

			break;
	}
}
void twatchTasks(void){ //this state machine services the #twatch

   static enum _twitterTCPstate{
		TWITTER_INIT=0,
		HOLD_COLOR,
		TWITTER_IDLE,
		TWITTER_SEARCH_TCP_START,
		TWITTER_SEARCH_TCP_SOCKET_OBTAINED,
		TWITTER_SEARCH_TCP_PROCESS_RESPONSE,
		TWITTER_SEARCH_TCP_DISCONNECT,
	} twitterTCPstate = TWITTER_INIT; //massive twitter parsing state machine

   static enum _HTTPstatus{
		UNKNOWN=0,
		OK,
		ERROR,
	} HTTPstatus = UNKNOWN; //get and track HTTP status and handle errors
	static unsigned char HTTPheaderBuf[20]; //used to store HTTP headers 
	static unsigned char HTTPheaderBufCnt; //pointer

	static BYTE HTTPretry=0, gotID=0;//extra static vars for twitter parser

	unsigned char tcpReadBytes, cnt;
	unsigned int	tcpTotalBytes; //for TCPsocket length, can be >256
	#define TCPBUF_LENGTH 50 //best size
	unsigned char	tcpBuf[TCPBUF_LENGTH];
	static DWORD		Timer;
	static TCP_SOCKET	TCPSocket = INVALID_SOCKET;

	static struct _timekeeper{
		DWORD	ticks;
		unsigned char minutes;
		unsigned char seconds;
		unsigned char runsec; //running seconds counter
	} time;

	//a minutes counter for determining when to refresh the search results
	if(TickGet() - time.ticks >= TICK_SECOND){
		time.ticks = TickGet();
		time.seconds++;
		time.runsec++;
		if(time.seconds>59){
			time.seconds=0;
			time.minutes++;
			if(time.minutes>59){
				time.minutes=0;
			}
		}
	}

	switch(twitterTCPstate){

		case TWITTER_INIT: //setup JSON parser structs on first run
			searchParser.searchTag=textTag;//tag to search for
			searchParser.searchTagLength=(sizeof(textTag)-1);//length of search tag
			searchParser.valueBuffer=tweetBuf; //assign buffer to this struct
			searchParser.valueBufferLength=TWEETCHARS;//buffer length
			searchParser.valueEndChar='"'; //text tag, value ends with "

			nameParser.searchTag=nameTag;//tag to name for
			nameParser.searchTagLength=(sizeof(nameTag)-1);//length of name tag
			nameParser.valueBuffer=nameBuf; //assign buffer to this struct
			nameParser.valueBufferLength=NAMECHARS;//buffer length
			nameParser.valueEndChar='"'; //text tag, value ends with "

			max_idParser.searchTag=max_idTag;//tag to search for
			max_idParser.searchTagLength=(sizeof(max_idTag)-1);//length of search tag
			max_idParser.valueBuffer=lastidTempBuf; //assign buffer to this struct
			max_idParser.valueBufferLength=MAX_IDCHARS;//buffer length
			max_idParser.valueEndChar=','; //text tag, value ends with "
			max_idParser.valueBuffer[20]='\0'; //ensure 0 termination

			//zero the last ID before first call
			lastidBuf[0]='\0';
			lastidBuf[1]='\0';

			//reset printer
			UARTTX(0x1b);
			UARTTX('@');
			//Control parameter command
			UARTTX(0x1b);
			UARTTX(0x37);
			UARTTX(0x07);//max printing dots
			UARTTX(0xFF);//heating time
			UARTTX(0x05);	//heating interval
			twitterTCPstate=TWITTER_SEARCH_TCP_START; //start TCP data grabber next cycle

			break;
		case HOLD_COLOR:
			if(time.runsec<HOLD_SECONDS){
				break;
			}		
			twitterTCPstate=TWITTER_IDLE;	
		case TWITTER_IDLE:	//if this variable set, then start the refresh process		
			//have we played all the buffered text
			if(T.cnt>0 && UART_EMPTY()){//step through text when idle
				
				if(T.t[T.read]==0xFF){//0xFF, end of tweet. reset line counter
					T.lncnt=0;
				}else{
					UARTTX(T.t[T.read]);
					T.lncnt++;

					//send a LF at the end of each X characters
					if(T.lncnt==PRINTER_WIDTH){
						UARTTX(0x0a);
						T.lncnt=0;
						
						twitterTCPstate=HOLD_COLOR;//next time hold solid color
					}
				}

				T.read++;
				//is this the final text?
				T.cnt--;
				if(T.cnt==0){//done with text
					time.runsec=0;//clear running counter for pause
					#ifndef DEBUG
						UARTTX(0x0a);
						UARTTX(0x0a);
						twitterTCPstate=HOLD_COLOR;//next time hold solid color
					#endif
				}

			}else if(time.seconds>=REFRESH_INTERVAL){ //if it has been at least X minutes, get tweet search results
				time.seconds=0;
				HTTPretry=0; //reset the number of retries	
				twitterTCPstate=TWITTER_SEARCH_TCP_START; //start TCP data grabber next cycle
			}			
			break;
		case TWITTER_SEARCH_TCP_START: //begins search for tweets 
			//setup the search parser struct
			resetJSONparser(&nameParser);
			resetJSONparser(&searchParser);
			resetJSONparser(&max_idParser);
			gotID=0; //reset the ID finder
			T.cnt=0; //reset the tweet letter counter	
			T.read=0; //reset the read pointer	
			HTTPstatus = UNKNOWN; //clear the HTTP status checker
			HTTPheaderBufCnt=0;
					
			//connect to twitter
			TCPSocket = TCPOpen((DWORD)&ServerName[0], TCP_OPEN_RAM_HOST, ServerPort, TCP_PURPOSE_GENERIC_TCP_CLIENT);

			if(TCPSocket == INVALID_SOCKET) break; //abort on error

			twitterTCPstate=TWITTER_SEARCH_TCP_SOCKET_OBTAINED;
			Timer = TickGet();
			break;

		case TWITTER_SEARCH_TCP_SOCKET_OBTAINED:
			//wait for server, with timeout
			if(!TCPIsConnected(TCPSocket)){
				if(TickGet()-Timer > 5*TICK_SECOND){
					TCPDisconnect(TCPSocket);
					TCPSocket = INVALID_SOCKET;
					twitterTCPstate--;
				}
				break;
			}

			Timer = TickGet();

			if(TCPIsPutReady(TCPSocket) < 125u) break; //socket ready for writes?
			
			TCPPutROMString(TCPSocket, (ROM BYTE*)"GET "); //setup the HTTP GET request 
			TCPPutROMString(TCPSocket, SearchURL);	//JSON search datafeed URL

			//add the last ID to the JSON search URL. (usually requires urlencoding, but we have numbers only)
			//#ifdef 0
			if(lastidBuf[0]!='\0'){ //don't put 0 length IDs into TCP, kills socket
				TCPPutString(TCPSocket, lastidBuf); //put the string in the TCP buffer
			}
			//#endif

			//form the rest of the HTTP request
			TCPPutROMString(TCPSocket, (ROM BYTE*)" HTTP/1.0\r\nHost: ");
			TCPPutString(TCPSocket, ServerName);
			TCPPutROMString(TCPSocket, (ROM BYTE*)"\r\nConnection: close\r\n\r\n");

			TCPFlush(TCPSocket); //send the HTTP request to the Twitter server

			twitterTCPstate=TWITTER_SEARCH_TCP_PROCESS_RESPONSE;
			break;

		case TWITTER_SEARCH_TCP_PROCESS_RESPONSE:
			if(!TCPIsConnected(TCPSocket)) twitterTCPstate = TWITTER_SEARCH_TCP_DISCONNECT; //check for connection // Do not break;  We might still have data in the TCP RX FIFO waiting for us

			tcpTotalBytes = TCPIsGetReady(TCPSocket);	//how many bytes waiting?
			tcpReadBytes = TCPBUF_LENGTH;

			while(tcpTotalBytes){ //process server reply
				if(tcpTotalBytes < tcpReadBytes){
					tcpReadBytes = tcpTotalBytes;
				}
				tcpTotalBytes -= TCPGetArray(TCPSocket, tcpBuf, tcpReadBytes);

				for(cnt=0;cnt<tcpReadBytes;cnt++){
					UART2TX(tcpBuf[cnt]);
					//---------------//
					switch(HTTPstatus){
						case UNKNOWN: //check header for response code before extracting tags
							HTTPheaderBuf[HTTPheaderBufCnt]=tcpBuf[cnt];//add to the headerbuf array
							if(HTTPheaderBufCnt<19) HTTPheaderBufCnt++; //if it won't overrun the array, increment the counter
						
							if(tcpBuf[cnt]==0x0d){//current character is a line break, examine the header for the response code
								//is it HTTP?
								if(HTTPheaderBuf[0]=='H' &&	HTTPheaderBuf[1]=='T' && 
								HTTPheaderBuf[2]=='T' && HTTPheaderBuf[3]=='P' ){						
									//loop past /1.x and space
									HTTPheaderBufCnt=4;
									while(HTTPheaderBuf[HTTPheaderBufCnt]!=' '){
										HTTPheaderBufCnt++;
										if(HTTPheaderBufCnt>19) break; //buffer overrun
									}
									HTTPheaderBufCnt++;
									//is it 200? (should be a ASCII->int loop that gets the actual value for error handling....
									if( ((HTTPheaderBufCnt+2) < 20) && HTTPheaderBuf[HTTPheaderBufCnt]=='2' &&	HTTPheaderBuf[HTTPheaderBufCnt+1]=='0' && 
										HTTPheaderBuf[HTTPheaderBufCnt+2]=='0'){
										HTTPstatus=OK;
									}else{
										HTTPstatus=ERROR;
									}
								}
							}
							break;
						case OK:
							if(tagSearch(tcpBuf[cnt], &nameParser)){//process the tweet for color data
								processname(nameParser.valueBufferCounter);
							}
							if(tagSearch(tcpBuf[cnt], &searchParser)){//process the tweet for color data
								processtweet(searchParser.valueBufferCounter);
							}
							if(gotID==0){//get only the first (highest) tweet ID to append to the URL next time
								if(tagSearch(tcpBuf[cnt], &max_idParser)){
									addValueByte('\0', &max_idParser);
									for(gotID=0; gotID<21; gotID++){
										lastidBuf[gotID]=lastidTempBuf[gotID];//only overwrite if comlete
									}
									gotID=1;
								}
							}
							break;
						case ERROR://do nothing because we need to clear the buffer
							break;
					}
					//------------------//
				}//for loop
				
				if(twitterTCPstate == TWITTER_SEARCH_TCP_PROCESS_RESPONSE) break;
			}//while
	
			break;
	
		case TWITTER_SEARCH_TCP_DISCONNECT:
			TCPDisconnect(TCPSocket); //close the socket
			TCPSocket = INVALID_SOCKET;

			//did not get valid HTML, retry, got no tags, retry once if no tags
			if(HTTPstatus!=OK ){
				HTTPretry++;
				if(HTTPretry>(HTTP_MAX_RETRY-1)){//retry, then wait till next time...
					twitterTCPstate = TWITTER_IDLE;
					time.seconds=0;
					break;
				}
				twitterTCPstate = TWITTER_SEARCH_TCP_START;
				break;
			}
			HTTPretry=0; //success, clear number or retries

			twitterTCPstate = TWITTER_IDLE;
			break;

	}//switch
	
Пример #30
0
/*****************************************************************************
  Function:
    void GenericSSLClient(void)

  Summary:
    Implements a simple HTTP client (over TCP).

  Description:
    This function implements a simple HTTP client, which operates over TCP.  
    The function is called periodically by the stack, and waits for BUTTON1 
    to be pressed.  When the button is pressed, the application opens a TCP
    connection to an Internet search engine, performs a search for the word
    "Microchip" on "microchip.com", and prints the resulting HTML page to
    the UART.  
    
    To add this to an existing application, make the call to GenericSSLClient 
    from StackTasks.
    
    This example can be used as a model for many TCP and HTTP client
    applications.

  Precondition:
    TCP is initialized.

  Parameters:
    None

  Returns:
    None
  ***************************************************************************/
void GenericSSLClient(void)
{
    uint8_t             i;
    uint16_t            w;
    DNS_RESULT          dnsRes;
    uint8_t             vBuffer[9];
    static TCPIP_NET_HANDLE    netH;
    static uint32_t     clientTimer;
    static TCP_SOCKET   MySocket = INVALID_SOCKET;
    static enum _GenericTCPExampleState
    {
        SM_HOME = 0,
        SM_WAIT_DNS,
        SM_DNS_RESOLVED,
        SM_SOCKET_OBTAINED,
        SM_START_SSL,
        SM_PROCESS_RESPONSE,
        SM_DISCONNECT,
        SM_DONE
    } GenericTCPExampleState = SM_DONE;

    switch(GenericTCPExampleState)
    {

        case SM_HOME:
            
            netH = TCPIP_STACK_GetDefaultNet();
            dnsRes = DNSBeginUsage(netH);
            if(dnsRes != DNS_RES_OK)
                break;
            DNSResolve(SSLServerName, DNS_TYPE_A);
            GenericTCPExampleState++;
            break;

        case SM_WAIT_DNS:
            
            dnsRes = DNSIsResolved(SSLServerName, &serverIP_SSL);
            if(dnsRes == DNS_RES_PENDING)
            {   // ongoing operation;
                break;
            }
            else if(dnsRes < 0)
            {   // some DNS error occurred; retry
                SYS_CONSOLE_MESSAGE((const char*)"\r\n\r\nDNS name resolving failed...\r\n");
                TCPClose(MySocket);
                MySocket = INVALID_SOCKET;
                GenericTCPExampleState = SM_HOME;
            }
            else
            {
                clientTimer = SYS_TICK_Get();
                GenericTCPExampleState++;
            }
            DNSEndUsage(netH);
            break;

        case SM_DNS_RESOLVED:
            // Connect the socket to the remote TCP server
            MySocket = TCPOpenClient(IP_ADDRESS_TYPE_IPV4, SSLServerPort, (IP_MULTI_ADDRESS*)&serverIP_SSL);
            
			// Abort operation if no TCP socket could be opened.
			// If this ever happens, you need to update your tcp_config.h
            if(MySocket == INVALID_SOCKET)
            {   // retry
                break;
            }

            SYS_CONSOLE_MESSAGE((const char*)"\r\n\r\nConnecting using Microchip TCP API...\r\n");

            GenericTCPExampleState++;
            clientTimer = SYS_TICK_Get();
            break;

        case SM_SOCKET_OBTAINED:

            // Wait for the remote server to accept our connection request
            if(!TCPIsConnected(MySocket))
            {
                // Time out if more than 5 seconds is spent in this state
                if((SYS_TICK_Get()-clientTimer) > 5 * SYS_TICK_TicksPerSecondGet() )
                {
                    // Close the socket so it can be used by other modules
                    TCPClose(MySocket);
                    MySocket = INVALID_SOCKET;
                    GenericTCPExampleState--;
                    SYS_CONSOLE_MESSAGE((const char*)"\r\n\r\nFailed connecting to the remote server...\r\n");
                }
                break;
            }

            clientTimer = SYS_TICK_Get();

            if(!TCPStartSSLClient(MySocket,(uint8_t *)"thishost"))
                break;

            GenericTCPExampleState++;
            break;

        case SM_START_SSL:
            if (TCPSSLIsHandshaking(MySocket)) 
            {
                // Handshaking may fail if the SSL_RSA_CLIENT_SIZE is not large enough
                // for the server’s certificate
                if(SYS_TICK_Get()-clientTimer > 10*SYS_TICK_TicksPerSecondGet())
                {
                    // Close the socket so it can be used by other modules
                    TCPClose(MySocket);
                    MySocket = INVALID_SOCKET;
                    GenericTCPExampleState=SM_HOME;
                }
                break;
            }


            // Make certain the socket can be written to
            if(TCPIsPutReady(MySocket) < 125u)
                break;
            
            // Place the application protocol data into the transmit buffer.  For this example, we are connected to an HTTP server, so we'll send an HTTP GET request.
            TCPPutString(MySocket, (const uint8_t*)"GET ");
            TCPPutString(MySocket, SSLRemoteURL);
            TCPPutString(MySocket, (const uint8_t*)" HTTP/1.0\r\nHost: ");
            TCPPutString(MySocket, (const uint8_t*)SSLServerName);
            TCPPutString(MySocket, (const uint8_t*)"\r\nConnection: close\r\n\r\n");

            // Send the packet
            TCPFlush(MySocket);
            GenericTCPExampleState++;
            break;

        case SM_PROCESS_RESPONSE:
            // Check to see if the remote node has disconnected from us or sent us any application data
            // If application data is available, write it to the UART
            if(!TCPIsConnected(MySocket))
            {
                GenericTCPExampleState = SM_DISCONNECT;
                // Do not break;  We might still have data in the TCP RX FIFO waiting for us
            }
    
            // Get count of RX bytes waiting
            w = TCPIsGetReady(MySocket);    
    
            // Obtian and print the server reply
            i = sizeof(vBuffer)-1;
            vBuffer[i] = '\0';
            while(w)
            {
                if(w < i)
                {
                    i = w;
                    vBuffer[i] = '\0';
                }
                w -= TCPGetArray(MySocket, vBuffer, i);
                SYS_CONSOLE_MESSAGE((char*)vBuffer);
                
                // SYS_CONSOLE_MESSAGE is a blocking call which will slow down the rest of the stack 
                // if we shovel the whole TCP RX FIFO into the serial port all at once.  
                // Therefore, let's break out after only one chunk most of the time.  The 
                // only exception is when the remote node disconncets from us and we need to 
                // use up all the data before changing states.
                if(GenericTCPExampleState == SM_PROCESS_RESPONSE)
                    break;
            }
    
            break;
    
        case SM_DISCONNECT:
            // Close the socket so it can be used by other modules
            // For this application, we wish to stay connected, but this state will still get entered if the remote server decides to disconnect
            TCPClose(MySocket);
            MySocket = INVALID_SOCKET;
            GenericTCPExampleState = SM_DONE;
            break;
    
        case SM_DONE:
            // Do nothing unless the user pushes BUTTON1 and wants to restart the whole connection/download process
            if(BUTTON1_IO == 0u)
                GenericTCPExampleState = SM_HOME;
            break;
    }
}