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

📄 cli_term.c

📁 命令行在嵌入式系统的实现
💻 C
📖 第 1 页 / 共 5 页
字号:
    else if (cFlag == 'c' )
    {
        csbi.dwCursorPosition.X = (_S16)(csbi.dwCursorPosition.X + iTmp) ;
        if (csbi.dwCursorPosition.X >= 80 )
            csbi.dwCursorPosition.X = 79 ;
        SetConsoleCursorPosition(hStdOut, csbi.dwCursorPosition) ;
    }
    return ;
}
#endif

#if MULTI_DEVICE_SUPPORT
/*==================================================================*/
/*      函数名      :CLI_SendToMML                                  */
/*      函数功能    :输出信息到MML,因为从设备所有终端类型都定义为  */
/*                   MML,因此需要在这一层加以区分                  */
/*      输入参数    :pTermStruct 终端任务结构                       */
/*      输出参数    :无                                             */
/*      返回值      :_U32  0:   成功  1:    失败                    */
/*      被调函数    :                                               */
/*==================================================================*/
_U32 CLI_SendToMML(PTerm_Data_S pTermStruct)
{
    #if MULTI_DEVICE_SUPPORT
    ST_MSG       *pstMsg;

    if (m_CliIsMainDevice != G_TRUE)
    {
        // 发送到主设备: 发送字符串,字符串标志,设备ID
        pstMsg = CLI_MSMsgCreat(0, pTermStruct->ulTermId,
                                MSG_CODE_CLI_FEEDBACK, pTermStruct->szSendBuf);
        CLI_ASSURE_OR_FAIL(G_NULL != pstMsg);

        if( G_SUCCESS != BOARD_SEND_MSG( pstMsg ) )
        {
            ROS_MsgFree(pstMsg);
            DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n  CLI(error return): CLI_SendToMML:: BOARD_SEND_MSG");
            return G_FAILURE;
        }
        return G_SUCCESS;
    }
    else
    #endif
    {
        PNMS_MSG_S pNmsMsg;
        _U16 usLen;
        if (!Agent_IsNmsOnline())
            return G_SUCCESS;

        if (pTermStruct->ulTermId != 2)
            MT_ERRLOG(pTermStruct->ulTermId);

        // 转发给agent处理:字符串
        usLen = (_U16)EOS_StrLen(pTermStruct->szSendBuf) + 1;
        if (usLen == 1)
            return G_SUCCESS;

        pNmsMsg = Agent_MsgMalloc((_U32)usLen);

        pNmsMsg->usLen = htons(usLen);
        MT_htons(pNmsMsg->usCmd, E_NMS_CODE_CMD_INFO);
        EOS_MemCopy(pNmsMsg->ucData, pTermStruct->szSendBuf, usLen);

        if (Agent_NmsCmdFeedback(pNmsMsg) != G_SUCCESS)
        {
            MT_ERRLOG(0);
        }
        ROS_MemFree(pNmsMsg);

        return G_SUCCESS;
    }
}
#endif



/*********************************************************************/
/* 函数名称 : CLI_TermTaskProc()                                     */
/* 函数功能 : 终端任务处理核心函数                                   */
/* 输入参数 : pTermStruct:终端任务数据                                */
/* 输出参数 : 终端任务数据                                           */
/* 返回     : 无                                                     */
/* 上层函数 : 终端任务函数体                                         */
/* 创建者   :                                                        */
/* 修改记录 :                                                        */
/*********************************************************************/
_VOID CLI_TermTaskProc(PTerm_Data_S pTermStruct)
{
    if (!IS_TERM_NORMAL(pTermStruct))
        return ;

     /*【1】从终端接收字符*/
    if (CLI_ReceiveFromTerm(pTermStruct, pTermStruct->ulTimeLeft) != G_SUCCESS)
        return;

    if (!IS_TERM_NORMAL(pTermStruct))
    {
        DBG_Out(PID_CLI, CLI_DBGOUT_NOTE,
                "\r\n CLI_TermTaskProc::Received but Term %d Abnormal!", pTermStruct->ulTermId);
        return;
    }

    /* 【2】处理命令缓冲区*/
    if (CI_CmdBufProcess(pTermStruct) != G_SUCCESS)
        return;

    /* 【3】执行完整接收的命令*/
    CI_CmdExecute(pTermStruct);

    /* 【4】保存命令(历史记录/日志记录)*/
    CLI_CmdRecord(pTermStruct);

    if (!IS_TERM_NORMAL(pTermStruct))
    {
        DBG_Out(PID_CLI, CLI_DBGOUT_NOTE,
                "\r\n CLI_TermTaskProc::Cmd executed but Term %d Abnormal!", pTermStruct->ulTermId);
        return;
    }

    CI_DisplayPrompt(pTermStruct);

    return;
}

/*********************************************************************/
/* 函数名称 : CLI_SerialTask()                                       */
/* 函数功能 : 串口任务函数体                                         */
/* 输入参数 : 无                                                     */
/* 输出参数 : 无                                                     */
/* 返回     : 无                                                     */
/* 上层函数 : 任务调度                                               */
/* 创建者   : Liuzequn                                               */
/* 修改记录 :                                                        */
/*********************************************************************/
_VOID CLI_SerialTask( _U32 ulArg1, _U32 ulArg2)
{
    PTerm_Data_S pTermStruct ;
    #if MULTI_DEVICE_SUPPORT
    _U32 ulTimeWait = 0;
    #endif

    (_VOID)ulArg1;
    (_VOID)ulArg2;

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

    CLI_SerialInit();
    pTermStruct->iSocket = SOCKET_FOR_SERIAL;

    CLI_TermLogin(pTermStruct);

    for ( ; ; )
    {
        if (pTermStruct->ucTermStatus < TERM_LOGED || pTermStruct->ulTimeLeft == 0)
        {
            CLI_TermLogout(pTermStruct);
            pTermStruct->iSocket = SOCKET_FOR_SERIAL;
            CLI_TermLogin(pTermStruct);
        }
        #if MULTI_DEVICE_SUPPORT
        else if (pTermStruct->ucTermStatus == TERM_WAIT_RESPONSE)
        {
            if (ulTimeWait == 0)
            {
                ulTimeWait = WAIT_RESPONSE_TIME;
            }
            else if (ulTimeWait == 1)
            {
                IO_Print(CLI_WAIT_RESP_TIMEOUT);
                CLI_SetTermStatus(pTermStruct, TERM_LOGED);
            }

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

                ulTimeWait = 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);
                }
                else
                    CLI_SendToTerm(pTermStruct);
            }
            else
            {
                ulTimeWait --;
                CLI_DELAY(10);
            }
            continue;

        }
        #endif
        CLI_TermTaskProc(pTermStruct);
    }
}



/*********************************************************************/
/* 函数名称 : CLI_PeriodTask()                                       */
/* 函数功能 : 命令行内部定时任务                                     */
/* 输入参数 : 无                                                     */
/* 输出参数 : 无                                                     */
/* 返回     : 无                                                     */
/* 上层函数 :                                                        */
/* 创建者   :                                                        */
/* 修改记录 :                                                        */
/*********************************************************************/
_VOID CLI_PeriodProc(_VOID)
{
    _U32 i;
    PTerm_Data_S pTermStruct;

    for (i = 0; i < m_ulCliMaxOnlineUser; i++)
    {
        pTermStruct = m_TDTable[i].pTermStruct;

        if (pTermStruct->ulTimeLeft == 1)
        {
            DBG_Out(PID_CLI, MT_DBGOUT_NOTE, "r\n CLI: Term %d Timeout!", pTermStruct->ulTermId);
        }

        if (pTermStruct->ulTimeLeft > 0)
        {
            pTermStruct->ulTimeLeft--;
        }
        //透传命令的处理任务不设超时
        if (pTermStruct->iSocket == SOCKET_FOR_MML)
        {
            if (pTermStruct->ucTermStatus < TERM_LOGED)
                pTermStruct->ucTermStatus = TERM_LOGED;
            pTermStruct->ulTimeLeft = DEADLINE_LONG;
        }
        // 对调试用户,如果设置了长超时的话,设置为永不注销
        // (由于只有串口才支持设置长超时,因此条件应为调试用户在串口登录)
        if (pTermStruct->ucUserLevel >= CT_AL_DEBUG
         && pTermStruct->ucTimeOutFlag == TIMEOUT_OFF)
        {
            pTermStruct->ulTimeLeft = DEADLINE_LONG;
        }
    }
    return;
}


/*********************************************************************/
/* 函数名称 : CLI_TermLogin()                                        */
/* 函数功能 : 终端登录函数入口                                       */
/* 输入参数 : 终端任务数据                                           */
/* 输出参数 : 终端任务数据。该函数中登录成功将改变任务的运行状态,同 */
/*            时改变所登录的用户信息的状态                           */
/* 返回     : 无                                                     */
/* 上层函数 : 终端任务执行主函数体                                   */
/* 备注     : cli用户可以踢cli/web用户; web用户不能踢cli/web用户;    */
/* 创建者   :                                                        */
/* 修改记录 :                                                        */
/*********************************************************************/
_VOID CLI_TermLogin(PTerm_Data_S pTermStruct)
{
    _S8  szPassword[PASSWORD_LEN] ;
    _S8  szUsername[USERNAME_LEN] ;
    _U32 ulFailCount;
    _U32 ulLogMode;
    PTermUserItem pTermUser;
    PTerm_Data_S  pstOldLogTerm;
    ST_TIME sTime;
    const _S8   *pszVendorLongName;

    if( G_NULL == pTermStruct )
    {
        MT_ERRLOG(0);
        return ;
    }
    if (pTermStruct->iSocket == SOCKET_FOR_MML)
    {
        return ;
    }

    /* 因为在用户名与密码接收过程中有状态的判断,*/
    /* 故此处先置一个允许正常进行的状态         */
    CLI_SetTermStatus(pTermStruct, TERM_ACTIVE);
    pTermStruct->ulTimeLeft   = DEADLINE_SHORT;
    ulFailCount = 0;

    for (; ;)
    {
        while(IO_GetCharByPeek() != G_NULL)
            ;
        #if CLI_DEBUG_ON
        if (pTermStruct->iSocket == SOCKET_FOR_SERIAL)
        {
            pTermStruct->ucTimeOutFlag = TIMEOUT_OFF;
            EOS_StrCpy (szUsername, g_csz_CFG_CLI_DBG_USER_NAME);
            EOS_StrCpy (szPassword, g_csz_CFG_CLI_DBG_USER_PASSWORD);
        }
        else
        #endif
        {
            /* 用户名获取 */
            IO_OutToTerm(pTermStruct, "\r\n\r\n [USERNAME]: ");
            if (G_SUCCESS != IO_GetString(szUsername, USERNAME_LEN, EN_GETSTRING_NORMALLY))
            {
                #if CLI_TELNET_SUPPORT
                if( G_YES == g_ul_INCLUDE_SUB_MODULE_CLI_TELNET )
                {
                    if (pTermStruct->iSocket != SOCKET_FOR_SERIAL)
                    {
                        DBG_ASSERT( G_NULL != g_pfn_CFG_CLI_CloseSocket );

                        /*如果是telnet,手动注销并关闭该终端*/
                        g_pfn_CFG_CLI_CloseSocket(pTermStruct);
                        CLI_TaskDataInit(pTermStruct);
                        CLI_ResetEnviroment(pTermStruct->pWS);
                        CLI_SetTermStatus(pTermStruct, TERM_SLEEPING);
                        return;
                    }
                }
                #endif

                /* 如果超时时间内用户无输入,则进入输入等待状态,*/
                /* 一旦有输入,重新进入用户名输入状态            */
                IO_OutToTerm(pTermStruct, "\r\n  Timeout. \r\n  Press any key and input again.");
                while(IO_GetChar() ==G_NULL)
                    pTermStruct->ulTimeLeft = DEADLINE_SHORT;

                continue;
            }
            _AffirmStrBeLower(szUsername);
            /* 密码获取, 输入失败的处理同于用户名  */
            IO_OutToTerm(pTermStruct, "\r\n [PASSWORD]: ");

⌨️ 快捷键说明

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