📄 cli_init.c
字号:
/************************************************************************
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 + -