📄 cli_io.c
字号:
/************************************************************************
Copyright 200X - 200X+1.
filename : CLI_Io.c
description : 本文件实现主机软件基本的输入输出,对外提供统一的接口;
在实现上依赖终端数据,终端的输入输出功能。
author : Woodhead
modification : Woodhead create 2004-12-07
************************************************************************/
#include "Ros.h"
#include "ML.h"
#include "Sys_Ml.h"
#include "Cli_MlPriv.h"
#include "Cli_Private.inc"
#include "Cli_intp.inc"
#include "..\include\Cli_io.h"
#include "CLI_User.inc"
/* 异步输出控制结构,只在本文件中使用 */
static ASYNDISPLAY__S m_DispBase;
static _U8 m_CLIucScroll = SCROLL_MANUAL;
#define IO_FORMAT_STRING(ulTermID, ulInfoID, ulLen) \
{ \
pFormat = ML_GetString(ulTermID, ulInfoID); \
if (pFormat == G_NULL || EOS_StrLen(pFormat) > ulLen - 200) \
{ \
CLI_RECORD(CLI_STAT_OUTPUT_TOO_LONG); \
MT_ERRLOG(0); \
return G_FAILURE; \
} \
va_start(arglist, ulInfoID) ; \
if (vsprintf(szOutPut, pFormat, arglist) >= ulLen) \
{ \
CLI_RECORD(CLI_STAT_OUTPUT_TOO_LONG); \
return G_FAILURE; \
} \
szOutPut[(ulLen) - 1] = '\0'; \
va_end(arglist) ; \
}
/* 如果终端是web终端, 返回失败 */
#define RET_FAILURE_IF_IS_WEB_TERM( ulTermID ) \
{ \
if( IS_WEB_TERMID(ulTermID) ) \
{ \
DBG_ASSERT(0); \
return G_FAILURE; \
} \
}
/*-------------------------------------------------------------------*/
/* 函数名称 : IO_PrintToTerm */
/* 功 能 : 将格式化串输出到指定终端 */
/* 输入参数 : ulTermID:终端ID */
/* ulInfoID:语种资源ID */
/* 输出参数 : 无 */
/* 返回值 : 成功、失败 */
/* 调用说明 : 调用本函数需要确保ulInfoID在语种资源中已经有定义,且该 */
/* 资源字符串的最长不得超过2K */
/* 典型示例 : IO_PrintToTerm(1, CLI_LOG_FAILED_TIME,3) */
/* 其中CLI_LOG_FAILED_TIME 对于中文语种信息为: */
/* "\r\n 你已连续登录失败%d次! " */
/*-------------------------------------------------------------------*/
_U32 IO_PrintToTerm(_U32 ulTermID, _U32 ulInfoID, ...)
{
_S8 szOutPut[OUTB_DIRRECT_LENTGH] = "";
const _S8 *pFormat;
PTerm_Data_S pTermStruct;
va_list arglist ;
#if ( CLI_WEB_SUPPORT == G_YES )
RET_FAILURE_IF_IS_WEB_TERM(ulTermID);
#endif
CLI_ASSURE_OR_FAIL(CLI_IS_TERMID_VALIDE(ulTermID));
/* 格式化串的组织 */
IO_FORMAT_STRING(ulTermID, ulInfoID, OUTB_DIRRECT_LENTGH);
pTermStruct = m_TDTable[ulTermID - 1].pTermStruct;
return IO_OutToTerm(pTermStruct, szOutPut);
}
/*-------------------------------------------------------------------*/
/* 函数名称 : IO_Print */
/* 功 能 : 将格式化串输出到当前终端 */
/* 输入参数 : ulInfoID 多语种资源ID */
/* 输出参数 : 无 */
/* 返回值 : 成功、失败 */
/* 调用说明 : 调用本函数需要确保ulInfoID在语种资源中已经有定义,且该 */
/* 资源字符串的最长不得超过2K */
/* 典型示例 : IO_Print(CLI_LOG_FAILED_TIME,3) */
/* 其中CLI_LOG_FAILED_TIME 对于中文语种信息为: */
/* "\r\n 你已连续登录失败%d次! " */
/*-------------------------------------------------------------------*/
_U32 IO_Print(_U32 ulInfoID, ...)
{
_S8 szOutPut[OUTB_DIRRECT_LENTGH] = "";
const _S8 *pFormat;
PTerm_Data_S pTermStruct;
_U32 ulTermID;
va_list arglist ;
if ((pTermStruct = CLI_GetCurrentTaskData()) == G_NULL)
return G_FAILURE;
if (pTermStruct->ulDispLineCount == CLI_INVALID
&& pTermStruct->ucTermStatus == TERM_EXECCMD)
return G_SUCCESS;
ulTermID = pTermStruct->ulTermId;
/* 格式化串的组织 */
IO_FORMAT_STRING(ulTermID, ulInfoID, OUTB_DIRRECT_LENTGH);
return IO_OutToTerm(pTermStruct, szOutPut);
}
/*-------------------------------------------------------------------*/
/* 函数名称 : IO_PrintToAllTerm */
/* 功 能 : 将格式化串输出到所有终端 */
/* 输入参数 : ulInfoID 多语种资源ID */
/* 输出参数 : 无 */
/* 返回值 : 成功、失败 */
/* 调用说明 : 暂不对外提供 */
/*-------------------------------------------------------------------*/
_U32 IO_PrintToAllTerm(_U32 ulInfoID, ...)
{
_S8 szOutPut[OUTB_DIRRECT_LENTGH] = "";
const _S8 *pFormat;
PTerm_Data_S pTermStruct;
_U32 ulTermID;
_U32 ulRet = G_FAILURE;
va_list arglist ;
for (ulTermID = 1; ulTermID <= m_ulCliMaxOnlineUser; ulTermID ++)
{
pTermStruct = m_TDTable[ulTermID-1].pTermStruct;
/* 仅输出到用户正确登录的终端 */
if (pTermStruct->ucTermStatus < TERM_LOGED)
continue;
/* 格式化串的组织 */
IO_FORMAT_STRING(ulTermID, ulInfoID, OUTB_DIRRECT_LENTGH);
if (IO_OutToTerm(pTermStruct, szOutPut) == G_SUCCESS)
ulRet = G_SUCCESS; //只要发送到一个终端成功即告成功
}
return ulRet;
}
/*-------------------------------------------------------------------*/
/* 函数名称 : IO_SendToTerm */
/* 功 能 : 将格式化串输出到当前终端 */
/* 输入参数 : ulTermID:终端ID,ulInfoID 语种信息ID */
/* 输出参数 : 无 */
/* 返回值 : 成功、失败 */
/* 调用说明 : 调用本函数需要确保ulInfoID在语种资源中已经有定义,且该 */
/* 资源字符串的最长不得超过1K. 该函数的返回值仅表示发送到 */
/* 异步输出队列的成功与失败,并不表示输出的正常与否 */
/* 典型示例 : IO_PrintToTerm(1, CLI_LOG_FAILED_TIME,3) */
/* 其中CLI_LOG_FAILED_TIME 对于中文语种信息为: */
/* "\r\n 你已连续登录失败%d次! " */
/*-------------------------------------------------------------------*/
_U32 IO_SendToTerm(_U32 ulTermID, _U32 ulInfoID, ...)
{
_S8 szOutPut[OUTBUFF_LENGTH] = "";
const _S8 *pFormat;
va_list arglist ;
#if ( CLI_WEB_SUPPORT == G_YES )
RET_FAILURE_IF_IS_WEB_TERM(ulTermID);
#endif
CLI_ASSURE_OR_FAIL(CLI_IS_TERMID_VALIDE(ulTermID));
/* 格式化串的组织 */
IO_FORMAT_STRING(ulTermID, ulInfoID, OUTBUFF_LENGTH);
return IO_InsertDispInfo(ulTermID, szOutPut);
}
/*-------------------------------------------------------------------*/
/* 函数名称 : IO_SendToAllTerm */
/* 功 能 : 将格式化串异步输出到所有终端 */
/* 输入参数 : ulInfoID 多语种资源ID */
/* 输出参数 : 无 */
/* 返回值 : 成功、失败 */
/* 调用说明 : 调用本函数需要确保ulInfoID在语种资源中已经有定义,且该 */
/* 资源字符串的最长不得超过1K. 该函数的返回值仅表示发送到 */
/* 异步输出队列的成功与失败,并不表示输出的正常与否 */
/* 典型示例 : IO_SendToAllTerm(CLI_LOG_FAILED_TIME,3) */
/* 其中CLI_LOG_FAILED_TIME 对于中文语种信息为: */
/* "\r\n 你已连续登录失败%d次! " */
/*-------------------------------------------------------------------*/
_U32 IO_SendToAllTerm(_U32 ulInfoID, ...)
{
_S8 szOutPut[OUTBUFF_LENGTH];
const _S8 *pFormat;
_U32 ulTermID, ulRet = 0;
va_list arglist ;
PTerm_Data_S pTermStruct;
for (ulTermID = 1; ulTermID <= m_ulCliMaxOnlineUser; ulTermID++)
{
//获取此结构指针只用来判断当前终端是否为MML,如果是,则不输出信息
pTermStruct = m_TDTable[ulTermID - 1].pTermStruct;
if(pTermStruct->iSocket != SOCKET_FOR_MML) //如果不是MML连接方式,才输出信息
{
/* 格式化串的组织 */
IO_FORMAT_STRING(ulTermID, ulInfoID, OUTBUFF_LENGTH);
ulRet &=IO_InsertDispInfo(ulTermID, szOutPut);
}
else
{
continue;
}
}
if (ulRet == G_SUCCESS)
{
return G_SUCCESS;
}
return G_FAILURE;
}
/*-------------------------------------------------------------------*/
/* 函数名称 : IO_OutString */
/* 功 能 : 直接输出字符串到当前终端 */
/* 输入参数 : szOutput 输出信息串 */
/* 输出参数 : 无 */
/* 返回值 : 成功、失败 */
/* 调用说明 : 直接输出,该函数的调用者多为调试信息输出与特殊要求的 */
/* 输出,如果当前任务非终端任务,则输出到串口 */
/* 典型示例 : IO_OutString("\r\n 正确输出.") */
/*-------------------------------------------------------------------*/
_U32 IO_OutString(const _S8 *szOutput)
{
PTerm_Data_S pTermStruct;
if ((pTermStruct = CLI_GetCurrentTaskData()) == G_NULL)
{
/*如果当前任务非终端任务,而串口已经登录,则打印到串口*/
pTermStruct = m_TDTable[0].pTermStruct;
if (pTermStruct->ucTermStatus < TERM_LOGED)
return G_FAILURE;
}
return IO_OutToTerm(pTermStruct, szOutput);
}
/*-------------------------------------------------------------------*/
/* 函数名称 : IO_OutString */
/* 功 能 : 直接输出字符串到调试终端 */
/* 输入参数 : szOutput 输出信息串 */
/* 输出参数 : 无 */
/* 返回值 : 成功、失败 */
/* 调用说明 : 该接口只提供给调试模块的调试输出使用 */
/* 典型示例 : IO_DebugOutString("\r\n 函数调用错误!") */
/*-------------------------------------------------------------------*/
_U32 IO_DebugOutString(_S8 *szOutput)
{
PTerm_Data_S pTermStruct;
CLI_ASSURE_OR_FAIL( szOutput != G_NULL);
/* 调试用户可能不在命令行终端, 可能从其他终端(如web网管)登录, 返回成功 */
if( ! CLI_IS_TERMID_VALIDE(m_sUserTable[0].ulTermId) )
{
return G_SUCCESS;
}
if (m_sUserTable[0].ucUserStatus >= TERM_LOGED)
pTermStruct = m_TDTable[m_sUserTable[0].ulTermId - 1].pTermStruct;
else
return G_FAILURE;
if (pTermStruct->ucTermStatus == TERM_WAIT_RESPONSE)
{
/* 如果终端处于等待从设备命令返回的阶段,不应有任何其它的输出干扰 */
return G_FAILURE;
}
return IO_OutToTerm(pTermStruct, szOutput);
}
/*********************************************************************/
/* 函数名称 : IO_InsertDispInfo() */
/* 函数功能 : 将准备输出的信息插入到输出队列 */
/* 输入参数 : ulTermID:终端ID, szOutput 输出的信息串 */
/* 输出参数 : 无 */
/* 返回 : 成功、失败 */
/* 上层函数 : */
/* 创建者 : */
/* 修改记录 : */
/*********************************************************************/
_U32 IO_InsertDispInfo(_U32 ulTermID, _S8 *szOutput)
{
struct AsynDisplay_Element_S *pAsynDispItem;
_S8 *pOutput;
PTerm_Data_S pTermStruct;
CLI_ASSURE_OR_FAIL(CLI_IS_TERMID_VALIDE(ulTermID) && szOutput != G_NULL);
/* 如果队列已满,新来信息不再入列,直接返回 */
if (CLI_INCCYCLE(m_DispBase.ulLastPos, ASYN_DISPLAY_NUM) == m_DispBase.ulFirstPos)
return G_FAILURE;
pTermStruct = m_TDTable[ulTermID - 1].pTermStruct;
/* 如果发送的目的终端尚未正确登录,取消发送 */
if (pTermStruct->ucTermStatus < TERM_LOGED || pTermStruct->ulTimeLeft == 0)
return G_FAILURE;
/* 为输出信息申请一块空间 */
pOutput = (_S8 *)ROS_MemAlloc(EOS_StrLen(szOutput) + 1, ROS_MEM_ALLOC_OPT_LEAK_CHECK);
if (pOutput == G_NULL)
{
MT_ERRLOG(0);
return G_FAILURE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -