⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cli_telnet.c

📁 命令行在嵌入式系统的实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/************************************************************************
Copyright 200X - 200X+1.

filename     : Cli_Telnet.c

description  : Telnet主文件

author       : Woodhead

modification : Woodhead    create              2004-12-07
************************************************************************/

#include "Ros.h"
#include "CLI_Private.inc"
#include "..\include\Cli_Io.h"
#include "Cli_telnet.inc"

#if CLI_DEBUG_ON
_BOOL   m_bCliTelnetDebugOn     = G_TRUE;
#else
_BOOL   m_bCliTelnetDebugOn     = G_FALSE;
#endif

/*------------------------------------------------------------------*/
/* Telnet FSM 状态转移表                                            */
/*------------------------------------------------------------------*/
extern _U32 CLI_CharProcess ( PTerm_Data_S, _U8 ) ;

struct Fsm_Trans_S TTStab[  ] =
{
    /*--------------------------------------------------------------*/
    /* 当前状态 输入        下一状态    对输入的处理函数            */
    /*--------------------------------------------------------------*/
    { TSDATA,   TCIAC,      TSIAC,      CLI_Noop        },
    { TSDATA,   TCANY,      TSDATA,     CLI_CharProcess },
    { TSIAC,    TCIAC,      TSDATA,     CLI_CharProcess },
    { TSIAC,    TCSB,       TSSUBNEG,   CLI_Noop        },
    { TSIAC,    TCNOP,      TSDATA,     CLI_Noop        },
    { TSIAC,    TCDM,       TSDATA,     CLI_tcdm        },
    { TSIAC,    TCWILL,     TSWOPT,     CLI_RecOpt      },
    { TSIAC,    TCWONT,     TSWOPT,     CLI_RecOpt      },
    { TSIAC,    TCDO,       TSDOPT,     CLI_RecOpt      },
    { TSIAC,    TCDONT,     TSDOPT,     CLI_RecOpt      },
    { TSIAC,    TCANY,      TSDATA,     CLI_Noop        },
    { TSSUBNEG, TCIAC,      TSSUBIAC,   CLI_SubOpt      },
    { TSSUBNEG, TCANY,      TSSUBNEG,   CLI_SubOpt      },
    { TSSUBIAC, TCSE,       TSDATA,     CLI_SubEnd      },
    { TSSUBIAC, TCANY,      TSSUBNEG,   CLI_SubOpt      },
    { TSWOPT,   TOTERMTYPE, TSDATA,     CLI_DoTermType  },
    { TSWOPT,   TOTXBINARY, TSDATA,     CLI_DoTxBinary  },
    { TSWOPT,   TCANY,      TSDATA,     CLI_DoNotSup    },
    { TSDOPT,   TOECHO,     TSDATA,     CLI_WillEcho    },
    { TSDOPT,   TONOGA,     TSDATA,     CLI_WillNoga    },
    { TSDOPT,   TOTXBINARY, TSDATA,     CLI_WillTxBinary},
    { TSDOPT,   TCANY,      TSDATA,     CLI_WillNotSup  },
    { FSINVALID,TCANY,      FSINVALID,  CLI_Abort       }
} ;


/*------------------------------------------------------------------*/
/* telnet FSM                                                       */
/*------------------------------------------------------------------*/
_U8 TTFsm[ NTSTATES ][ NCHRS ] ;


/*------------------------------------------------------------------*/
/* Telnet选项子协商FSM状态转换表                                    */
/*------------------------------------------------------------------*/
struct Fsm_Trans_S SubStab[ ] =
{
    /*--------------------------------------------------------------*/
    /* 当前状态     输入       下一状态        对输入的处理函数     */
    /*--------------------------------------------------------------*/
    { SS_START,     TOTERMTYPE, SS_TERMTYPE,    CLI_Noop        },
    { SS_START,     TCANY,      SS_END,         CLI_Noop        },

    { SS_TERMTYPE,  TT_IS,      SS_IS,          CLI_Noop        },
    { SS_TERMTYPE,  TCANY,      SS_END,         CLI_Noop        },

    { SS_IS,        TCIAC,      SS_END,         CLI_SubTermType },
    { SS_IS,        TCANY,      SS_IS,          CLI_SubTermType },

    { SS_END,       TCANY,      SS_END,         CLI_Noop        },
    { FSINVALID,    TCANY,      FSINVALID,      CLI_Abort       }
} ;

/*------------------------------------------------------------------*/
/* telnet 选项子协商 FSM                                            */
/*------------------------------------------------------------------*/
_U8 SubFsm[ NSSTATES ][ NCHRS ] ;

_S8 szInputChar[ 10 ] ;

/*==================================================================*/
/*      函数名      :CLI_NegotiateOption                            */
/*      函数功能    :协商telnet选项                                 */
/*      输入参数    :PTerm_Data_S pTermStruct 任务数据              */
/*      输出参数    :PTerm_Data_S pTermStruct 任务数据              */
/*      返回值      :无                                             */
/*      调用函数    :CLI_SendToTerm ( )                           */
/*      被调函数    :                                               */
/*==================================================================*/

_VOID CLI_NegotiateOption ( PTerm_Data_S pTermStruct )
{
    if(pTermStruct == G_NULL)
    {
        return;
    }
    /*--------------------------------------------------------------*/
    /* 为简单方便, telnet server 仅与telnet client协商以下三个选项: */
    /*        1. ECHO                                               */
    /*        2. SUPRESS-GO-AHEAD                                   */
    /*        3. TERM-TYPE                                          */
    /* "IAC WILL ECHO" 设置telnet client远端回显而不本地回显        */
    /* "IAC WILL ECHO" and "IAC WILL SUPRESS-GO-AHEAD" 设置client为 */
    /*  字符处理设备而非行处理设备                                  */
    /* "IAC DO TERMTYPE" 开始子协商选项                             */
    /*--------------------------------------------------------------*/

    /*--------------------------------------------------------------*/
    /* IAC WILL ECHO                                                */
    /*--------------------------------------------------------------*/
    pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCIAC ;
    pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCWILL ;
    pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = TOECHO ;

    /*--------------------------------------------------------------*/
    /* IAC WILL SUPRESS-GO-AHEAD                                    */
    /*--------------------------------------------------------------*/
    pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCIAC ;
    pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCWILL ;
    pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = TONOGA ;

    /*--------------------------------------------------------------*/
    /* IAC DO TERMTYPE                                              */
    /*--------------------------------------------------------------*/
    /* 由于在WIN2000下面TELNET慢,所以去掉这里的协商代码 */
    #if 0
    pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCIAC ;
    pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCDO ;
    pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = TOTERMTYPE ;
    #endif

    pTermStruct->szSendBuf[ pTermStruct->iSendLen ] = '\0' ;

    CLI_SendToTerm ( pTermStruct ) ;

    return ;
}


/*==================================================================*/
/*      函数名      :CLI_FsmBuild                                   */
/*      函数功能    :建立状态机                                     */
/*      输入参数    :无                                             */
/*      输出参数    :无                                             */
/*      返回值      :无                                             */
/*      调用函数    :CLI_FsmInit ( )                                */
/*      被调函数    :                                               */
/*==================================================================*/

_VOID CLI_FsmBuild ( _VOID )
{
    /*--------------------------------------------------------------*/
    /* 初始化telnet FSM                                             */
    /*--------------------------------------------------------------*/
    CLI_FsmInit ( TTFsm, TTStab, NTSTATES ) ;

    /*--------------------------------------------------------------*/
    /* 初始化选项子协商FSM                                          */
    /*--------------------------------------------------------------*/
    CLI_FsmInit ( SubFsm, SubStab, NSSTATES ) ;

    return ;
}

/*==================================================================*/
/*      函数名      :CLI_FsmInit                                    */
/*      函数功能    :初始化状态机                                   */
/*      输入参数    :_U8 fsm[ ][ NCHRS ] 要初始化的状态机         */
/*                   _U8    ucMaxState  最大状态数                */
/*      输出参数    :_U8 fsm[ ][ NCHRS ] 初始化后的状态机         */
/*      返回值      :无                                             */
/*      调用函数    :CLI_FsmInit ( )                                */
/*      被调函数    :                                               */
/*==================================================================*/

_VOID CLI_FsmInit ( _U8 fsm[ ][ NCHRS ],
               struct Fsm_Trans_S Ttab[ ],
               _U8    ucMaxState )
{
    struct Fsm_Trans_S  * lpTab ;
    _S32   ulState, jState, iChar ;

    /*--------------------------------------------------------------*/
    /* 首先将FSM初始化为 TINVALID (无效)                            */
    /*--------------------------------------------------------------*/
    for ( iChar = 0 ; iChar < NCHRS ; ++ iChar )
        for ( ulState = 0 ; ulState < ucMaxState ; ++ ulState )
            fsm[ ulState ][ iChar ] = TINVALID ;

    /*--------------------------------------------------------------*/
    /*根据状态转移表初始化FSM,将FSM与状态转换表对应起来,建立索引关系*/
    /*--------------------------------------------------------------*/
    for ( ulState = 0 ; Ttab[ ulState ].Ft_State != FSINVALID ; ++ ulState )
    {
        lpTab = &Ttab[ ulState ] ;
        jState = lpTab->Ft_State ;
        if ( lpTab->Ft_Char == TCANY )
        {
            for ( iChar = 0 ; iChar < NCHRS ; ++ iChar )
                if ( fsm[ jState ][ iChar ] == TINVALID )
                    fsm[ jState ][ iChar ] = (_U8)ulState ;
        }
        else
            fsm[ jState ][ lpTab->Ft_Char ] = (_U8)ulState ;
    }
    return ;
}


/*==================================================================*/
/*      函数名      :CLI_tcdm                                       */
/*      函数功能    :处理telnet "data mark"数据标记信令             */
/*      输入参数    :PTerm_Data_S pTermStruct  任务数据             */
/*                   _U8 c  接收到的输入字符                      */
/*      输出参数    :PTerm_Data_S pTermStruct  任务数据             */
/*      返回值      :_U32   1:成功                                 */
/*      调用函数    :CLI_DebugOutString ( )                         */
/*      被调函数    :                                               */
/*==================================================================*/

_U32 CLI_tcdm ( PTerm_Data_S pTermStruct, _U8 c )
{
    _S8 szFSMInfoEn[] =
    "\r\n\r\n  The telnet NVT FSM : \r\n \
     \r\n    the current state   : TSIAC \
     \r\n    the input character : DM ( Data Mark ) \
     \r\n    the next state      : TSDATA \
     \r\n    the action          : Synching = 0 ";
     _S8 szFSMInfoCh[] =
    "\r\n\r\n  Telnet 网络虚拟终端状态机 : \r\n \
     \r\n    当前状态    : TSIAC \
     \r\n    输入字符    : DM ( Data Mark ) \
     \r\n    下一状态    : TSDATA \
     \r\n    执行动作    : Synching = 0 ";

    (_VOID)c ;   /* for lint */
    if(pTermStruct == G_NULL)
    {
        return 1;
    }
    /*--------------------------------------------------------------*/
    /* marks end of SYNCH                                           */
    /*--------------------------------------------------------------*/
    pTermStruct->TelnetParam.Synching = 0 ;

    if ( G_TRUE == m_bCliTelnetDebugOn )
    {
        if ( pTermStruct->iRecvLen == 1 )
        {
            CLI_TelFSMDegOut(szFSMInfoEn, szFSMInfoCh);
        }
    }

    return 1 ;
}

/*==================================================================*/
/*      函数名      :CLI_RecOpt                                     */
/*      函数功能    :记录选项类型                                   */
/*      输入参数    :PTerm_Data_S pTermStruct  任务数据             */
/*                   _U8 c  接收到的输入字符                      */
/*      输出参数    :PTerm_Data_S pTermStruct  任务数据             */
/*      返回值      :_U32   1:成功                                 */
/*      调用函数    :CLI_DebugOutString ( )                         */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -