?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{FILE START}

library

?curdirlinks? - Rev 32

?prevdifflink? - Blame - ?getfile?

/*********************************************************************
 *
 *      Telnet Server
 *  Module for Microchip TCP/IP Stack
 *       -Provides Telnet services on TCP port 23
 *       -Reference: RFC 854
 *
 *********************************************************************
 * FileName:        Telnet.c
 * Dependencies:    TCP
 * Processor:       PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32
 * Compiler:        Microchip C32 v1.05 or higher
 *                                      Microchip C30 v3.12 or higher
 *                                      Microchip C18 v3.30 or higher
 *                                      HI-TECH PICC-18 PRO 9.63PL2 or higher
 * Company:         Microchip Technology, Inc.
 *
 * Software License Agreement
 *
 * Copyright (C) 2002-2009 Microchip Technology Inc.  All rights
 * reserved.
 *
 * Microchip licenses to you the right to use, modify, copy, and
 * distribute:
 * (i)  the Software when embedded on a Microchip microcontroller or
 *      digital signal controller product ("Device") which is
 *      integrated into Licensee's product; or
 * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h,
 *              ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device
 *              used in conjunction with a Microchip ethernet controller for
 *              the sole purpose of interfacing with the ethernet controller.
 *
 * You should refer to the license agreement accompanying this
 * Software for additional information regarding your rights and
 * obligations.
 *
 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
 *
 *
 * Author               Date    Comment
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Howard Schlunder     9/12/06 Original
 ********************************************************************/
#define __TELNET_C

#include "TCPIPConfig.h"

#if defined(STACK_USE_TELNET_SERVER)

#include "TCPIP Stack/TCPIP.h"

// Set up configuration parameter defaults if not overridden in 
// TCPIPConfig.h
#if !defined(TELNET_PORT)
    // Unsecured Telnet port
        #define TELNET_PORT                     23
#endif
#if !defined(TELNETS_PORT)      
    // SSL Secured Telnet port (ignored if STACK_USE_SSL_SERVER is undefined)
        #define TELNETS_PORT            992     
#endif
#if !defined(MAX_TELNET_CONNECTIONS)
    // Maximum number of Telnet connections
        #define MAX_TELNET_CONNECTIONS  (3u)
#endif
#if !defined(TELNET_USERNAME)
    // Default Telnet user name
        #define TELNET_USERNAME         "admin"
#endif
#if !defined(TELNET_PASSWORD)
    // Default Telnet password
        #define TELNET_PASSWORD         "microchip"
#endif

// Demo title string
static ROM BYTE strTitle[]                      = "\x1b[2J\x1b[31m\x1b[1m"      // 2J is clear screen, 31m is red, 1m is bold
                                                                          "Microchip Telnet Server 1.1\x1b[0m\r\n"      // 0m is clear all attributes
                                                                          "(for this demo, type 'admin' for the login and 'microchip' for the password.)\r\n"
                                                                          "Login: ";
// Demo password
static ROM BYTE strPassword[]           = "Password: \xff\xfd\x2d";     // DO Suppress Local Echo (stop telnet client from printing typed characters)
// Access denied message
static ROM BYTE strAccessDenied[]       = "\r\nAccess denied\r\n\r\n";
// Successful authentication message
static ROM BYTE strAuthenticated[]      = "\r\nLogged in successfully\r\n\r\n"
                                                                          "\r\nPress 'q' to quit\r\n";
// Demo output string
static ROM BYTE strDisplay[]            = "\r\nSNTP Time:    (disabled)"
                                                                          "\r\nAnalog:             1023"
                                                                          "\r\nButtons:         3 2 1 0"
                                                                          "\r\nLEDs:    7 6 5 4 3 2 1 0";
// String with extra spaces, for Demo
static ROM BYTE strSpaces[]                     = "          ";
// Demo disconnection message
static ROM BYTE strGoodBye[]            = "\r\n\r\nGoodbye!\r\n";

extern BYTE AN0String[8];

/*********************************************************************
 * 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)
{
        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;
        
                                // 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 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, 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[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;
        }
}

#endif  //#if defined(STACK_USE_TELNET_SERVER)
{FILE END}
{FOOTER START}

Powered by WebSVN v2.8.3