📄 cli_termtelnet.c
字号:
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 + -