?? cli_termtelnet.c
字號:
/************************************************************************
Copyright 200X - 200X+1.
filename : CLI_Term.c
description : 1、實現(xiàn)命令行操作終端的任務(wù)管理
2、終端任務(wù)數(shù)據(jù)中的字符串編輯緩沖的處理
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 初始化標(biāo)志 只在本文件使用*/
static _U32 m_ulTelnetInitFlag = G_FALSE;
/*==================================================================*/
/* 函數(shù)名 :CLI_TelnetTasksCreat */
/* 函數(shù)功能 :創(chuàng)建與Telnet相關(guān)的任務(wù). */
/* 輸入?yún)?shù) :無 */
/* 輸出參數(shù) :無 */
/* 返回值 :_U32 0: 初始化成功 1: 初始化失敗 */
/* 被調(diào)函數(shù) : */
/*==================================================================*/
_U32 CLI_TelnetTasksCreat(_VOID)
{
_U32 ulRet;
_U32 ulArg[2] = {0, 0};
_U32 ulTaskID;
_U32 i;
_S8 szTaskName[32];
/* telnet服務(wù)器任務(wù)創(chuàng)建 */
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: 第一個任務(wù)為命令透傳處理任務(wù)(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;
}
/*==================================================================*/
/* 函數(shù)名 :CLI_TelnetServerInit */
/* 函數(shù)功能 :初始化telnet連接 */
/* 輸入?yún)?shù) :無 */
/* 輸出參數(shù) :無 */
/* 返回值 :_U32 0: 初始化成功 1: 初始化失敗 */
/* 被調(diào)函數(shù) : */
/*==================================================================*/
_U32 CLI_TelnetServerInit (_S32 *iSocketServer)
{
struct sockaddr_in sServerAddr ;
/* 創(chuàng)建一TCP socket連接 */
if ( ( *iSocketServer = socket ( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
{
MT_ERRLOG(0);
return G_FAILURE ;
}
/* 設(shè)置服務(wù)器端端口,并與套接字綁定 */
memset ( ( _VOID * )&sServerAddr, 0, sizeof(sServerAddr) ) ;
sServerAddr.sin_family = AF_INET ; /* TCP - 數(shù)據(jù)流 */
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狀態(tài)機 */
if(m_ulTelnetInitFlag == G_FALSE)
{
CLI_FsmBuild ( ) ;
m_ulTelnetInitFlag = G_TRUE;
}
return G_SUCCESS ;
}
/*********************************************************************/
/* 函數(shù)名稱 : CLI_TelnetInit() */
/* 函數(shù)功能 : telnet任務(wù)初始化函數(shù) */
/* 輸入?yún)?shù) : pTermStruct telnet終端任務(wù)數(shù)據(jù) */
/* 輸出參數(shù) : pTermStruct telnet終端任務(wù)數(shù)據(jù) */
/* 返回 : 成功/失敗 */
/* 上層函數(shù) : */
/* 創(chuàng)建者 : */
/* 修改記錄 : */
/*********************************************************************/
_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選項, 默認應(yīng)該關(guān)閉, 即 iOptVal = 0 */
iOptVal = 0 ;
iOptLen = sizeof ( iOptLen ) ;
setsockopt ( pTermStruct->iSocket, IPPROTO_TCP, 0x01, ( _S8 * ) & iOptVal, iOptLen ) ;
CLI_NegotiateOption ( pTermStruct) ;
return G_SUCCESS;
}
/*==================================================================*/
/* 函數(shù)名 :CLI_TelnetServer */
/* 函數(shù)功能 :Telnet Server任務(wù)函數(shù)體 */
/* 輸入?yún)?shù) :無 */
/* 輸出參數(shù) :無 */
/* 返回值 :無 */
/* 被調(diào)函數(shù) : */
/*==================================================================*/
_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訪問允許列表內(nèi))*/
#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 ;
}
/* 激活該任務(wù)的狀態(tài) */
m_TDTable[ulCount].pTermStruct->iSocket = iSocket;
m_TDTable[ulCount].pTermStruct->ulClientIP = sClientAddr.sin_addr.s_addr;
CLI_SetTermStatus(m_TDTable[ulCount].pTermStruct, TERM_ACTIVE);
}
}
/*==================================================================*/
/* 函數(shù)名 :CLI_ReceiveFromTelnet */
/* 函數(shù)功能 :從telnet客戶端接收數(shù)據(jù) */
/* 輸入?yún)?shù) :pTermStruct 任務(wù)數(shù)據(jù) */
/* ulSecond 接收超時時間 */
/* 輸出參數(shù) :無 */
/* 返回值 :無 */
/*==================================================================*/
_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客戶端的數(shù)據(jù) */
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 ;
}
/*==================================================================*/
/* 函數(shù)名 :CLI_SendToTelnet */
/* 函數(shù)功能 :向telnet客戶端發(fā)送數(shù)據(jù) */
/* 輸入?yún)?shù) :PTerm_Data_S pTermStruct 任務(wù)數(shù)據(jù) */
/* PTerm_Data_S pTermStruct 任務(wù)數(shù)據(jù) */
/* 輸出參數(shù) :無 */
/* 返回值 :_U32 0: 發(fā)送成功 1: 發(fā)送失敗 */
/* 被調(diào)函數(shù) : */
/*==================================================================*/
_U32 CLI_SendToTelnet ( PTerm_Data_S pTermStruct )
{
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -