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

📄 cli_termtelnet.c

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

filename     : CLI_Term.c

description  : 1、实现命令行操作终端的任务管理
               2、终端任务数据中的字符串编辑缓冲的处理

author       : Woodhead

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

#include "Ros.h"
#include "CLI_Private.inc"
#include "CLI_Io.h"
#include "CLI_User.inc"
#include "CLI_Intp.inc"
#include "CLI_Telnet.inc"
#include "ML.h"
#include "Sys_Ml.h"
#include "Cli_MlPriv.h"
#include "cm_sock.h"
#include "Board_Pub.h"
#include "Config\Cli_ConfigGlbVar.h"

extern _VOID CLI_MMLTaskInit(PTerm_Data_S pTermStruct);


#if CLI_TELNET_SUPPORT


/*telnet server 初始化标志  只在本文件使用*/
static _U32 m_ulTelnetInitFlag = G_FALSE;


/*==================================================================*/
/*      函数名      :CLI_TelnetTasksCreat                           */
/*      函数功能    :创建与Telnet相关的任务.                               */
/*      输入参数    :无                                             */
/*      输出参数    :无                                             */
/*      返回值      :_U32  0:   初始化成功  1:    初始化失败        */
/*      被调函数    :                                               */
/*==================================================================*/
_U32 CLI_TelnetTasksCreat(_VOID)
{
    _U32 ulRet;
    _U32 ulArg[2] = {0, 0};
    _U32 ulTaskID;
    _U32 i;
    _S8  szTaskName[32];

    /* telnet服务器任务创建 */
    ulRet = ROS_SelfTaskCreate(PID_CLI,  "CLI_TASK_TELSERVER",
                    EN_ROS_TASK_PRIORITY_NORMAL,
                    ROS_TASK_STACK_SIZE_DEFAULT,
                    ulArg, CLI_TelnetServer, &ulTaskID);
    CLI_ASSURE_OR_FAIL(ulRet == G_SUCCESS);


    /* Note: 第一个任务为命令透传处理任务(MML) */
    /* ??? LingJian_Tailor */
    #if 0
    ulArg[0] = 1;
    EOS_Sprintf(szTaskName, "CLI_TASK_TEL%d", i);
    ulRet = ROS_SelfTaskCreate(PID_CLI, szTaskName,
                    EN_ROS_TASK_PRIORITY_NORMAL,
                    ROS_TASK_STACK_SIZE_DEFAULT,
                    ulArg, CLI_TelnetTask, &ulTaskID );
    CLI_ASSURE_OR_FAIL(ulRet == G_SUCCESS);
    #endif

    for (i = FIRST_TELNET_DATA; i < m_ulCliMaxOnlineUser; i++)
    {
        ulArg[0] = i;
        EOS_Sprintf(szTaskName, "CLI_TASK_TEL%d", i);
        ulRet = ROS_SelfTaskCreate(PID_CLI, szTaskName,
                        EN_ROS_TASK_PRIORITY_NORMAL,
                        ROS_TASK_STACK_SIZE_DEFAULT,
                        ulArg, CLI_TelnetTask, &ulTaskID );
        CLI_ASSURE_OR_FAIL(ulRet == G_SUCCESS);
    }

    return G_SUCCESS;

}


/*==================================================================*/
/*      函数名      :CLI_TelnetServerInit                           */
/*      函数功能    :初始化telnet连接                               */
/*      输入参数    :无                                             */
/*      输出参数    :无                                             */
/*      返回值      :_U32  0:   初始化成功  1:    初始化失败        */
/*      被调函数    :                                               */
/*==================================================================*/
_U32 CLI_TelnetServerInit (_S32 *iSocketServer)
{
    struct sockaddr_in sServerAddr ;

    /* 创建一TCP socket连接 */
    if ( ( *iSocketServer = socket ( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
    {
        MT_ERRLOG(0);
        return G_FAILURE ;
    }

    /* 设置服务器端端口,并与套接字绑定 */
    memset ( ( _VOID * )&sServerAddr, 0, sizeof(sServerAddr) ) ;
    sServerAddr.sin_family = AF_INET ;          /* TCP - 数据流     */
    sServerAddr.sin_port = (_U16)htons(TELNETPORT);   /* Telnet 端口号 23 */
    sServerAddr.sin_addr.s_addr = (_U32)htonl(INADDR_ANY) ; /* 任意客户IP地址 */

    if ( bind ( *iSocketServer, ( struct sockaddr * )&sServerAddr,
                   sizeof( sServerAddr ) ) != 0 )
    {
        urp_close(*iSocketServer);
        MT_ERRLOG(0);
        return G_FAILURE ;
    }

    /* 侦听TELNET CLIENT的连接请求 */
    if ( listen ( *iSocketServer, (int)g_ul_CFG_CLI_MAX_TELNET_CLIENT_NUM) != 0 )
    {
        urp_close(*iSocketServer);
        MT_ERRLOG(0);
        return G_FAILURE ;
    }

    /* 建立TELNET状态机 */
    if(m_ulTelnetInitFlag == G_FALSE)
    {
        CLI_FsmBuild ( ) ;
        m_ulTelnetInitFlag = G_TRUE;
    }

    return G_SUCCESS ;
}

/*********************************************************************/
/* 函数名称 : CLI_TelnetInit()                                       */
/* 函数功能 : telnet任务初始化函数                                   */
/* 输入参数 : pTermStruct  telnet终端任务数据                        */
/* 输出参数 : pTermStruct  telnet终端任务数据                        */
/* 返回     : 成功/失败                                              */
/* 上层函数 :                                                        */
/* 创建者   :                                                        */
/* 修改记录 :                                                        */
/*********************************************************************/
_U32 CLI_TelnetInit(PTerm_Data_S pTermStruct)
{
    _S32    iOptVal,iOptLen;

    iOptVal = 1 ;
    iOptLen = sizeof ( iOptLen ) ;
    setsockopt ( pTermStruct->iSocket, SOL_SOCKET,  SO_OOBINLINE, ( _S8 * ) & iOptVal,iOptLen ) ;

    /* telnet server的TCP_NODELAY选项, 默认应该关闭, 即 iOptVal = 0 */
    iOptVal = 0 ;
    iOptLen = sizeof ( iOptLen ) ;
    setsockopt ( pTermStruct->iSocket, IPPROTO_TCP, 0x01,  ( _S8 * ) & iOptVal, iOptLen ) ;

    CLI_NegotiateOption ( pTermStruct) ;

    return G_SUCCESS;
}
/*==================================================================*/
/*      函数名      :CLI_TelnetServer                               */
/*      函数功能    :Telnet Server任务函数体                        */
/*      输入参数    :无                                             */
/*      输出参数    :无                                             */
/*      返回值      :无                                             */
/*      被调函数    :                                               */
/*==================================================================*/
_VOID CLI_TelnetServer( _U32 ulArg1, _U32 ulArg2)
{
    struct sockaddr_in sClientAddr ;
    _S32 iSocket;
    _S32 iNameLen, iSocketServer;
    _U32 ulCount;
    _S8 szTelnetIp[20];

    (_VOID)ulArg1;
    (_VOID)ulArg2;

    /*--------------------------------------------------------------*/
    /* 初始化telnet sever                                           */
    /*--------------------------------------------------------------*/
    while ( CLI_TelnetServerInit(&iSocketServer) != G_SUCCESS )
    {
        DBG_Out(PID_CLI, CLI_DBGOUT_NOTE, "\r\n CLI: TelnetServer Initial failed!");
        CLI_DELAY(200);
    }

    iNameLen = sizeof( sClientAddr ) ;
    for ( ; ; )
    {
        /* 等待接收telnet client的连接                              */
        if( ( iSocket = accept( (int)iSocketServer, ( struct sockaddr * )&sClientAddr,
                    (int*)&iNameLen ) ) <= 0 )
        {
            CLI_DELAY(10);
            continue ;
        }

        _IPAddrToStr(sClientAddr.sin_addr.s_addr, &szTelnetIp[0]) ;
        DBG_Out(PID_CLI, MT_DBGOUT_NOTE,
                "\r\n CLI: 客户端 %s 连接到本机.", szTelnetIp);

        /* 检验客户端ip地址的合法性(是否在telnet访问允许列表内)*/
        #if MULTI_DEVICE_SUPPORT
    if (m_CliIsMainDevice == G_TRUE)
        #endif
        if( CLI_AclCheck(sClientAddr.sin_addr.s_addr) != G_SUCCESS )
        {
            IO_SendToAllTerm(CLI_TELNET_CLIENT_REFUSED, szTelnetIp);
            CLI_DELAY(200);
            urp_close ( iSocket ) ;
            continue ;
        }

        for(ulCount = FIRST_TELNET_DATA; ulCount < m_ulCliMaxOnlineUser; ulCount++)
        {
            if (m_TDTable[ulCount].pTermStruct->ucTermStatus == TERM_SLEEPING
             && m_TDTable[ulCount].pTermStruct->iSocket == SOCKET_NOT_INITIAL)
                break;
        }

        if(ulCount == m_ulCliMaxOnlineUser)
        {
            send ( (int)iSocket, (char *)"\n\r  Too many telnet users!", 26, 0 ) ;
            CLI_DELAY(100);
            urp_close ( iSocket ) ;
            continue ;
        }

        /* 激活该任务的状态 */
        m_TDTable[ulCount].pTermStruct->iSocket = iSocket;
        m_TDTable[ulCount].pTermStruct->ulClientIP = sClientAddr.sin_addr.s_addr;
        CLI_SetTermStatus(m_TDTable[ulCount].pTermStruct, TERM_ACTIVE);

    }
}

/*==================================================================*/
/*      函数名      :CLI_ReceiveFromTelnet                          */
/*      函数功能    :从telnet客户端接收数据                         */
/*      输入参数    :pTermStruct 任务数据                           */
/*                   ulSecond 接收超时时间                          */
/*      输出参数    :无                                             */
/*      返回值      :无                                             */
/*==================================================================*/
_U32 CLI_ReceiveFromTelnet ( PTerm_Data_S pTermStruct, _U32 ulSecond)
{
    fd_set SocketSet ;
    struct timeval stWait ;
    _S32 lErr =0;

    if ( G_NULL == pTermStruct || ulSecond > DEADLINE_SHORT)
    {
        CLI_RECORD(CLI_STAT_RECEIVE_ERR);
        return G_FAILURE ;
    }

    stWait.tv_usec = 0 ;
    stWait.tv_sec  = (_S32)ulSecond;

    FD_ZERO ( &SocketSet ) ;
    FD_SET ( (_U32)pTermStruct->iSocket, &SocketSet ) ;

    CLI_RECORD(CLI_STAT_CLIENT_GOTO_SELECT);
    lErr = urp_select ( FD_SETSIZE, &SocketSet, ( fd_set * ) 0, ( fd_set * ) 0, &stWait );
    CLI_RECORD(CLI_STAT_CLIENT_OVER_SELECT);
    if ( lErr > 0 )
    {
        /* 接收来自telnet客户端的数据 */
        FD_ZERO ( &SocketSet ) ;

        if (TERM_SEM_P(pTermStruct))
        {
            CLI_RECORD(CLI_STAT_SEM_P);
            return G_FAILURE;
        }

        CLI_RECORD(CLI_STAT_CLIENT_GOTO_RECV);
        pTermStruct->iRecvLen = recv ( pTermStruct->iSocket, pTermStruct->szRecvBuf,  TERM_IO_BUFFER, 0) ;
        CLI_RECORD(CLI_STAT_CLIENT_OVER_RECV);

        if(TERM_SEM_V(pTermStruct))
        {
            CLI_RECORD(CLI_STAT_SEM_V);
            DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n Sem_P of Term %d Failed!", pTermStruct->ulTermId);
        }

        if (pTermStruct->iRecvLen> 0 )
        {
            return G_SUCCESS ;
        }
        DBG_Out(PID_CLI, CLI_DBGOUT_NOTE, "\r\n CLI_ReceiveFromeTelnet:: recv() Failed!");
    }
    else if(lErr == 0)
    {
        CLI_RECORD(CLI_STAT_CLIENT_RECV_TIMEOUT);
        return G_FAILURE;
    }

    CLI_SetTermStatus(pTermStruct, TERM_SLEEPING);
    CLI_RECORD(CLI_STAT_CLIENT_RECV_CLOSED);

    return G_FAILURE ;
}

/*==================================================================*/
/*      函数名      :CLI_SendToTelnet                               */
/*      函数功能    :向telnet客户端发送数据                         */
/*      输入参数    :PTerm_Data_S pTermStruct 任务数据              */
/*                   PTerm_Data_S pTermStruct 任务数据              */
/*      输出参数    :无                                             */
/*      返回值      :_U32   0:  发送成功   1:   发送失败            */
/*      被调函数    :                                               */
/*==================================================================*/
_U32 CLI_SendToTelnet ( PTerm_Data_S pTermStruct )
{

⌨️ 快捷键说明

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