📄 cli_termtelnet.c
字号:
/************************************************************************
Copyright 200X - 200X+1.
filename : CLI_Term.c
description : 1、实现命令行操作终端的任务管理
2、终端任务数据中的字符串编辑缓冲的处理
author : Woodhead
modification : Woodhead create 2004-12-07
************************************************************************/
#include "Ros.h"
#include "CLI_Private.inc"
#include "CLI_Io.h"
#include "CLI_User.inc"
#include "CLI_Intp.inc"
#include "CLI_Telnet.inc"
#include "ML.h"
#include "Sys_Ml.h"
#include "Cli_MlPriv.h"
#include "cm_sock.h"
#include "Board_Pub.h"
#include "Config\Cli_ConfigGlbVar.h"
extern _VOID CLI_MMLTaskInit(PTerm_Data_S pTermStruct);
#if CLI_TELNET_SUPPORT
/*telnet server 初始化标志 只在本文件使用*/
static _U32 m_ulTelnetInitFlag = G_FALSE;
/*==================================================================*/
/* 函数名 :CLI_TelnetTasksCreat */
/* 函数功能 :创建与Telnet相关的任务. */
/* 输入参数 :无 */
/* 输出参数 :无 */
/* 返回值 :_U32 0: 初始化成功 1: 初始化失败 */
/* 被调函数 : */
/*==================================================================*/
_U32 CLI_TelnetTasksCreat(_VOID)
{
_U32 ulRet;
_U32 ulArg[2] = {0, 0};
_U32 ulTaskID;
_U32 i;
_S8 szTaskName[32];
/* telnet服务器任务创建 */
ulRet = ROS_SelfTaskCreate(PID_CLI, "CLI_TASK_TELSERVER",
EN_ROS_TASK_PRIORITY_NORMAL,
ROS_TASK_STACK_SIZE_DEFAULT,
ulArg, CLI_TelnetServer, &ulTaskID);
CLI_ASSURE_OR_FAIL(ulRet == G_SUCCESS);
/* Note: 第一个任务为命令透传处理任务(MML) */
/* ??? LingJian_Tailor */
#if 0
ulArg[0] = 1;
EOS_Sprintf(szTaskName, "CLI_TASK_TEL%d", i);
ulRet = ROS_SelfTaskCreate(PID_CLI, szTaskName,
EN_ROS_TASK_PRIORITY_NORMAL,
ROS_TASK_STACK_SIZE_DEFAULT,
ulArg, CLI_TelnetTask, &ulTaskID );
CLI_ASSURE_OR_FAIL(ulRet == G_SUCCESS);
#endif
for (i = FIRST_TELNET_DATA; i < m_ulCliMaxOnlineUser; i++)
{
ulArg[0] = i;
EOS_Sprintf(szTaskName, "CLI_TASK_TEL%d", i);
ulRet = ROS_SelfTaskCreate(PID_CLI, szTaskName,
EN_ROS_TASK_PRIORITY_NORMAL,
ROS_TASK_STACK_SIZE_DEFAULT,
ulArg, CLI_TelnetTask, &ulTaskID );
CLI_ASSURE_OR_FAIL(ulRet == G_SUCCESS);
}
return G_SUCCESS;
}
/*==================================================================*/
/* 函数名 :CLI_TelnetServerInit */
/* 函数功能 :初始化telnet连接 */
/* 输入参数 :无 */
/* 输出参数 :无 */
/* 返回值 :_U32 0: 初始化成功 1: 初始化失败 */
/* 被调函数 : */
/*==================================================================*/
_U32 CLI_TelnetServerInit (_S32 *iSocketServer)
{
struct sockaddr_in sServerAddr ;
/* 创建一TCP socket连接 */
if ( ( *iSocketServer = socket ( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
{
MT_ERRLOG(0);
return G_FAILURE ;
}
/* 设置服务器端端口,并与套接字绑定 */
memset ( ( _VOID * )&sServerAddr, 0, sizeof(sServerAddr) ) ;
sServerAddr.sin_family = AF_INET ; /* TCP - 数据流 */
sServerAddr.sin_port = (_U16)htons(TELNETPORT); /* Telnet 端口号 23 */
sServerAddr.sin_addr.s_addr = (_U32)htonl(INADDR_ANY) ; /* 任意客户IP地址 */
if ( bind ( *iSocketServer, ( struct sockaddr * )&sServerAddr,
sizeof( sServerAddr ) ) != 0 )
{
urp_close(*iSocketServer);
MT_ERRLOG(0);
return G_FAILURE ;
}
/* 侦听TELNET CLIENT的连接请求 */
if ( listen ( *iSocketServer, (int)g_ul_CFG_CLI_MAX_TELNET_CLIENT_NUM) != 0 )
{
urp_close(*iSocketServer);
MT_ERRLOG(0);
return G_FAILURE ;
}
/* 建立TELNET状态机 */
if(m_ulTelnetInitFlag == G_FALSE)
{
CLI_FsmBuild ( ) ;
m_ulTelnetInitFlag = G_TRUE;
}
return G_SUCCESS ;
}
/*********************************************************************/
/* 函数名称 : CLI_TelnetInit() */
/* 函数功能 : telnet任务初始化函数 */
/* 输入参数 : pTermStruct telnet终端任务数据 */
/* 输出参数 : pTermStruct telnet终端任务数据 */
/* 返回 : 成功/失败 */
/* 上层函数 : */
/* 创建者 : */
/* 修改记录 : */
/*********************************************************************/
_U32 CLI_TelnetInit(PTerm_Data_S pTermStruct)
{
_S32 iOptVal,iOptLen;
iOptVal = 1 ;
iOptLen = sizeof ( iOptLen ) ;
setsockopt ( pTermStruct->iSocket, SOL_SOCKET, SO_OOBINLINE, ( _S8 * ) & iOptVal,iOptLen ) ;
/* telnet server的TCP_NODELAY选项, 默认应该关闭, 即 iOptVal = 0 */
iOptVal = 0 ;
iOptLen = sizeof ( iOptLen ) ;
setsockopt ( pTermStruct->iSocket, IPPROTO_TCP, 0x01, ( _S8 * ) & iOptVal, iOptLen ) ;
CLI_NegotiateOption ( pTermStruct) ;
return G_SUCCESS;
}
/*==================================================================*/
/* 函数名 :CLI_TelnetServer */
/* 函数功能 :Telnet Server任务函数体 */
/* 输入参数 :无 */
/* 输出参数 :无 */
/* 返回值 :无 */
/* 被调函数 : */
/*==================================================================*/
_VOID CLI_TelnetServer( _U32 ulArg1, _U32 ulArg2)
{
struct sockaddr_in sClientAddr ;
_S32 iSocket;
_S32 iNameLen, iSocketServer;
_U32 ulCount;
_S8 szTelnetIp[20];
(_VOID)ulArg1;
(_VOID)ulArg2;
/*--------------------------------------------------------------*/
/* 初始化telnet sever */
/*--------------------------------------------------------------*/
while ( CLI_TelnetServerInit(&iSocketServer) != G_SUCCESS )
{
DBG_Out(PID_CLI, CLI_DBGOUT_NOTE, "\r\n CLI: TelnetServer Initial failed!");
CLI_DELAY(200);
}
iNameLen = sizeof( sClientAddr ) ;
for ( ; ; )
{
/* 等待接收telnet client的连接 */
if( ( iSocket = accept( (int)iSocketServer, ( struct sockaddr * )&sClientAddr,
(int*)&iNameLen ) ) <= 0 )
{
CLI_DELAY(10);
continue ;
}
_IPAddrToStr(sClientAddr.sin_addr.s_addr, &szTelnetIp[0]) ;
DBG_Out(PID_CLI, MT_DBGOUT_NOTE,
"\r\n CLI: 客户端 %s 连接到本机.", szTelnetIp);
/* 检验客户端ip地址的合法性(是否在telnet访问允许列表内)*/
#if MULTI_DEVICE_SUPPORT
if (m_CliIsMainDevice == G_TRUE)
#endif
if( CLI_AclCheck(sClientAddr.sin_addr.s_addr) != G_SUCCESS )
{
IO_SendToAllTerm(CLI_TELNET_CLIENT_REFUSED, szTelnetIp);
CLI_DELAY(200);
urp_close ( iSocket ) ;
continue ;
}
for(ulCount = FIRST_TELNET_DATA; ulCount < m_ulCliMaxOnlineUser; ulCount++)
{
if (m_TDTable[ulCount].pTermStruct->ucTermStatus == TERM_SLEEPING
&& m_TDTable[ulCount].pTermStruct->iSocket == SOCKET_NOT_INITIAL)
break;
}
if(ulCount == m_ulCliMaxOnlineUser)
{
send ( (int)iSocket, (char *)"\n\r Too many telnet users!", 26, 0 ) ;
CLI_DELAY(100);
urp_close ( iSocket ) ;
continue ;
}
/* 激活该任务的状态 */
m_TDTable[ulCount].pTermStruct->iSocket = iSocket;
m_TDTable[ulCount].pTermStruct->ulClientIP = sClientAddr.sin_addr.s_addr;
CLI_SetTermStatus(m_TDTable[ulCount].pTermStruct, TERM_ACTIVE);
}
}
/*==================================================================*/
/* 函数名 :CLI_ReceiveFromTelnet */
/* 函数功能 :从telnet客户端接收数据 */
/* 输入参数 :pTermStruct 任务数据 */
/* ulSecond 接收超时时间 */
/* 输出参数 :无 */
/* 返回值 :无 */
/*==================================================================*/
_U32 CLI_ReceiveFromTelnet ( PTerm_Data_S pTermStruct, _U32 ulSecond)
{
fd_set SocketSet ;
struct timeval stWait ;
_S32 lErr =0;
if ( G_NULL == pTermStruct || ulSecond > DEADLINE_SHORT)
{
CLI_RECORD(CLI_STAT_RECEIVE_ERR);
return G_FAILURE ;
}
stWait.tv_usec = 0 ;
stWait.tv_sec = (_S32)ulSecond;
FD_ZERO ( &SocketSet ) ;
FD_SET ( (_U32)pTermStruct->iSocket, &SocketSet ) ;
CLI_RECORD(CLI_STAT_CLIENT_GOTO_SELECT);
lErr = urp_select ( FD_SETSIZE, &SocketSet, ( fd_set * ) 0, ( fd_set * ) 0, &stWait );
CLI_RECORD(CLI_STAT_CLIENT_OVER_SELECT);
if ( lErr > 0 )
{
/* 接收来自telnet客户端的数据 */
FD_ZERO ( &SocketSet ) ;
if (TERM_SEM_P(pTermStruct))
{
CLI_RECORD(CLI_STAT_SEM_P);
return G_FAILURE;
}
CLI_RECORD(CLI_STAT_CLIENT_GOTO_RECV);
pTermStruct->iRecvLen = recv ( pTermStruct->iSocket, pTermStruct->szRecvBuf, TERM_IO_BUFFER, 0) ;
CLI_RECORD(CLI_STAT_CLIENT_OVER_RECV);
if(TERM_SEM_V(pTermStruct))
{
CLI_RECORD(CLI_STAT_SEM_V);
DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n Sem_P of Term %d Failed!", pTermStruct->ulTermId);
}
if (pTermStruct->iRecvLen> 0 )
{
return G_SUCCESS ;
}
DBG_Out(PID_CLI, CLI_DBGOUT_NOTE, "\r\n CLI_ReceiveFromeTelnet:: recv() Failed!");
}
else if(lErr == 0)
{
CLI_RECORD(CLI_STAT_CLIENT_RECV_TIMEOUT);
return G_FAILURE;
}
CLI_SetTermStatus(pTermStruct, TERM_SLEEPING);
CLI_RECORD(CLI_STAT_CLIENT_RECV_CLOSED);
return G_FAILURE ;
}
/*==================================================================*/
/* 函数名 :CLI_SendToTelnet */
/* 函数功能 :向telnet客户端发送数据 */
/* 输入参数 :PTerm_Data_S pTermStruct 任务数据 */
/* PTerm_Data_S pTermStruct 任务数据 */
/* 输出参数 :无 */
/* 返回值 :_U32 0: 发送成功 1: 发送失败 */
/* 被调函数 : */
/*==================================================================*/
_U32 CLI_SendToTelnet ( PTerm_Data_S pTermStruct )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -