/***	void TcpClient::discardReadBuffer(void)
**
**	Synopsis:   
**      Empties (flushes) the input (read) buffer.
**      All bytes are discarded.
**
**	Parameters:
**      None
**
**	Return Values:
**      None
**
**	Errors:
**      None
**
**  Notes:
**
**      This call is safe to make without checking the connection status.
**
*/
void TcpClient::discardReadBuffer(void)
{
    // run periodic tasks, and finish a connection
    isConnected(DNETcK::msImmediate);

    if(_hTCP < INVALID_SOCKET)
    {
        // clean out the buffer
        TCPDiscard(_hTCP);
    }
}
/***	void TCPSocket::close(void)
**
**	Synopsis:   
**      Closes the socket and clears the TCPSocket instance;
**      Returns the instance to a just constructed state releasing
**      all resources.
**
**	Parameters:
**      None
**
**	Return Values:
**      None
**
**	Errors:
**      None
**
**  Notes:
**
**      Returns the TCPSocket instance to
**      a state just as if the instance had just been
**      constructed. It also, Close the connection if
**      if it is still active.
**
*/
void TCPSocket::close(void)
{
    if(_classState != ipsNotInitialized)
    {
        // clean out the buffer
        TCPDiscard(&_socket);

        // release the resources back to stack
        TCPClose(&_socket, NULL);
    }

    // reset our member variables
    clear(false);
 }
/***	void TcpClient::close(void)
**
**	Synopsis:   
**      Closes the socket and clears the TcpClient instance;
**      Returns the instance to a just constructed state releasing
**      all resources.
**
**	Parameters:
**      None
**
**	Return Values:
**      None
**
**	Errors:
**      None
**
**  Notes:
**
**      Returns the TcpClient instance to 
**      a state just as if the instance had just been
**      constructed. It also, Close the connection if
**      if it is still active.
**
*/
void TcpClient::close(void)
{
    if(_hTCP < INVALID_SOCKET)
    {
        // clean out the buffer
        TCPDiscard(_hTCP);

        // release the resources back to the MAL
        TCPClose(_hTCP);
    }

    // we are just closed
    _hTCP = INVALID_SOCKET;
    _classState = DNETcK::NotConnected;

    // say the enpoints are gone too
    _fEndPointsSetUp = false;
 }
Example #4
0
/****************************************************************************
  Function:
   TCP_SOCKET ChipKITClientConnect(unsigned int dwOpenVal, BYTE vRemoteHostType, unsigned short wPort, unsigned int cSecTimout)

  Description:
    This routine opens a socket and for clients only, attempts to connect to the server.
	DNS lookups are done if a URL is specifed for dwOpenVal and vRemoteHostType == TCP_OPEN_RAM_HOST
	
  Precondition:
    None

  Parameters:
    dwOpenVal		- Same as in TCPOpen
	vRemoteHostType	- Same as in TCPOpen
	wPort			- Same as in TCPOpen
	cSecTimout		- If this is a client connecting to a host, this is the number of seconds to wait for a 
						successful connection to occur

  Returns:
   	The valid socket if the open was successful, or INVALID_SOCKET if no sockets were avaiable or 
	the connection was not made (in the case of a client)

  Remarks:
	This routine will attempt to wait until the connection is made for client, but will return immediately for servers as servers
	listen for connections. For the client case, if cSecTimout is exceeded, the connection is close and the socket released back to
	the stack for reuse.
   ***************************************************************************/
TCP_SOCKET ChipKITClientConnect(unsigned int dwOpenVal, BYTE vRemoteHostType, unsigned short wPort, unsigned int cSecTimout)
{
	TCP_SOCKET hTCP = UNKNOWN_SOCKET;
	DWORD t = 0;

	hTCP = TCPOpen((DWORD) dwOpenVal, vRemoteHostType, (WORD) wPort, TCP_PURPOSE_DEFAULT);
	ChipKITPeriodicTasks();

	// if it just fails, don't even attempt a retry
	if(hTCP == INVALID_SOCKET)
	{
		return(hTCP);
	}

	// if this is a client, we have to wait until we connect
	// No need to do this for servers as they connect when some one comes in on the listen
	if(vRemoteHostType != TCP_OPEN_SERVER) 
	{
		t = TickGet(); // so we don't loop forever
		while(!TCPIsConnected(hTCP))
		{
		 	ChipKITPeriodicTasks();
	
			// if after 10 seconds we do not connect, just fail and clean up
			if( (TickGet() - t) >= (cSecTimout * TICK_SECOND))
			{
				TCPClose(hTCP);
				TCPDiscard(hTCP);
				hTCP = INVALID_SOCKET;
				
				// make sure we run tasks again to get for the close to take effect
				// so don't return here, break out of the while to clean up
				break;  
			}
		}
				
		ChipKITPeriodicTasks();
	}

	return(hTCP);
}
/***	void TcpServer::close(void)
**
**	Synopsis:   
**      Stops Listening and closes all unaccepted sockets/connections
**      and clears everything back to it's originally constructed state.
**
**	Parameters:
**      None
**
**	Return Values:
**      None
**
**	Errors:
**      None
**
**  Notes:
**
**      Returns the TcpServer instance to 
**      a state just as if the instance had just been
**      constructed. It also, Close all connections
**      and releases all resources (sockets).
**
*/
void TcpServer::close(void)
{
    stopListening();

    for(int i = 0; i<_cMaxPendingAllowed; i++)
    {
        if(_rghTCP[i] < INVALID_SOCKET)
        {
            // clean out the buffer
            TCPDiscard(_rghTCP[i]);

            // release the resources back to the MAL
            TCPClose(_rghTCP[i]);

            // invalidate the socket
            _rghTCP[i] = INVALID_SOCKET;
        }
    }

    clear();
}
Example #6
0
/****************************************************************************
  Function:
    void ChipKITClientStop(TCP_SOCKET hTCP)

  Description:
    This routine closes the socket, discards the input buffer, and returns the socket to the TCPIP stack.

  Precondition:
    hTCP must be open and valid.

  Parameters:
    hTCP - The socket to close

  Returns:
    none

  Remarks:
	This is to match functionality of the Arduino Client class stop method
  ***************************************************************************/
void ChipKITClientStop(TCP_SOCKET hTCP)
{

	// the MAL can hang if you attempt to close an invalid socket
	if(hTCP == INVALID_SOCKET || hTCP == UNKNOWN_SOCKET)
	{
		return;
	}

	// close the handle
	TCPClose(hTCP);

	// empty the receive buffer because we are killing it.
	TCPDiscard(hTCP);

	// loop until it is acknowledged to be closed
	do
	{
		ChipKITPeriodicTasks();
	} while(TCPIsConnected(hTCP));	

}
/***	void TcpServer::stopListening(void)
**
**	Synopsis:   
**      This stops listening on the server port, but does not shutdown TcpServer
**
**	Parameters:
**     None
**
**	Return Values:
**      None
**
**	Errors:
**      None
**
**  Notes:
**      To resume listening, just call ResumeListening
**      This is a soft stop listening in that only the server stops listening on the port
**      however the instance is still valid and you can continue to accept pending client.
**      and you can resume the listening.
**
*/
void TcpServer::stopListening(void)
{
    // DO NOT blow away pending clients.
    // that will be done on a close()
    // update the pending count so we have them all.
    availableClients();

    if(_cPending < _cPendingMax && _rghTCP[_cPending] < INVALID_SOCKET)
    {
        // clean out the buffer
        TCPDiscard(_rghTCP[_cPending]);

        // release the resources back to the MAL
        TCPClose(_rghTCP[_cPending]);

        // only invalidate if this is the listening socket
        _rghTCP[_cPending] = INVALID_SOCKET;
    }

    // no longer listening
    _fListening = false;
}
Example #8
0
/****************************************************************************
  Function:
    void ChipKITClientFlush(TCP_SOCKET hTCP)

  Description:
    This routine discards any bytes in the socket input buffer

  Precondition:
    hTCP must be open and valid.

  Parameters:
    hTCP - The socket to check

  Returns:
    none.

  Remarks:
	This is to match functionality of the Arduino Client class flush method
	In Arduino, flush means to discard the input buffer which is different than
	Flush in the MAL which means to push the data out on the wire.
  ***************************************************************************/
void ChipKITClientFlush(TCP_SOCKET hTCP)
{
	TCPDiscard(hTCP);
	ChipKITPeriodicTasks();
}
Example #9
0
static HTTP_IO_RESULT HTTPMPFSUpload(void)
{
	BYTE c[16];
	WORD lenA, lenB;
	
	switch(curHTTP.httpStatus)
	{
		// New upload, so look for the CRLFCRLF
		case HTTP_MPFS_UP:
		
			lenA = TCPFindROMArray(sktHTTP, (ROM BYTE*)"\r\n\r\n", 4, 0, FALSE);
		
			if(lenA != 0xffff)
			{// Found it, so remove all data up to and including
				lenA = TCPGetArray(sktHTTP, NULL, lenA);
				curHTTP.byteCount -= lenA;
				
				// Make sure first 6 bytes are also in
				if(TCPIsGetReady(sktHTTP) < (4 + 6) )
				{
					lenA++;
					return HTTP_IO_NEED_DATA;
				}
				
				// Make sure it's an MPFS of the correct version
				lenA = TCPGetArray(sktHTTP, c, 10);
				curHTTP.byteCount -= lenA;
				if(memcmppgm2ram(c, (ROM void*)"\r\n\r\nMPFS\x02\x00", 10) == 0)
				{// Read as Ver 2.0
					curHTTP.httpStatus = HTTP_MPFS_OK;
					
					// Format MPFS storage and put 6 byte tag
					curHTTP.file = MPFSFormat();
					MPFSPutArray(curHTTP.file, &c[4], 6);
				}
				else
				{// Version is wrong
					curHTTP.httpStatus = HTTP_MPFS_ERROR;
				}
			}
			else
			{// Otherwise, remove as much as possible
				lenA = TCPGetArray(sktHTTP, NULL, TCPIsGetReady(sktHTTP) - 4);
				curHTTP.byteCount -= lenA;
			}
			
			break;
		
		// Received file is invalid
		case HTTP_MPFS_ERROR:
			curHTTP.byteCount -= TCPIsGetReady(sktHTTP);
			TCPDiscard(sktHTTP);
			if(curHTTP.byteCount < 100 || curHTTP.byteCount > 0x80000000)
			{// If almost all data was read, or if we overflowed, then return
				smHTTP = SM_HTTP_SERVE_HEADERS;
				return HTTP_IO_DONE;
			}
			break;
		
		// File is verified, so write the data
		case HTTP_MPFS_OK:
			// Determine how much to read
			lenA = TCPIsGetReady(sktHTTP);
			if(lenA > curHTTP.byteCount)
				lenA = curHTTP.byteCount;
				
			while(lenA > 0)
			{
				lenB = TCPGetArray(sktHTTP, c, mMIN(lenA,16));
				curHTTP.byteCount -= lenB;
				lenA -= lenB;
				MPFSPutArray(curHTTP.file, c, lenB);
			}
				
			// If we've read all the data
			if(curHTTP.byteCount == 0)
			{
				MPFSPutEnd();
				smHTTP = SM_HTTP_SERVE_HEADERS;
				return HTTP_IO_DONE;
			}
	}
		
	// Ask for more data
	return HTTP_IO_NEED_DATA;
	
}
Example #10
0
static BOOL PutFile(void)
{
    BYTE v;


    switch(smFTPCommand)
    {
    case SM_FTP_CMD_IDLE:
        if ( !FTPFlags.Bits.bLoggedIn )
        {
            FTPResponse     = FTP_RESP_LOGIN;
            return TRUE;
        }
        else
        {
            FTPResponse     = FTP_RESP_DATA_OPEN;
            FTPDataSocket   = TCPConnect(&REMOTE_HOST(FTPSocket), FTPDataPort.Val);

			// Make sure that a valid socket was available and returned
			// If not, return with an error
			if(FTPDataSocket != INVALID_SOCKET)
			{
	            smFTPCommand = SM_FTP_CMD_WAIT;
			}
			else
			{
	            FTPResponse = FTP_RESP_DATA_NO_SOCKET;
	            return TRUE;
			}
        }
        break;

    case SM_FTP_CMD_WAIT:
        if ( TCPIsConnected(FTPDataSocket) )
        {
#if defined(FTP_PUT_ENABLED)
            if ( !MPFSIsInUse() )
#endif
            {
#if defined(FTP_PUT_ENABLED)
                FTPFileHandle   = MPFSFormat();
#endif

                smFTPCommand    = SM_FTP_CMD_RECEIVE;
            }
        }
        break;

    case SM_FTP_CMD_RECEIVE:
        if ( TCPIsGetReady(FTPDataSocket) )
        {
            // Reload timeout timer.
            lastActivity    = TickGet();
            MPFSPutBegin(FTPFileHandle);
            while( TCPGet(FTPDataSocket, &v) )
            {
                USARTPut(v);

#if defined(FTP_PUT_ENABLED)
                MPFSPut(v);
#endif
            }
            FTPFileHandle = MPFSPutEnd();
            TCPDiscard(FTPDataSocket);

			// Print hash characters on FTP client display
	        if(TCPIsPutReady(FTPSocket))
	        {
				TCPPut(FTPSocket, '#');
				TCPFlush(FTPSocket);
	        }

        }
        else if ( !TCPIsConnected(FTPDataSocket) )
        {
#if defined(FTP_PUT_ENABLED)
            MPFSPutEnd();
            MPFSClose();
#endif
            TCPDisconnect(FTPDataSocket);
            FTPDataSocket   = INVALID_SOCKET;
            FTPResponse     = FTP_RESP_DATA_CLOSE;
            return TRUE;
        }
    }
    return FALSE;
}
Example #11
0
/*********************************************************************
 * Function:        void FTPServer(void)
 *
 * PreCondition:    FTPInit() must already be called.
 *
 * Input:           None
 *
 * Output:          Opened FTP connections are served.
 *
 * Side Effects:    None
 *
 * Overview:
 *
 * Note:            This function acts as a task (similar to one in
 *                  RTOS).  This function performs its task in
 *                  co-operative manner.  Main application must call
 *                  this function repeatdly to ensure all open
 *                  or new connections are served on time.
 ********************************************************************/
BOOL FTPServer(void)
{
    BYTE v;
    TICK currentTick;

    if ( !TCPIsConnected(FTPSocket) )
    {
        FTPStringLen    = 0;
        FTPCommand      = FTP_CMD_NONE;
        smFTP           = SM_FTP_NOT_CONNECTED;
        FTPFlags.Val    = 0;
        smFTPCommand    = SM_FTP_CMD_IDLE;
        return TRUE;
    }

    if ( TCPIsGetReady(FTPSocket) )
    {
        lastActivity    = TickGet();

        while( TCPGet(FTPSocket, &v ) )
        {
            USARTPut(v);
            FTPString[FTPStringLen++]   = v;
            if ( FTPStringLen == MAX_FTP_CMD_STRING_LEN )
                FTPStringLen            = 0;
        }
        TCPDiscard(FTPSocket);


        if ( v == '\n' )
        {
            FTPString[FTPStringLen]     = '\0';
            FTPStringLen                = 0;
            ParseFTPString();
            FTPCommand                  = ParseFTPCommand(FTP_argv[0]);
        }
    }
    else if ( smFTP != SM_FTP_NOT_CONNECTED )
    {
        currentTick = TickGet();
        currentTick = TickGetDiff(currentTick, lastActivity);
        if ( currentTick >= FTP_TIMEOUT )
        {
            lastActivity                = TickGet();
            FTPCommand                  = FTP_CMD_QUIT;
            smFTP                       = SM_FTP_CONNECTED;
        }
    }

    switch(smFTP)
    {
    case SM_FTP_NOT_CONNECTED:
        FTPResponse = FTP_RESP_BANNER;
        lastActivity = TickGet();
        /* No break - Continue... */

    case SM_FTP_RESPOND:
SM_FTP_RESPOND_Label:
        if(!TCPIsPutReady(FTPSocket))
		{
			return TRUE;
		}
		else
		{
			ROM char* pMsg;
			
			pMsg = FTPResponseString[FTPResponse];
			
			while( (v = *pMsg++) )
			{
			    USARTPut(v);
			    TCPPut(FTPSocket, v);
			}
			TCPFlush(FTPSocket);
			FTPResponse = FTP_RESP_NONE;
			smFTP = SM_FTP_CONNECTED;
		}
        // No break - this will speed up little bit

    case SM_FTP_CONNECTED:
        if ( FTPCommand != FTP_CMD_NONE )
        {
            if ( ExecuteFTPCommand(FTPCommand) )
            {
                if ( FTPResponse != FTP_RESP_NONE )
                    smFTP = SM_FTP_RESPOND;
                else if ( FTPCommand == FTP_CMD_QUIT )
                    smFTP = SM_FTP_NOT_CONNECTED;

                FTPCommand = FTP_CMD_NONE;
                smFTPCommand = SM_FTP_CMD_IDLE;
            }
            else if ( FTPResponse != FTP_RESP_NONE )
            {
                smFTP = SM_FTP_RESPOND;
                goto SM_FTP_RESPOND_Label;
            }
        }
        break;


    }

    return TRUE;
}
Example #12
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 );
}
Example #13
0
/*********************************************************************
 * Function:        void SMTP Client State machine(void)
 *
 * PreCondition:    FTPInit() must already be called.
 *
 * Input:           None
 *
 * Output:          Ready to send mail.
 *
 * Side Effects:    None
 *
 * Overview:
 *
 * Note:            This function acts as a task (similar to one in
 *                  RTOS).  This function performs its task in
 *                  co-operative manner.  Main application must call
 *                  this function repeatedly to ensure it can send
 *                  mails when requested. (include in the main loop)
 ********************************************************************/
void SMTPClient(void)
{
    BYTE v;
//    TICK currentTick;

    // check if state machine is stuck somewhere and reset the SM after a while if needed :
    if ((smSMTP != SM_SMTP_STDBY) && (TickGetDiff(TickGet(), lastActivity) > (15 * TICK_SECOND))) {
        if (TCPIsConnected(SMTPSocket))
           TCPDisconnect(SMTPSocket) ;
        if(cptretry--) {						// if not all retries done...
           lastActivity = TickGet();			// re-init delay
           smSMTP = SM_SMTP_STDBY ;   			// force standby state
        } else {
           fsend_mail = FALSE ;					// give up !
           smSMTP = SM_SMTP_STDBY ;   			// -> standby
        }
    }

    // work each state :
    switch(smSMTP)
    {
    case SM_SMTP_STDBY:		// standby: idle, waiting for connection request
        if (fsend_mail) {
           if (TickGetDiff(TickGet(), lastActivity) > (10 * TICK_SECOND)) {
      USARTPut(0xBB) ;

              lastActivity = TickGet();
              ARPResolve(&nodedist.IPAddr) ;	// resolve IP adress
              smSMTP = SM_SMTP_ARP ;   			// -> wait ARP answer
           }
        }
        break ;

    case SM_SMTP_ARP:		// wait ARP to be resolved
        if ( ARPIsResolved(&nodedist.IPAddr, &nodedist.MACAddr)) {
           SMTPSocket = TCPConnect(&nodedist, SMTP_PORT) ;
           if (SMTPSocket == INVALID_SOCKET) {
              fsend_mail = FALSE ;	       		// avorte
           } else {
              smSMTP = SM_SMTP_CONNECT ;   		// -> attente ACK
           }
        }
        break ;

    case SM_SMTP_CONNECT:		// standby: attente ack connexion
        if (TCPIsConnected(SMTPSocket)) {
           smSMTP = SM_SMTP_WELCOME ;   		// -> attente WELCOME

        }
        break ;

    case SM_SMTP_WELCOME:		// attente welcome du serveur
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket, &v)) {
              if (v == '2') {		// commence par un 2 ? (220..)
                 TCPDiscard(SMTPSocket) ;
                 ExecuteSMTPCommand(SMTP_CMD_HELO) ;
                 smSMTP = SM_SMTP_HELO ;   		// -> attente reponse au HELO
              }else {
              smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;

    case SM_SMTP_HELO:			// attente HELO du serveur
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket,&v)) {
              if (v == '2') {					// commence par un 2 ? (220..)
                 TCPDiscard(SMTPSocket) ;
                 ExecuteSMTPCommand(SMTP_CMD_FROM) ;
                 smSMTP = SM_SMTP_FROM ;   		// -> attente reponse au FROM
              }else {
                 smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;

    case SM_SMTP_FROM:			// attente HELO du serveur
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket,&v)) {
              if (v == '2') {		// commence par un 2 ? (220..)
                 TCPDiscard(SMTPSocket) ;
                 ExecuteSMTPCommand(SMTP_CMD_TO) ;
                 smSMTP = SM_SMTP_TO ;   		// -> attente reponse au TO
              }else {
                 smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;

    case SM_SMTP_TO:			// attente HELO du serveur
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket,&v)) {
              if (v == '2') {					// commence par un 2 ? (220..)
                 TCPDiscard(SMTPSocket) ;
                 ExecuteSMTPCommand(SMTP_CMD_DATA) ;
                 smSMTP = SM_SMTP_DATA1 ;  		// -> attente reponse au DATA
              }else {
                 smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;

    case SM_SMTP_DATA1:			// when OK send message headers
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket,&v)) {
              if (v == '3') {		// commence par un 3 ? (220..)
                 TCPDiscard(SMTPSocket) ;
                 ExecuteSMTPCommand(SMTP_CMD_DATA_HEADERS) ;	// send headers
//                 ExecuteSMTPCommand(SMTP_CMD_DATA_MESSAGE) ; // message
//                 ExecuteSMTPCommand(SMTP_CMD_DATA_END) ;     // termine

                 smSMTP = SM_SMTP_DATA2;   		// -> send body
              }else {
                 smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;

    case SM_SMTP_DATA2:			// wait to send message body
        if (TCPIsPutReady(SMTPSocket)) {				// wait for TX buffer free
           ExecuteSMTPCommand(SMTP_CMD_DATA_MESSAGE) ;	// message
           smSMTP = SM_SMTP_DATA3 ;   		// -> attente reponse au TO
        } else {
//           USARTPut(0xCC) ;		vérifié qu'il y avait bien besoin d'une attente ici

        }
        break ;

    case SM_SMTP_DATA3:			// wait to send the final "."
        if (TCPIsPutReady(SMTPSocket)) {				// wait for TX buffer free
           ExecuteSMTPCommand(SMTP_CMD_DATA_END) ; 		// termine
           smSMTP = SM_SMTP_QUIT ;						// -> end
        }  else {
//            USARTPut(0xDD) ;		vérifié qu'il y avait bien besoin d'une attente ici

        }
        break ;

    case SM_SMTP_QUIT:		// wait last message before leaving...
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket,&v)) {
              if (v == '2') {		// commence par un 2 ? (220..)

                 TCPDiscard(SMTPSocket) ;
                 smSMTP = SM_SMTP_DONE ;   		// -> deconnecte
              }else {
                 smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;


    case SM_SMTP_DONE:			// disconnect Socket :
        if (TCPIsConnected(SMTPSocket) && (TCPIsPutReady(SMTPSocket))) { // wait for TX buff free
           TCPDisconnect(SMTPSocket) ;
        }
        fsend_mail = FALSE ;		// done !
        smSMTP = SM_SMTP_STDBY ;   // -> standby
        break ;
    }
}
void lftp_task( void )
{	
	WORD ttt;
	BYTE c;
	BOOL bPreLine;
	BOOL bPostLine;
	
	// Nothing to do if we don't have a link
	if ( !MACIsLinked() ) return;
	
	// check if state machine is stuck somewhere and reset the it after a while if needed :
    if ( ( ftp_state != LFTP_STATE_NONE ) && 
	    	( TickGetDiff( TickGet(), lastActivity) > ( LFTP_TIMEOUT * TICK_SECOND ) ) ) {
		
		// Close ftp client socker if open
		//if ( TCPIsConnected( ftpsocket ) ) {
        	writeRomString2Socket( quit );
        	TCPDisconnect( ftpsocket );
        	ftpsocket = UNKNOWN_SOCKET;
        //}
        
        // Close data socket if open
        TCPDisconnect( datasocket );
        datasocket = UNKNOWN_SOCKET;
		
		// Check if we should try again or if its time
		// to pack it in
        cntBeforeFail++;
        if ( cntBeforeFail > LFTP_MAX_RETRIES ) {
	    	
	    	cntBeforeFail = 0;
	    	ftp_state = LFTP_STATE_NONE;		// Give up...
	    	bftpLoadWork = FALSE;	// Work is done - failed
	    	
	    }
 
        ftp_state = LFTP_STATE_NONE;
    }
		
		
		
	switch( ftp_state ) {
	
		// **
		// Start to work if its time to do so
		
		case LFTP_STATE_NONE:
		
			// Check timer and see if we should fetch
			// data from the server.
			lastActivity = TickGet();
			
			if ( bftpLoadWork ) {
				ftp_state = LFTP_STATE_ARP;	// Must get MAC address for server
				cntBeforeFail = 0;			// Init. failure counter
				DBG_OUT('A');
			}
			break;
			
			
		//**
		// Resolve the MAC address of the ftp server
			
		case LFTP_STATE_ARP:
			
			ftp_nodeinfo.IPAddr.v[ 0 ] = LFTP_SERVER_IP_v0;
			ftp_nodeinfo.IPAddr.v[ 1 ] = LFTP_SERVER_IP_v1;
			ftp_nodeinfo.IPAddr.v[ 2 ] = LFTP_SERVER_IP_v2;
			ftp_nodeinfo.IPAddr.v[ 3 ] = LFTP_SERVER_IP_v3;
			
			if ( ARPIsTxReady() ) {	
				DBG_OUT('B');
				ARPResolve( &ftp_nodeinfo.IPAddr );	// resolve IP adress
				ftp_state = LFTP_STATE_ARP_RESOLVE;
				lastActivity = TickGet();
			}
			break;	
		
			
		// **
		// Check if the ftp MAC address is resolved
			
		case LFTP_STATE_ARP_RESOLVE:	
			if ( ARPIsResolved( &ftp_nodeinfo.IPAddr, &ftp_nodeinfo.MACAddr ) ) {
				DBG_OUT('D');
				ftp_state = LFTP_STATE_CONNECT;
				lastActivity = TickGet();	
			}
			break;			
			
			
			
		// **
		// Connect to ftp server
			
		case LFTP_STATE_CONNECT:				
			
			// Try to connect				
			ftpsocket = TCPConnect( &ftp_nodeinfo, LFTP_PORT );
			if ( INVALID_SOCKET != ftpsocket ) {
				DBG_OUT('E');
				ftp_state = LFTP_STATE_CONNECT_WAIT;
				lastActivity = TickGet();
			}
			break;
		
			
		// **
		// Waiting for ftp connection
		
		case LFTP_STATE_CONNECT_WAIT:
		
			if ( TCPIsConnected( ftpsocket ) ) {
				DBG_OUT('F');
				ftp_state = LFTP_STATE_USER;
				lastActivity = TickGet();	
			}
			break;
				
							
							
		// Here we wait for server connection and send
		// USER command if OK	
		case LFTP_STATE_USER:

			// Fetch data if we are connected
			if ( TCPIsGetReady( ftpsocket ) ) {
					
				// get first digit
				while( TCPGet( ftpsocket, &c ) ) {
					if ( isdigit( c ) ) break;
				}
					
				// If connected with positive response "2xx - xxxxxxxx..."
				// we send username. If not we just timeout
				if ( '2' == c ) {
					DBG_OUT('G');
					writeRomString2Socket( user );
					ftp_state = LFTP_STATE_PASS;
					lastActivity = TickGet();
				}
					
				TCPDiscard( ftpsocket );
				 	
			}
			break;	
			
			
			
			// **
			// Here we wait for response from USER command
			// and send PASS command if OK
			
			case LFTP_STATE_PASS:
				
			// Fetch data if we are connected
			if ( TCPIsGetReady( ftpsocket ) ) {
				
				DBG_OUT('$');
					
				// get first digit
				while( TCPGet( ftpsocket, &c ) ) {
					DBG_OUT(c);
					if ( isdigit( c ) ) break;
				}
					
				// If connected with positive response "3xx - xxxxxxxx..."
				// we send username. If not we just timeout
				if ( ('3' == c ) || ('2' == c ) ) {
					DBG_OUT('H');
					writeRomString2Socket( pass );
					ftp_state = LFTP_STATE_PASV;	
					lastActivity = TickGet();
				}
					
				TCPDiscard( ftpsocket );
						
			}
			break;
			
			
			
			// **
			// Here we wait for response of PASS command
			// and send PASV command if positive and also
			// creates the data socket
			
			case LFTP_STATE_PASV:
		 
			// Fetch data if we are connected
			if ( TCPIsGetReady( ftpsocket ) ) {
				
				DBG_OUT('!');					
				
				// get first digit
				while( TCPGet( ftpsocket, &c ) ) {
					DBG_OUT(c);
					if ( isdigit( c ) ) break;
				}
					
				// If connected with positive response "2xx - xxxxxxxx..."
				// we send username. If not we just timeout
				if ( '2' == c ) {
					DBG_OUT('I');	
						
					writeRomString2Socket( pasv );
					ftp_state = LFTP_STATE_RETR;
					lastActivity = TickGet();
							
				}
					
				TCPDiscard( ftpsocket );	
				 	
			}
			break;
			
			
			// **
			// Here we wait for the result of PASV command
			// and parse its data
			// if OK we send RETR and go on to the next state
			
			case LFTP_STATE_RETR:
	 				
				// Fetch data if we are connected
				if ( TCPIsGetReady( ftpsocket ) ) {
					
					TCPGet( ftpsocket, &c );
					
					if ( '2' == c ) {
						
						DBG_OUT('J');
						
						// Get pasv parameters
						getPasvParams();
						
						// retrive file
						writeRomString2Socket( retr );
						
						ttt = portdata;
						while ( ttt ) {
							DBG_OUT('0' + (ttt % 10) );
							ttt = ttt / 10;
						} 
						
						ftp_state = LFTP_STATE_DATA_CONNECT;		
					}
					
					TCPDiscard( ftpsocket );					
				}
			break;
		
		
			// **
			// Connect to the data socket
		
			case LFTP_STATE_DATA_CONNECT:
			
				// Try to connect				
				datasocket = TCPConnect( &ftp_nodeinfo, portdata );
				if ( INVALID_SOCKET != datasocket ) {
					DBG_OUT('K');
					ftp_state = LFTP_STATE_WAIT_DATA_CONNECT; 
					lastActivity = TickGet();
				}
			break;
			
			
			// **
			// Wait for the data connection to establish
			
			case LFTP_STATE_WAIT_DATA_CONNECT:
			
				if ( TCPIsConnected( datasocket ) ) {
					DBG_OUT('L');
					//writeRomString2Socket( lftpDataSocket, crlf );
					ftp_state = LFTP_STATE_FETCH_DATA;
					lastActivity = TickGet();
				}
				
				// Check for reply on ftp socket FIX!!!!
				if ( TCPIsGetReady( ftpsocket ) ) {	
					DBG_OUT('?');
					while( TCPGet( ftpsocket, &c ) ) {
						DBG_OUT( c );
					}
					TCPDiscard( ftpsocket );
				}
			break;
		
			
			
			// **
			// Fetch the data and send it out on the
			// serial i/f
			
			case LFTP_STATE_FETCH_DATA:
 
				// Fetch data if we are connected
				if ( TCPIsGetReady( datasocket ) ) {	
					DBG_OUT('M');
					
					// Framework start
					serPutByte( 0x00  );
					serPutByte( 0xff  );
					serPutByte( 0xff  );
					serPutByte( 0x01  );
					serPutByte( 0x01  );
					serPutByte( 0x01  );
					
					bPreLine = FALSE;
					bPostLine = FALSE;
					
					// get data
					while( TCPGet( datasocket, &c ) ) {
						
						if ( 0x0d == c ) {
							// We skip CR
						}
						else if ( 0x0a == c ) {
							// Send end line stuff
							serPutByte( 0xff );
							bPreLine = FALSE;
							bPostLine = TRUE;
						}
						else {
							bPostLine = FALSE;	// no end line codes sent
							if ( !bPreLine ) {
								// Send preline stuff
								bPreLine = TRUE;
								serPutByte( 0x01 );
								serPutByte( 0x03 );
								serPutByte( 0xef );
								serPutByte( 0xb0 );
							}
							serPutByte( c );
						}
					}
					
					// If we end with a row without LF we must send
					// Line end stuff
					if ( !bPostLine ) {
						serPutByte( 0xff );
					}
					
					// Framework end
					serPutByte( 0xff  );
					serPutByte( 0x00  );
					
					ftp_state = LFTP_STATE_END;
					TCPDiscard( datasocket );	
				}
				
				
				// Check for data on ftp socket
				if ( TCPIsGetReady( ftpsocket ) ) {	
					
					while( TCPGet( ftpsocket, &c ) ) {
						DBG_OUT( c );
					}
					TCPDiscard( ftpsocket );
				}
				
			break;
				
				
				
			// **
			// We are done for this time
				
			case LFTP_STATE_END:
				DBG_OUT('*');
				TCPDisconnect( ftpsocket );
				TCPDisconnect( datasocket );
				bftpLoadWork = FALSE;	// Work is done
				ftp_state = LFTP_STATE_NONE;
			break;
	}	
}
/*********************************************************************
 * Function:        void UART2TCPBridgeTask(void)
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void UART2TCPBridgeTask2(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;
	unsigned char buffer[PACK_MAX_RX_SIZE];
	DATA_RX_PACKET_T * prx;
	DATA_TX_PACKET_T * ptx;

	switch(BridgeState)
	{
	default:
		case SM_HOME:

			putrsUART((ROM char*)"\r\n IN UART2TCPBridgeTask() 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, UART1TCPBRIDGE_PORT, TCP_PURPOSE_UART_2_TCP_BRIDGE);
			#else
				MySocket = TCPOpen(0, TCP_OPEN_SERVER, UART1TCPBRIDGE_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:

			//RELAY_OUT_1 = 0;

			// 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))
			{	
				LED7_IO = 0;
				break;
			}
			
			LED7_IO = 1;

			// Make sure to clear UART errors so they don't block all future operations

			if(OERR2) //RCSTAbits.OERR)
			{
				//RCSTAbits.CREN = 0;
				CREN2 = 0;
				//RCSTAbits.CREN = 1;
				CREN2 = 1;
				LED1_IO ^= 1;
			}
			if(FERR2) //RCSTAbits.FERR)
			{
				BYTE dummy = RCREG2; //RCREG;
				LED2_IO ^= 1;
			}



			prx =  GetFinishedPacket();
			if(prx != NULL) {
				if(prx->finished) {
					if(prx->index > 0) {
						wMaxPut = TCPIsPutReady(MySocket);	// Get TCP TX FIFO space
						wMaxPut = (prx->index > wMaxPut)?wMaxPut:prx->index;
						if(wMaxPut > 0) {
							TCPPutArray(MySocket, &(prx->buffer[0]), wMaxPut);
							prx->index = 0;
							prx->finished = 0;
							TCPFlush(MySocket);
						}
					}
					prx->index = 0;
					prx->finished = 0;  //测试用
					//if(THISINFO)putrsUART((ROM char *)"\r\UART Bridge look at it");
				}
			}
			//PIE1bits.RCIE = 1;
			RC2IE = 1;



			wMaxGet = TCPIsGetReady(MySocket);	// Get TCP RX FIFO byte count
			if(wMaxGet > 0) {
				DATA_TX_PACKET_T * ptx = find_next_empty_tx_buffer();
				if(ptx != NULL) {
					wMaxGet = (wMaxGet > PACK_MAX_RX_SIZE)?PACK_MAX_RX_SIZE:wMaxGet;
				    TCPGetArray(MySocket,(BYTE *)&buffer[0],wMaxGet);
				    ptx = prase_in_buffer(buffer,wMaxGet);
				    if(ptx != NULL) {
					    if(ptx->index > 0) {
						    //启动发送
						    //PIE1bits.TXIE = 1;
							TX2IE = 1;
					    }
				    }
				}
			} else {
				TCPDiscard(MySocket);
			}
			break;
	}
}
/// @cond debug
//****************************************************************************
//	TCPRxFlush callback function
//****************************************************************************
int cTCPRxFlush()
{
	TCPDiscard(xSocket);
	return 0;
}	
Example #17
0
/*
 * Main entry point.
 */
void main(void)
{
    static TICK8 t = 0;

#ifdef	HEATHERD
	NODE_INFO tcpServerNode;
	static TCP_SOCKET tcpSocketUser = INVALID_SOCKET;
	BYTE c;
#endif

    static BYTE testLED;
    testLED = 1;

    //Set SWDTEN bit, this will enable the watch dog timer
    WDTCON_SWDTEN = 1;
    aliveCntrMain = 0xff;   //Disable alive counter during initialization. Setting to 0xff disables it.

    //Initialize any application specific hardware.
    InitializeBoard();

    //Initialize all stack related components. Following steps must
    //be performed for all applications using PICmicro TCP/IP Stack.
    TickInit();    

    //Initialize buses
    busInit();

    //Initialize serial ports early, because they could be required for debugging
    if (appcfgGetc(APPCFG_USART1_CFG & APPCFG_USART_ENABLE)) {
        appcfgUSART();              //Configure the USART1
    }

    if (appcfgGetc(APPCFG_USART2_CFG & APPCFG_USART_ENABLE)) {
        appcfgUSART2();             //Configure the USART2
    }

    //After initializing all modules that use interrupts, enable global interrupts
    INTCON_GIEH = 1;
    INTCON_GIEL = 1;

    //Initialize file system.
    fsysInit();

    //Intialize HTTP Execution unit
    htpexecInit();

    //Initialize Stack and application related NV variables.
    appcfgInit();

    //First call appcfgCpuIOValues() and then only appcfgCpuIO()!!! This ensures the value are set, before enabling ports.
    appcfgCpuIOValues();    //Configure the CPU's I/O port pin default values
    appcfgCpuIO();          //Configure the CPU's I/O port pin directions - input or output
    
    appcfgADC();            //Configure ADC unit
    appcfgPWM();            //Configure PWM Channels

    //Serial configuration menu - display it for configured time and allow user to enter configuration menu
    scfInit(appcfgGetc(APPCFG_STARTUP_SER_DLY));
    
    //LCD Display Initialize
    lcdInit();

    //Initialize expansion board
    appcfgXboard();

    StackInit();

#if defined(STACK_USE_HTTP_SERVER)
    HTTPInit();
#endif

#if defined(STACK_USE_FTP_SERVER)
    FTPInit();
#endif

    //Intialise network componet of buses - only call after StackInit()!
    busNetInit();

    //Initializes events.
    evtInit();

    //Initializes "UDP Command Port" and "UDP Even Port".
    cmdInit();

    ioInit();

    #if (DEBUG_MAIN >= LOG_DEBUG)
        debugPutMsg(1); //@mxd:1:Starting main loop
    #endif

    /*
     * Once all items are initialized, go into infinite loop and let
     * stack items execute their tasks.
     * If application needs to perform its own task, it should be
     * done at the end of while loop.
     * Note that this is a "co-operative mult-tasking" mechanism
     * where every task performs its tasks (whether all in one shot
     * or part of it) and returns so that other tasks can do their
     * job.
     * If a task needs very long time to do its job, it must broken
     * down into smaller pieces so that other tasks can have CPU time.
     */

#ifdef HEATHERD
    //Create a TCP socket that listens on port 54123
    tcpSocketUser = TCPListen(HEATHERD);

#define HEATHERD_ENABLE (!(appcfgGetc(APPCFG_TRISA) & 1))
#define HEATHERD_WRITE_ENABLE (!(appcfgGetc(APPCFG_TRISA) & 2))

#endif
    
    while(1)
    {
        aliveCntrMain = 38;     //Reset if not services in 52.42ms x 38 = 2 seconds

        //Blink SYSTEM LED every second.
        if (appcfgGetc(APPCFG_SYSFLAGS) & APPCFG_SYSFLAGS_BLINKB6) {
            //Configure RB6 as output, and blink it every 500ms
            if ( TickGetDiff8bit(t) >= ((TICK8)TICKS_PER_SECOND / (TICK8)2) )
            {
                t = TickGet8bit();
                
                //If B6 is configured as input, change to output
                if (appcfgGetc(APPCFG_TRISB) & 0x40) {
                    appcfgPutc(APPCFG_TRISB, appcfgGetc(APPCFG_TRISB) & 0b10111111);
                }
          
                TRISB_RB6 = 0;
                LATB6 ^= 1;     //Toggle
                
                //Toggle IOR5E LED, if IOR5E is present
                if (appcfgGetc(APPCFG_XBRD_TYPE) == XBRD_TYPE_IOR5E) {
                    ior5eLatchData.bits.ledPWR ^= 1;    // Toggle
                }
            }
        }

        //This task performs normal stack task including checking for incoming packet,
        //type of packet and calling appropriate stack entity to process it.
        StackTask();

        //Service LCD display
        lcdService();
        
        //Process commands
        cmdTask();
        
        //Process events
        evtTask();

        //Process serial busses
        busTask();

        //I2C Task
        i2cTask();


#ifdef HEATHERD
        //Has a remote node made connection with the port we are listening on
        if ((tcpSocketUser != INVALID_SOCKET) && TCPIsConnected(tcpSocketUser)) {
    		if (HEATHERD_ENABLE) {
	
	            //Is there any data waiting for us on the TCP socket?
	            //Because of the design of the Modtronix TCP/IP stack we have to
	            //consume all data sent to us as soon as we detect it.
	            while(TCPIsGetReady(tcpSocketUser)) {
	                //We are only interrested in the first byte of the message.
	                TCPGet(tcpSocketUser, &c);
					if (HEATHERD_WRITE_ENABLE) serPutByte(c);
	            }
	            //Discard the socket buffer.
	            TCPDiscard(tcpSocketUser);
			    while (serIsGetReady() && TCPIsPutReady(tcpSocketUser)) {
					TCPPut(tcpSocketUser,serGetByte());
				}
				TCPFlush(tcpSocketUser);
	        } else {
				TCPDisconnect(tcpSocketUser);
			}
		}
#endif

#if defined(STACK_USE_HTTP_SERVER)
        //This is a TCP application.  It listens to TCP port 80
        //with one or more sockets and responds to remote requests.
        HTTPServer();
#endif

#if defined(STACK_USE_FTP_SERVER)
        FTPServer();
#endif

#if defined(STACK_USE_ANNOUNCE)
        DiscoveryTask();
#endif

#if defined(STACK_USE_NBNS)
        NBNSTask();
#endif

        //Add your application speicifc tasks here.
        ProcessIO();

        //For DHCP information, display how many times we have renewed the IP
        //configuration since last reset.
        if ( DHCPBindCount != myDHCPBindCount )
        {
            #if (DEBUG_MAIN >= LOG_INFO)
                debugPutMsg(2); //@mxd:2:DHCP Bind Count = %D
                debugPutByteHex(DHCPBindCount);
            #endif
            
            //Display new IP address
            #if (DEBUG_MAIN >= LOG_INFO)
                debugPutMsg(3); //@mxd:3:DHCP complete, IP = %D.%D.%D.%D
                debugPutByteHex(AppConfig.MyIPAddr.v[0]);
                debugPutByteHex(AppConfig.MyIPAddr.v[1]);
                debugPutByteHex(AppConfig.MyIPAddr.v[2]);
                debugPutByteHex(AppConfig.MyIPAddr.v[3]);
            #endif
            myDHCPBindCount = DHCPBindCount;
            
            #if defined(STACK_USE_ANNOUNCE)
                AnnounceIP();
            #endif             
        }
    }
}
/***	void TCPSocket::discardReadBuffer(void)
**
**	Synopsis:   
**      Empties (flushes) the input (read) buffer.
**      All bytes are discarded.
**
**	Parameters:
**      None
**
**	Return Values:
**      None
**
**	Errors:
**      None
**
**  Notes:
**
**      This call is safe to make without checking the connection status.
**
*/
void TCPSocket::discardReadBuffer(void)
{
    TCPDiscard(&_socket);
}
Example #19
0
File: HTTP.c Project: sonite/mGit
/*********************************************************************
 * Serve a single connection
 ********************************************************************/
static void HTTP_Process(BOOL available)
{
    BYTE error;
	const struct HTTP_FileContent rom *content;

retry:
	switch(HTTP.StateMachine)
	{
	// Introduced explicit disconnect state handling in order to properly
	// finish all queries
	case SM_HTTP_IDLE:
		// Connections closed for any reason will automatically end up in
		// the disconnected state, so this is a good place to make sure
		// we don't leak files.
		if(HTTP.file)
		{
			FSfclose(HTTP.file);
			HTTP.file = NULL;
		}

		// Just wait for any connection to be made
		if(!TCPIsConnected(HTTP.socket))
			// Don't break for new connections.  There may be 
 			// an entire request in the buffer already.
			return;
		
		HTTP.StateMachine = SM_HTTP_PARSE_REQUEST;
		
		// Adjust the TCP FIFOs for optimal reception of 
		// the next HTTP request from the browser
		///while(!TCPAdjustFIFOSize(HTTP.socket, 1, 0, TCP_ADJUST_PRESERVE_RX | TCP_ADJUST_GIVE_REST_TO_RX));
		// Fallthrough
		// .
		// .
		// .
	case SM_HTTP_PARSE_REQUEST:
		// Verify the entire first line is in the FIFO and
		if(!HTTP_SetBuf(-1))
			break;

		// Check that the file system is mounted
		error = HTTP_ERR_NOT_AVAILABLE;

		if(available)
		{
			// Parse the request line
			error = HTTP_ERR_NOT_IMPLEMENTED;
			// Parses the first line for a file name and GET args 
			if(HTTP_Parse())
			{				
				static char read[] = FS_READ;
				
				error = HTTP_ERR_NOT_FOUND;
				// Open the file
				if(HTTP.file = FSfopen(HTTP_ParseName, read), HTTP.file)
					// Success!
					goto retry;
			}
		}

		HTTP.FileType = error;
		HTTP.StateMachine = SM_HTTP_ERROR;

		// Fallthrough
		// .
		// .
		// .
	case SM_HTTP_ERROR:
		if(TCPIsPutReady(HTTP.socket) >= strlenpgm((const char far rom *) HTTP_Errors[HTTP.FileType]))
		{
			TCPPutROMString(HTTP.socket, (ROM BYTE *) HTTP_Errors[HTTP.FileType]);
			TCPFlush(HTTP.socket);
			TCPDisconnect(HTTP.socket);
			HTTP.StateMachine = SM_HTTP_IDLE;
		}
		break;

	// Parse out the POST header lines
	case SM_HTTP_POST_HEADER:
		// Is the next line ready yet?
		while(HTTP_SetBuf(-1))
		{
			char ch;

			// Isolate the field name
			HTTP_Buffer.write = HTTP_Data;

			do
			{
				ch = HTTP_GetBuf();

				// The payload starts after the first empty line
				if(ch == '\0')
				{
					HTTP.StateMachine = SM_HTTP_POST_ARGUMENTS;
					goto retry;
				}

				HTTP_PutBuf(ch);
			}
			while(ch != ' ');

			HTTP_PutBuf('\0');

			// The content length is needed to know the length of the variable block
			if(!Cfg_StringCompare(HTTP_Data, (const char ROM *) HTTP_CONTENT_LENGTH_STRING))
			{
				unsigned int len = 0;

				while(ch = HTTP_GetBuf() - '0', (unsigned char) ch <= 9)
				{
					len *= 10;
					len += ch;
				}

				HTTP.length = len;
			}
		}
		break;

	case SM_HTTP_POST_ARGUMENTS:
		if(!HTTP_SetBuf(HTTP.length))
			break;

		if(HTTP_ParseAttribs())
		{
			Microchip_RefreshSettings();
			Microchip_RestoreSPI();
		};

		HTTP.StateMachine = SM_HTTP_PARSE_HEADERS;

		// Fallthrough
		// .
		// .
		// .
	case SM_HTTP_PARSE_HEADERS:
		content = &HTTP_FileContent[HTTP.FileType];
		
		// Write response string
		TCPPutROMString(HTTP.socket, HTTP_OK_STRING);
		TCPPutROMString(HTTP.socket, (ROM BYTE *) content->mime);

		// Generic cache control mechanism
		TCPPutROMString(HTTP.socket, content->cache ? HTTP_NL_DO_CACHE_STRING : HTTP_NL_NO_CACHE_STRING);

		//  Generate the content-length field so that dismount errors can be detected
		HTTP.dynamic = content->dynamic;

		if(!HTTP.dynamic)
		{
			Numeric(Num_Buffer, HTTP.file->size);
			TCPPutROMString(HTTP.socket, HTTP_NL_CONTENT_LENGTH_STRING);
			TCPPutString(HTTP.socket, (BYTE *) Num_Buffer);
		}

		TCPPutROMString(HTTP.socket, HTTP_NL_HEADER_END_STRING);

		HTTP.StateMachine = SM_HTTP_PROCESS_GET;

		// Fallthrough
		// .
		// .
		// .
	case SM_HTTP_PROCESS_GET:
		// Throw away any more data receieved - we aren't going to use it.
		TCPDiscard(HTTP.socket);

		if(HTTP_SendFile())
		{
			TCPFlush(HTTP.socket);
			TCPDisconnect(HTTP.socket);
			HTTP.StateMachine = SM_HTTP_IDLE;
		}
		break;
	}

	// Flush out any remaining line-buffered data
	HTTP_FlushBuf();

	// If, during handling of HTTP socket, it gets disconnected then forget
	// about any previous processing and return to the idle state.
	//
	// Do wait until as much processing as possible has been completed on
	// whatever data remains in the buffers however
	if(!TCPIsConnected(HTTP.socket))
		HTTP.StateMachine = SM_HTTP_IDLE;
}