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

📄 cli_init.c

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

filename     : CLI_Init.c

description  : 本文件实现命令行模块主要部分的初始化操作

author       : Woodhead

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

#include "Ros.h"
#include "ML.h"
#include "Cli_MlPriv.h"
#include "Cli_Private.inc"
#include "CLI_Intp.inc"
#include "..\include\Cli_IO.h"
#include "CLI_Telnet.inc"
#include "CLI_User.inc"
#include "Cli_Log.inc"
#include "CLI_Cmd.inc"
#include "Board_Pub.h"
#include "Config\Cli_ConfigGlbVar.h"

/*任务数据表(表项数目为m_ulCliMaxTermNum)*/
/*说明: 该任务数据表为静态表,其中前两个分别为串口任务和MML终端  */
/*      的服务器端,后四个为telnet任务, 终端任务ID即取该表下标+1 */
/*      若为从设备,则由终端1到的6分别对应主设备的终端,终端0、7 */
/*      分别为从设备自己的串口和telnet任务接收函数               */
struct TD_S      *m_TDTable = G_NULL;
CT_MODE_RECORD_T *m_sModeMutex[CTM_TOTAL];                      /* 模式互斥结构 */
_S8              m_szHostName[HOSTNAME_LENGTH] ;                /* 主机设备名 */
TIMER_ID         m_CliSecTimer;                                 /* 命令行定时器   */
_U32             m_ulCliStat[CLI_STAT_BUTT];                    /* 命令行统计信息 */

/* 串口波特率 */
_U32             m_ulSerialBaudrate             = 0;

/* 最大终端个数, 包括各种终端类型(com/telnet/web等), 表m_TDTable的大小  */
_U32             m_ulCliMaxTermNum              = 0;

/* 命令行最大在线用户个数 */
_U32             m_ulCliMaxOnlineUser           = 0;

/* Web网管终端在m_TDTable的起始索引和终止索引 */
#if ( CLI_WEB_SUPPORT == G_YES )
_U32             m_ulCliWebTermFirstIndex       = G_NULL_DWORD;
_U32             m_ulCliWebTermLastIndex        = G_NULL_DWORD;
#endif /* #if ( CLI_WEB_SUPPORT == G_YES ) */

#if MULTI_DEVICE_SUPPORT
_U8 m_CliIsMainDevice;

extern _U32 BOARD_IsMainDevice(_VOID);
#endif

/* 命令行模块的多语种字符串ID的枚举值的最大值 */
_U32            g_ul_EN_CLI_ML_PRIV_SID_BUTT = EN_CLI_ML_PRIV_SID_BUTT;

/*==================================================================*/
/*      函数名      :CLI_ProcessMsg                                 */
/*      函数功能    :命令行通用消息处理                             */
/*      输入参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      输出参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      返回值      :无                                             */
/*      调用函数    :无                                             */
/*      备注        :环境变量的初始化不在该函数中进行               */
/*==================================================================*/
_VOID CLI_ProcessMsg(ST_MSG *pMsg)
{
    ST_DBG_MSG* pDbgMsg;
    ST_TIMER_NOTIFY_MSG *pstNotify;
#if MULTI_DEVICE_SUPPORT
    PNMS_MSG_S pNmsMsg;
    PST_MSCLI_MSG pstMsCliMsg;
    PTerm_Data_S pTermStruct;
#endif

    if (pMsg == G_NULL || pMsg->usDstPid != PID_CLI)
    {
        DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n!CLI:recieved error message!");
        MT_ERRLOG(0);
        return ;
    }
    DBG_Out(PID_CLI, EN_DBG_OUT_CHN_31,
            "\r\n CLI_ProcessMsg:: Received msg (Code:%x)", pMsg->usMsgCode);

    switch (pMsg->usSrcPid)
    {
        case PID_DEBUG:
            if( G_NULL != g_pfn_CFG_CLI_CmdTestProc )
            {
                pDbgMsg = (ST_DBG_MSG *)&( pMsg->ucData[pMsg->usDataOffset] );
                (_VOID)g_pfn_CFG_CLI_CmdTestProc(pDbgMsg);
            }
            break;

        case PID_ROS_TIMER:
            pstNotify = (ST_TIMER_NOTIFY_MSG*)&( pMsg->ucData[pMsg->usDataOffset]);
            if (pstNotify->TimerId == m_CliSecTimer)
            {
                CLI_PeriodProc();
            }
            break;

    #if MULTI_DEVICE_SUPPORT
    /* 主从设备命令行之间的交互消息 */
        case PID_AGENT:
            // here no break
        case PID_CLI:
            if (pMsg->usSrcPid == PID_CLI)
            {
                pstMsCliMsg = (PST_MSCLI_MSG)&( pMsg->ucData[pMsg->usDataOffset]);

                if (!CLI_IS_TERMID_VALIDE(pstMsCliMsg->ucTermID))
                {
                    CLI_RECORD(CLI_STAT_RECEIVED_UNWANTED);
                    DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n!  CLI:recieved error message from other device!");
                    break;
                }

                pTermStruct = m_TDTable[pstMsCliMsg->ucTermID - 1].pTermStruct;
            }
            else
            {
                pNmsMsg = (PNMS_MSG_S)&( pMsg->ucData[pMsg->usDataOffset]);
                pstMsCliMsg = (PST_MSCLI_MSG)pNmsMsg->ucData;
                pTermStruct = m_TDTable[1].pTermStruct; // 网管分配的终端为第二个
            }

            switch (pMsg->usMsgCode)
            {
                /* 接收透传上层设备下发的透传命令 */
                case MSG_CODE_AGENT_SEND_CMD:
                case MSG_CODE_CLI_TRANSCMD:
                    /* 如果该终端的接收状态不正确,直接返回 */
                    if (pTermStruct->iSocket != SOCKET_FOR_MML || pTermStruct->ucTermStatus != TERM_LOGED)
                    {
                        DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                                "\r\n CLI: Term %d cannot process this command",pTermStruct->ulTermId);
                        break;
                    }

                    /* 如果命令超长,直接返回 */
                    if (EOS_StrLen((_S8 *)(pstMsCliMsg->ucData)) > CT_MAX_CMDBUF)
                    {
                        DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                                "\r\n CLI: Term %d received too long Command:\r\n    %s",pTermStruct->ulTermId,  pTermStruct->szRecvBuf);
                        break;
                    }

                    /* 设置该终端的语种与上层终端一致 */
                    ML_SetLanguage(pTermStruct->ulTermId, pstMsCliMsg->ucLan);

                    /* 从消息包中接收命令串 */
                    EOS_StrNCpy(pTermStruct->szRecvBuf, (_S8 *)(pstMsCliMsg->ucData), TERM_IO_BUFFER);
                    if (pTermStruct->ulTermId == 2)
                        EOS_StrCat(pTermStruct->szRecvBuf, "\r\n");
                    pTermStruct->iRecvLen = (_S32)EOS_StrLen(pTermStruct->szRecvBuf);

                    /* 注意命令的执行必须告知模式,否则无法使用现有命令解释机制 */
                    pTermStruct->pWS->ulCurrentMode =
                            (_U32)(pstMsCliMsg->ucMode < CTM_TOTAL ? pstMsCliMsg->ucMode: 0);

                    DBG_Out(PID_CLI, CLI_DBGOUT_NOTE,
                            "\r\n CLI: Term %d received Command:%s",pTermStruct->ulTermId,  pTermStruct->szRecvBuf);
                    break;

                case MSG_CODE_CLI_FEEDBACK:
                    /* 接收反馈信息的终端状态不正确,直接返回 */
                    if (pTermStruct->ucTermStatus != TERM_WAIT_RESPONSE)
                    {
                        DBG_Out(PID_CLI, CLI_DBGOUT_NOTE,
                                "\r\n CLI: Term %d Cannot Output the feedback info",pstMsCliMsg->ucTermID);
                    }
                    else if ((EOS_StrLen(pTermStruct->szSendBuf) + EOS_StrLen((_S8*)(pstMsCliMsg->ucData)))
                       < (TERM_IO_BUFFER - TERM_OUT_FOR_RESPONSE))
                    {
                        /* 复制反馈内容到发送缓冲区 */
                        DBG_Out(PID_CLI, CLI_DBGOUT_NOTE,
                                "\r\n CLI: Term %d received Output info:%s",pstMsCliMsg->ucTermID,  pTermStruct->szSendBuf);
                        /* 注意: 应当保证从此处到该信息的输出之前不调用IO_OutToTerm */
                        EOS_StrCat(pTermStruct->szSendBuf, (_S8*)(pstMsCliMsg->ucData));
                        pTermStruct->iSendLen = (_S32)EOS_StrLen(pTermStruct->szSendBuf);
                    }
                    break;

                case MSG_CODE_CLI_EXECRESP:
                    if (pTermStruct->ucTermStatus == TERM_WAIT_RESPONSE)
                    {
                        DBG_Out(PID_CLI, CLI_DBGOUT_NOTE,
                                "\r\n CLI: Term %d received excute response",pstMsCliMsg->ucTermID,  pTermStruct->szSendBuf);
                        /* 注意: 应当保证从此处到该信息的输出之前不调用IO_OutToTerm */
                        EOS_StrCat(pTermStruct->szSendBuf, CMD_RESPONED_END);
                        break;
                    }
                    //else分支直接往下走

                default:
                    CLI_RECORD(CLI_STAT_RECEIVED_UNWANTED);
                    DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                            "\r\n CLI: No process for message:Code-%d!", pMsg->usMsgCode);
                    break;
            }
            break;
        #endif

        default:
            CLI_RECORD(CLI_STAT_RECEIVED_UNWANTED);
            DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                    "\r\n CLI: No process for message from PID:%d!", pMsg->usSrcPid);
            break;
    }
}

#if MULTI_DEVICE_SUPPORT
/*==================================================================*/
/*      函数名      :CLI_MSMsgCreat                                 */
/*      函数功能    :主从命令的消息构建函数                         */
/*      输入参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      输出参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      返回值      :无                                             */
/*      调用函数    :无                                             */
/*      备注        :环境变量的初始化不在该函数中进行               */
/*==================================================================*/
ST_MSG* CLI_MSMsgCreat(_U32 usDeviceID, _U32 ulTermID, _U16 usMSmsgType, _S8 *szSend)
{
    _U32 ulSize;
    PST_MSCLI_MSG pstCliMsg;
    ST_MSG       *pstMsg;

    if (szSend == G_NULL)
        ulSize = sizeof(ST_MSCLI_MSG);
    else
        ulSize = sizeof(ST_MSCLI_MSG) + EOS_StrLen(szSend);

    pstMsg = ROS_MsgAlloc(PUBLIC_LENS_TOTAL + ulSize, ROS_MSG_ALLOC_OPT_LEAK_CHECK );
    if (pstMsg == G_NULL)
    {
        DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n  CLI(error return): CLI_MSMsgCreat:: ROS_MsgAlloc");
        MT_ERRLOG(0);
        return G_NULL;
    }

    /* 填充消息包的内容 */
    pstMsg->usSrcBid        = g_usTransLocalBID;
    pstMsg->usDstBid        = g_usTransLocalBID;
    pstMsg->usSrcPid        = PID_CLI;
    pstMsg->usDstPid        = PID_CLI;
    pstMsg->usMsgCode       = usMSmsgType;

    pstMsg->usDataOffset    = 0;
    pstMsg->usDataLens      = (_U16)ulSize;

    pstCliMsg = (PST_MSCLI_MSG)&( pstMsg->ucData[pstMsg->usDataOffset] );

    pstCliMsg->ucLan         = ML_GetLanguage(ulTermID);

    /* 由于主从命令行的终端ID不是完全对应的,因此需要作算术映射 */
    if (m_CliIsMainDevice != G_TRUE && ulTermID >= 2)
        ulTermID -= 2;
    else if (m_CliIsMainDevice == G_TRUE)
        ulTermID += 2;

    pstCliMsg->ucTermID      = (_U8)ulTermID;

    if (szSend != G_NULL)
        EOS_StrCpy((_S8 *)(pstCliMsg->ucData), szSend);

    return pstMsg;
}
#endif

/*********************************************************************/
/* 函数名称 : CLI_CfgGlbVarInit()                                    */
/* 函数功能 : 与配置相关的模块变量的初始化                           */
/* 输入参数 :                                                        */
/* 输出参数 :                                                        */
/* 返回     :                                                        */
/* 上层函数 : CLI_ConfigInit()                                       */
/* 创建者   :                                                        */
/* 修改记录 :                                                        */
/*********************************************************************/
_U32 CLI_CfgGlbVarInit( _VOID )
{
    _U32                i, ulSize;
    _U8                *pucMem;

    /* 命令行最大在线用户个数( 最前两个分别为串口任务和MML终端的服务器端, 保留 ) */
    m_ulCliMaxOnlineUser = 2 + g_ul_CFG_CLI_MAX_TELNET_CLIENT_NUM;

    #if MULTI_DEVICE_SUPPORT
    {

⌨️ 快捷键说明

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