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

📄 cli_termtelnet.c

📁 命令行在嵌入式系统的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
    fd_set SocketSet ;
    struct timeval stWait;
    _S32 ulErr = 0;

    CLI_ASSURE_OR_FAIL( G_NULL != pTermStruct );

    if ( pTermStruct->iSendLen == 0)
        return G_SUCCESS;

    stWait.tv_sec  = 10;
    stWait.tv_usec = 0 ;

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

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

    CLI_RECORD(CLI_STAT_CLIENT_GOTO_SELECT_S);
    ulErr = urp_select( (_U32)(pTermStruct->iSocket + 1), ( fd_set * ) 0, &SocketSet,  ( fd_set * ) 0, &stWait );
    CLI_RECORD(CLI_STAT_CLIENT_OVER_SELECT_S);
    if (ulErr > 0 )
    {
        FD_ZERO ( &SocketSet );

        CLI_RECORD(CLI_STAT_CLIENT_GOTO_SEND);
        ulErr = send ( pTermStruct->iSocket, pTermStruct->szSendBuf, pTermStruct->iSendLen, 0 );
        CLI_RECORD(CLI_STAT_CLIENT_OVER_SEND);

        if(TERM_SEM_V(pTermStruct))
        {
            CLI_RECORD(CLI_STAT_SEM_V);
            DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n Sem_V_1 of Term %d Failed!", pTermStruct->ulTermId);
        }
        if (  ulErr>= 0 )
        {
            pTermStruct->iSendLen = 0 ;
            pTermStruct->szSendBuf[ 0 ] = '\0' ;
            return G_SUCCESS;
        }
        else
        {
            DBG_Out(PID_CLI, CLI_DBGOUT_NOTE, "\r\n CLI_SendToTelnet:: send() Failed!");
            return G_FAILURE;
        }
    }

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

    CLI_SetTermStatus(pTermStruct, TERM_SLEEPING);
    CLI_RECORD(CLI_STAT_CLIENT_SEND_CLOSED);
    return G_FAILURE;
}

_U32 CLI_CloseSocket(PTerm_Data_S pTermStruct)
{
    urp_close (pTermStruct->iSocket);
    pTermStruct->iSocket = SOCKET_NOT_INITIAL;
    return G_SUCCESS;
}





/*********************************************************************/
/* 函数名称 : CLI_TelnetTask()                                       */
/* 函数功能 : telnet任务体,根据状态实现telnet功能                   */
/* 输入参数 : 无                                                     */
/* 输出参数 : 无                                                     */
/* 返回     : 无                                                     */
/* 上层函数 : 任务调度函数                                           */
/* 创建者   :                                                        */
/* 修改记录 :                                                        */
/*********************************************************************/
_VOID CLI_TelnetTask( _U32 ulArg1, _U32 ulArg2)
{
    PTerm_Data_S pTermStruct ;
    #if MULTI_DEVICE_SUPPORT
    _U32  ulTimeDes[5] = {0,0,0,0,0};
    #endif

    (void)ulArg2;

    if (ulArg1 >= m_ulCliMaxOnlineUser)
    {
        DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n CLI: telnet task id invalid!", ulArg1);
        MT_ERRLOG(ulArg1);
        return;
    }

    pTermStruct = m_TDTable[ulArg1].pTermStruct;
    if (EOS_TaskGetSelfID(&m_TDTable[ulArg1].lTaskid) != G_SUCCESS)
    {
        CLI_RECORD(CLI_STAT_GET_TID_FAILD);
        DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n CLI: Get task id of tel%d failed!", ulArg1);
        MT_ERRLOG(0);
    }

    /* 第一个创建的任务或由从设备创建的任务,均作为命令透传处理任务 */
    if (ulArg1 == 1)
    {
        CLI_MMLTaskInit(pTermStruct);
    }
#if MULTI_DEVICE_SUPPORT
    if (m_CliIsMainDevice != G_TRUE && ulArg1 + 1 < m_ulCliMaxOnlineUser )
    {
        CLI_MMLTaskInit(pTermStruct);
    }
#endif

    for (; ;)
    {
        switch (pTermStruct->ucTermStatus)
        {
            case TERM_SLEEPING:
                CLI_DELAY(20);
                break;
            case TERM_ACTIVE:
                CLI_TelnetInit(pTermStruct);
                CLI_TermLogin(pTermStruct);
                break;
            case TERM_LOGED:
                CLI_TermTaskProc(pTermStruct);
                if (!IS_TERM_NORMAL(pTermStruct))
                {
                    CLI_TermLogout(pTermStruct);
                }
                break;
            #if MULTI_DEVICE_SUPPORT
            case TERM_WAIT_RESPONSE:
            {
                if (ulTimeDes[ulArg1 - 1] == 0)
                {
                    ulTimeDes[ulArg1 - 1] = WAIT_RESPONSE_TIME;
                }
                else if (ulTimeDes[ulArg1 - 1] == 1)
                {
                    IO_Print(CLI_WAIT_RESP_TIMEOUT);
                    CLI_SetTermStatus(pTermStruct, TERM_LOGED);
                }

                if (m_CliIsMainDevice != G_TRUE)
                {
                    CLI_SetTermStatus(pTermStruct, TERM_LOGED);
                    ulTimeDes[ulArg1 - 1] = 0;
                    continue;
                }
                if (pTermStruct->szSendBuf[0] != '\0')
                {
                    _S8 *pcPos = G_NULL;

                    ulTimeDes[ulArg1 - 1] = WAIT_RESPONSE_TIME;

                    pTermStruct->ulTimeLeft
                        = (pTermStruct->ucTimeOutFlag == TIMEOUT_ON ? DEADLINE_SHORT : DEADLINE_LONG);
                    if ((pcPos = strstr(pTermStruct->szSendBuf, CMD_RESPONED_END)) != G_NULL)
                    {
                        *pcPos = '\0';
                        CLI_SendToTerm(pTermStruct);
                        CLI_SetTermStatus(pTermStruct, TERM_LOGED);
                        ulTimeDes[ulArg1 - 1] = 0;
                    }
                    else
                        CLI_SendToTerm(pTermStruct);
                }
                else
                {
                    ulTimeDes[ulArg1 - 1]--;
                    CLI_DELAY(10);
                }
                break;
            }
            #endif
            default:
                CLI_SetTermStatus(pTermStruct, TERM_SLEEPING);
                break;
        }
    }
}


/*==================================================================*/
/*      函数名      :CLI_TelnetEditString                           */
/*      函数功能    :Telnet扫描接收缓冲区,并编辑字符串编辑缓冲区    */
/*      输入参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      输出参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      返回值      :_U32   0:  接收到一完整命令行并准备提交该命令  */
/*                         1:  只接收到一字符并准备继续接收字符     */
/*      调用函数    : CLI_EditString()                              */
/*      被调函数    :                                               */
/*==================================================================*/
_U32 CLI_TelnetEditString( PTerm_Data_S pTermStruct )
{
    _U32  ulTmp ;
    _U8   ucTmp ;
    _U32  jTmp;
    struct Fsm_Trans_S * pt ;

    CLI_ASSURE_OR_FAIL( G_NULL != pTermStruct );
    CLI_ASSURE_OR_FAIL ( pTermStruct->iSocket != SOCKET_FOR_SERIAL )

    /* 接收字符串来自telnet terminal client,利用telnet的有限状态机  */
    for ( ulTmp = 0 ; ulTmp < (_U32)pTermStruct->iRecvLen ; ulTmp ++ )
    {
        ucTmp = (_U8)pTermStruct->szRecvBuf[ ulTmp ] ;
        jTmp = ucTmp ;

        jTmp = TTFsm[ pTermStruct->TelnetParam.TTState ][ jTmp ] ;

        if(jTmp != TINVALID)
        {
            pt = &TTStab[ jTmp ] ;
            pTermStruct->TelnetParam.TTState = pt->Ft_Next ;
            if ( ! ( pt->Ft_Action ) ( pTermStruct, ucTmp ) )
                return G_SUCCESS ;
        }
    }

    return G_FAILURE ;

}



#endif /* #if CLI_TELNET_SUPPORT */

/*==================================================================*/
/*      函数名      :CLI_MMLTaskInit                                */
/*      函数功能    :MML类型的终端任务数据初始化                    */
/*      输入参数    :pTermStruct 终端任务结构                       */
/*      输出参数    :无                                             */
/*      返回值      :无                                             */
/*      被调函数    :                                               */
/*==================================================================*/
_VOID CLI_MMLTaskInit(PTerm_Data_S pTermStruct)
{
    pTermStruct->iSocket = SOCKET_FOR_MML;
    pTermStruct->ucTermStatus = TERM_LOGED;
    pTermStruct->ucScroll = SCROLL_AUTO;
    pTermStruct->pWS->ulSmart = SMART_OFF;
    pTermStruct->pWS->ulLevel = CT_AL_DEBUG;
    pTermStruct->ucUserLevel =  CT_AL_DEBUG;
    return;
}

/*┏━━━━━━━━━━Telnet调试命令实现━━━━━━━━━┓*/
/*┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛*/
_U32 CLI_CmdTelnetDiag(_U32 Param1, _U32 Param2, _U32 Param3, _U32 Param4)
{
    extern _U32 CLI_DispStatInfo(_U32 ulTermID);

    _S8 szIpaddr[20], szMask[20] = "255.255.0.0";
    _U32 ulIpaddr, ulMask;
    _U32 ulRet = G_SUCCESS;
    PTerm_Data_S pTermStruct;
    (_VOID)Param4;

    switch(Param1)
    {
        case 0:
            DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                    "\r\n param1 -- 调试类型: 1. 打开一个telnet访问允许(IP:param2.param3.0.0/16)"
                    "\r\n                     2. 查看telnet终端信息"
                    "\r\n                     3. 踢掉一个终端(ID = param2)"
                    "\r\n                     4. 查询统计信息");
            break;
        case 1:
            EOS_Sprintf(szIpaddr, "%d.%d.0.0", Param2, Param3);
            if ((_StrToIPAddr(szIpaddr, &ulIpaddr) != G_SUCCESS)
             || (_StrToIPAddr(szMask, &ulMask) != G_SUCCESS))
                return G_FAILURE;
            ulRet = CLI_AclAdd(ulIpaddr, ulMask);
            break;
        case 2:
            break;
        case 3:
            if (!CLI_IS_TERMID_VALIDE(Param2))
                return G_FAILURE;

            //强行注销该终端
            CLI_TermLogout(m_TDTable[Param3].pTermStruct);
            break;
        case 4:
            CLI_DispStatInfo(1);
            break;
        case 5:
            if (!CLI_IS_TERMID_VALIDE(Param2))
                return G_FAILURE;

            pTermStruct = m_TDTable[Param2 - 1].pTermStruct;

            DBG_Out(PID_CLI, CLI_DBGOUT_MUST, "\r\n Term Data: (address = 0x%x)\r\n"
                                "\r\n socket = 0x%x"
                                "\r\n username = %s"
                                "\r\n ulTimeLeft = %d"
                                "\r\n ucTermStatus = %d"
                                "\r\n ucUserLevel = %d"
                                "\r\n pWS data: (address = 0x%x)"
                                "\r\n szCmd = %s"
                                "\r\n ulLevel = %d"
                                "\r\n ulStatus = %d",
                                (_U32)pTermStruct, pTermStruct->iSocket,
                                pTermStruct->szCurUserName, pTermStruct->ulTimeLeft,
                                pTermStruct->ucTermStatus,  pTermStruct->ucUserLevel,
                                (_U32)pTermStruct->pWS,     pTermStruct->pWS->szCmdString,
                                pTermStruct->pWS->ulLevel,  pTermStruct->pWS->ulStatus);
            break;
        default:
            return G_FAILURE;
    }

    return ulRet;
}

⌨️ 快捷键说明

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