Ejemplo n.º 1
0
/*********************************************************************
 * Function:        void TelnetTask(void)
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Performs Telnet Server related tasks.  Contains
 *                  the Telnet state machine and state tracking
 *                  variables.
 *
 * Note:            None
 ********************************************************************/
void TelnetTask(void)
{
    uint8_t         i;
    uint8_t     vTelnetSession;
    uint16_t        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 uint8_t vTelnetStates[MAX_TELNET_CONNECTIONS];
    static bool bInitialized = false;

    // Perform one time initialization on power up
    if((!bInitialized)||(AppConfig.hibernateFlag))
    {
        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 tcpip_config.h
                if(MySocket == INVALID_SOCKET)
                    break;

                // Open an SSL listener if SSL server support is enabled
                #if defined(STACK_USE_SSL_SERVER)
                    TCPAddSSLListener(MySocket, TELNETS_PORT);
                #endif

                TelnetState++;
                break;

            case SM_PRINT_LOGIN:
                #if defined(STACK_USE_SSL_SERVER)
                    // Reject unsecured connections if TELNET_REJECT_UNSECURED is defined
                    #if defined(TELNET_REJECT_UNSECURED)
                        if(!TCPIsSSL(MySocket))
                        {
                            if(TCPIsConnected(MySocket))
                            {
                                TCPDisconnect(MySocket);
                                TCPDisconnect(MySocket);
                                break;
                            }
                        }
                    #endif

                    // Don't attempt to transmit anything if we are still handshaking.
                    if(TCPSSLIsHandshaking(MySocket))
                        break;
                #endif

                // 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 uint8_t*)"\r\nToo much data.\r\n");
                        TCPDisconnect(MySocket);
                    }

                    break;
                }

                // Search for the username -- case insensitive
                w2 = TCPFindROMArray(MySocket, (ROM uint8_t*)TELNET_USERNAME, sizeof(TELNET_USERNAME)-1, 0, true);
                if( !((sizeof(TELNET_USERNAME)-1 == w - w2) || (sizeof(TELNET_USERNAME) == w - w2)))
                {
                    // 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 uint8_t*)"Too much data.\r\n");
                        TCPDisconnect(MySocket);
                    }

                    break;
                }

                // Search for the password -- case sensitive
                w2 = TCPFindROMArray(MySocket, (ROM uint8_t*)TELNET_PASSWORD, sizeof(TELNET_PASSWORD)-1, 0, false);
                if(!((sizeof(TELNET_PASSWORD) == w - w2) || (sizeof(TELNET_PASSWORD) - 1 == w - w2))
                    || (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 uint8_t*)"\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 uint32_t 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 uint32_t dwTime;
                        uint8_t vTime[11];

                        if(dwTime != SNTPGetUTCSeconds())
                        {

                            // Position cursor at Line 10, Col 15
                            TCPPutROMString(MySocket, (ROM uint8_t*)"\x1b[10;15f");
                            dwTime = SNTPGetUTCSeconds();
                            ultoa(dwTime, vTime);
                            TCPPutROMArray(MySocket, (ROM uint8_t*)strSpaces, 10-strlen((char*)vTime));
                            TCPPutString(MySocket, vTime);
                        }
                    }
                    #endif

                    // Position cursor at Line 11, Col 21
                    TCPPutROMString(MySocket, (ROM uint8_t*)"\x1b[11;21f");

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

                    // Put Buttons
                    TCPPutROMString(MySocket, (ROM uint8_t*)"\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 uint8_t*)"\x1b[13;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 uint8_t*)"\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;
    }
}
Ejemplo n.º 2
0
void TelnetTask(void)
{
	BYTE		vTelnetSession;
	WORD		w, w2;
	TCP_SOCKET	MySocket;
	char outstr[60];


	// 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;
	
				// Open an SSL listener if SSL server support is enabled
				#if defined(STACK_USE_SSL_SERVER)
					TCPAddSSLListener(MySocket, TELNETS_PORT);
				#endif
	
				TelnetState++;
				break;
	
			case SM_PRINT_LOGIN:
				#if defined(STACK_USE_SSL_SERVER)
					// Reject unsecured connections if TELNET_REJECT_UNSECURED is defined
					#if defined(TELNET_REJECT_UNSECURED)
						if(!TCPIsSSL(MySocket))
						{
							if(TCPIsConnected(MySocket))
							{
								TCPDisconnect(MySocket);
								TCPDisconnect(MySocket);
								break;
							}	
						}
					#endif
						
					// Don't attempt to transmit anything if we are still handshaking.
					if(TCPSSLIsHandshaking(MySocket))
						break;
				#endif

				sprintf(outstr,"%s%d%s",(char *)strTitle,AppConfig.SerialNumber,(char *)strTitle1);
			
				// Make certain the socket can be written to
				if(TCPIsPutReady(MySocket) < strlen(outstr))
					break;
				
				// Place the application protocol data into the transmit buffer.
				TCPPutString(MySocket, (BYTE *)outstr);
	
				// 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 = TCPFindArray(MySocket, TELNET_USERNAME, strlen((char*)TELNET_USERNAME), 0, TRUE);
				if((w2 < 0) || !((w2 == ((w - strlen((char *)TELNET_USERNAME)) - 1)) || (w2 == (w - strlen((char *)TELNET_USERNAME)))))
				{
					// 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 = TCPFindArray(MySocket, TELNET_PASSWORD, strlen((char *)TELNET_PASSWORD), 0, FALSE);

				if((w2 != 3u) || !(((strlen((char *)TELNET_PASSWORD) == w-4)) || ((strlen((char *)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);
				TCPFlush(MySocket);
				TelnetState = SM_AUTHENTICATED;
				// No break
		
			case SM_AUTHENTICATED:
				break;
		}
		// Save session state back into the static array
		hTelnetSockets[vTelnetSession] = MySocket;
		vTelnetStates[vTelnetSession] = TelnetState;
	}
}