?? message.cpp
字號:
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003, Ulink Telecom Equipment Co., Ltd. All rights reserved.
//
// File:
//
// Message.cpp
//
// Abstract:
//
// implementation of the CMessage class.
//
// History:
//
// V1.0 2002-12-17 Alex Duan Original version.
// V1.1 2003-07-25 Alex Duan Add session for every connection
// V1.2 2003-09-01 Alex Duan Fixed the Receive's bug: overflow possibly.
// V1.3 2003-10-29 Alex Duan Add UARTSETTING for two uart ports
// V1.4 2003-11-12 Alex Duan Replace >>/<< with OnSaveData/OnLoadData
// V1.5 2004-01-29 Lianxi Zhu Save Level when user modified password
// Do not modify Level when user logout
// V1.6 2006-09-11 Bozhong Xu Rename SendHdlc to SendToHdlc
// Rename SendConsole to SendToConsole
// Rename SendHdlcQueue to PutMsgToHdlcQueue
// Rename GetHdlcQueue to GetMsgFromHdlcQueue
// Rename GetIsCurSocket to GetSocketIndex
// Rename GetUsableRes to GetUserIndex
// Modified IsLocalCmd implementation
// Modified RemoCommandTask implementation
// Add virtual function DisposeRemoteCmd
///////////////////////////////////////////////////////////////////////////////
#ifdef __EFC_MASTER // Added by xbz
#include "efc.h"
#include "Message.h"
#include "APPCORE.H"
#include "FlashFile.h"
#include "AsyInterface.h"
#include "SynInterface.h"
#include "LanInterface.h"
#include "OptInterface.h"
#include "fal.h"
#include "tftpdefc.h"
#include "tftpextc.h"
#include "xyModem.h"
extern "C"
{
// the following two functions are used to reset (defined in init.s)
void INT_Initialize(void); // restart from current code of DRAM
void Reset_Handler(void); // restart from code of FLASH
}
///////////////////////////////////////////////////////////////////////////////
// CMessage
IMPLEMENT_DYNAMIC(CMessage, CRTObject)
///////////////////////////////////////////////////////////////////////////////
// System Limits : this limits only used in Message
#define LIUPORTCOUNT_MAX 8
#define BOARDCOUNT_MAX 16
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
UINT SESSION::nTimeout = 0;
CMessage::CMessage()
{
m_pcdDevice = GetApp()->GetDevice();
m_pceEventLog = GetApp()->GetEventLog();
m_pcuUser = GetApp()->GetUser();
m_pcqQueueRece = NULL;
m_pcqQueueSend = NULL;
memset(m_muUsers, 0, sizeof(m_muUsers));
//add by bella yu 2004/08/23
// m_bModerm_r = FALSE;
// m_bModerm_t = FALSE;
// InitModermStru();
// m_bConsole = TRUE;
// m_bUpbackApp = FALSE;
m_pBuff.dwSize = 0;
m_pBuff.puBuff = NULL;
m_pBuff.bEnd = FALSE;
// default uart setting
for (int i = 0; i < 2; i++)
{
m_usUart[i].uPort = i;
m_usUart[i].dwBaudRate = 9600;
m_usUart[i].uDataBits = 8;
m_usUart[i].uParity = 0;
m_usUart[i].uStopBits = 1;
}
ASSERT(m_pcdDevice);
ASSERT(m_pceEventLog);
ASSERT(m_pcuUser);
SetSectionString("Message");
m_dwLength = 0;
m_bModemUsing = FALSE;
}
CMessage::~CMessage()
{
}
///////////////////////////////////////////////////////////////////////////////
// Parameters:
// mRecv [in]MESSAGE object received.
// Return Value:
// TRUE if the message requires local disposing, other FALSE.
// Remarks:
// Does the command require local disposing?
BOOL CMessage::IsLocalCmd(const MESSAGE &mRecv) const
{// Modified by Bozhong Xu in 2007.5.17
ADDR aLocalAddr;
ASSERT(m_pcdDevice);
m_pcdDevice->GetAddr(aLocalAddr);
return ((mRecv.aDesAddr == aLocalAddr)
|| (mRecv.aDesAddr == mRecv.aSrcAddr)
|| (mRecv.uCmdID == CMD_MSGMODE));
}
///////////////////////////////////////////////////////////////////////////////
// Parameters:
//
// Return Value:
// TRUE : send to console
// FALSE: send to HDLC
// Remarks:
//
BOOL CMessage::IsReturnCmd(const MESSAGE &mSend) const
{
BOOL bRetVal = FALSE;
// ADDR aLocalAddr;
// ASSERT(m_pcdDevice);
// m_pcdDevice->GetAddr(aLocalAddr);
// if (mSend.uCmdID == CMD_MSGMODE || mSend.aDesAddr == aLocalAddr)
// bRetVal = TRUE;
if (mSend.aDesAddr == mSend.aSrcAddr)
bRetVal = TRUE;
return bRetVal;
}
///////////////////////////////////////////////////////////////////////////////
// Parameters:
// uByte The value to be received.
// rfFlag Receiving flag
// mRecv Received MESSAGE object.
// Return Values:
// TRUE if a full message has been received, otherwise FALSE.
// Remarks:
// Receive one byte data.
BOOL CMessage::Receive(BYTE uByte, SRecvFlag &rfFlag, MESSAGE &mRecv)
{
BOOL bRetVal = FALSE;
BYTE *arByte = (BYTE*)&mRecv;
if (rfFlag.nCount >= MESSAGE_HEADER_SIZE)
{// The MESSAGE_HEADER has been received.
WORD nNewLen = MAKEWORD(mRecv.uLength, mRecv.uPacket);
if (rfFlag.nCount == MESSAGE_HEADER_SIZE)
{
// Allocate memory for the data_field and check_sum of the message
ASSERT(MESSAGE_FRAME_SIZE <= nNewLen && nNewLen <= WORD_MAX);
if (mRecv.puData != NULL)
{
delete[] mRecv.puData;
mRecv.puData = NULL;
}
// if (nNewLen > MESSAGE_FRAME_SIZE)
// {// New length includes checksum and a byte of redundancy used when
// rfFlag.nCount == nNewLen but uByte != EOM.
mRecv.puData = new BYTE[nNewLen - MESSAGE_HEADER_SIZE + 1];
ASSERT(mRecv.puData);
// }
}
else if (rfFlag.nCount > nNewLen)
{// overflow
rfFlag.bStarted = FALSE;
rfFlag.bPrevSOM = FALSE;
rfFlag.nCount = 0;
}
arByte = mRecv.puData - MESSAGE_HEADER_SIZE;
}
if (uByte == SOM)
{
if (rfFlag.bStarted)
{// has started
if (rfFlag.bPrevSOM)
{
arByte[rfFlag.nCount++] = uByte;
rfFlag.bPrevSOM = FALSE;
}
else
{
rfFlag.bPrevSOM = TRUE;
}
}
else
{
rfFlag.bStarted = TRUE;
rfFlag.bPrevSOM = FALSE;
rfFlag.nCount = 0;
}
}
else if (rfFlag.bPrevSOM && uByte == EOM)
{
mRecv.uCheckSum = arByte[rfFlag.nCount - 1];
rfFlag.bStarted = FALSE;
rfFlag.bPrevSOM = FALSE;
rfFlag.nCount = 0;
bRetVal = TRUE;
}
else
{
///////////////////////////////////////////////////////////////////////
// new start_flag
if (rfFlag.bPrevSOM)
{
rfFlag.bStarted = FALSE; // Modified from TRUE by xbz in 2007.7.4
rfFlag.bPrevSOM = FALSE;
rfFlag.nCount = 0;
}
///////////////////////////////////////////////////////////////////////
if (rfFlag.bStarted)
{
arByte[rfFlag.nCount++] = uByte;
}
}
return bRetVal;
}
///////////////////////////////////////////////////////////////////////////////
// Parameters:
// mSend [in]Hold a frame of MESSAGE to be sent.
// Remarks:
// Send a frame of message from uart
#define uart_PutByte(ch) uart4510_PutByte(0, ch, TRUE)
void CMessage::UartSend(const MESSAGE &mSend) const
{
int i;
BYTE *pByte = (BYTE*)&mSend;
VERIFY(uart_PutByte(SOM));
for (i = 0; i < MESSAGE_HEADER_SIZE; i++)
{
if (*pByte == SOM)
{
VERIFY(uart_PutByte(SOM));
}
VERIFY(uart_PutByte(*pByte));
pByte++;
}
for (i = 0; i < mSend.GetDataLength(); i++)
{
if (mSend.puData[i] == SOM)
{
VERIFY(uart_PutByte(SOM));
}
VERIFY(uart_PutByte(mSend.puData[i]));
}
if (mSend.uCheckSum == SOM)
{
VERIFY(uart_PutByte(SOM));
}
VERIFY(uart_PutByte(mSend.uCheckSum));
VERIFY(uart_PutByte(SOM));
VERIFY(uart_PutByte(EOM));
}
///////////////////////////////////////////////////////////////////////////////
// Parameters:
// mSend [in]Hold a frame of MESSAGE to be sent.
// sockfd Socket descriptor.
// Remarks:
// Send a frame of message from net
#define net_PutByte(pch) NU_Send(sockfd, (char*)(pch), 1, 0)
void CMessage::NetSend(const MESSAGE &mSend, int sockfd) const
{
UINT i;
BYTE *pByte = (BYTE*)&mSend;
BYTE uSOM = SOM;
BYTE uEOM = EOM;
VERIFY(net_PutByte(&uSOM) == 1);
for (i = 0; i < MESSAGE_HEADER_SIZE; i++)
{
if (*pByte == SOM)
{
VERIFY(net_PutByte(&uSOM) == 1);
}
VERIFY(net_PutByte(pByte) == 1);
pByte++;
}
for (i = 0; i < mSend.GetDataLength(); i++)
{
if (mSend.puData[i] == SOM)
{
VERIFY(net_PutByte(&uSOM) == 1);
}
VERIFY(net_PutByte(&mSend.puData[i]) == 1);
}
if (mSend.uCheckSum == SOM)
{
VERIFY(net_PutByte(&uSOM) == 1);
}
VERIFY(net_PutByte(&mSend.uCheckSum) == 1);
VERIFY(net_PutByte(&uSOM) == 1);
VERIFY(net_PutByte(&uEOM) == 1);
}
// Dispose one frame of message
BOOL CMessage::DisposeCmd(SESSION &session)
{
MESSAGE &mSend = session.mSend; // MESSAGE to be sent.
MESSAGE &mRecv = session.mRecv; // MESSAGE been received.
ASSERT(m_pcdDevice);
m_pcdDevice->GetAddr(mSend.aSrcAddr);
if (!IsLocalCmd(mRecv) && mRecv.uCmdID != CMD_TFTP) // zlx 2004.12.24
{// the command don't require local dispose.
PutMsgToHdlcQueue(mRecv, mRecv.uLength);
session.FreeMessage();
return FALSE;
}
session.nIdleTime = 0; // Clear idle time counter
// Set default value
mSend.uCmdID = mRecv.uCmdID;
mSend.aDesAddr= mRecv.aSrcAddr;
mSend.uSubCmd = mRecv.uSubCmd | CMD_RETURN;
mSend.uPacket = mRecv.uPacket;
mSend.SetLength(MESSAGE_FRAME_SIZE);
if (GetApp()->IsDistributedSystem())
{
if (DispatchDeviceCmd(session, 0xFE))
{ // creat event
if (SUBCMD_WRITE && session.mRecv.uCmdID != CMD_MSGMODE)
{
if(session.mRecv.uCmdID == CMD_LOGIN && !session.bLogin)
{
}
else
{
BYTE auParam[] = {session.uLevel, session.mRecv.uCmdID, session.mRecv.uSubCmd};
GetApp()->AddEvent(EVENT_CMD_WRITE, auParam, sizeof(auParam));
}
}
}
session.FreeMessage();
return TRUE;
}
BOOL bDisposed = DispatchSuperCmd(session);
if (!bDisposed)
{// normal commands
if (session.bLogin || (mRecv.aDesAddr != mRecv.aSrcAddr))
{
if(mRecv.uCmdID == CMD_TFTP && mRecv.aDesAddr != mRecv.aSrcAddr)
{
bDisposed = DispatchSpecialCmd(session);
if(!bDisposed)
{ // don't reply
return TRUE;
}
}
else
{
bDisposed = DispatchNormalCmd(session);
}
if (!bDisposed)
{
mSend.SetErrorCmd(CMD_BAD_COMMAND);
}
}
else
{
mSend.SetErrorCmd(CMD_ACCESS_DENIED);
}
}
if (bDisposed)
{// Event log
if (SUBCMD_WRITE && mRecv.uCmdID != CMD_MSGMODE)
{
if(mRecv.uCmdID == CMD_LOGIN && !session.bLogin)
{
}
else
{
BYTE auParam[] = {session.uLevel, mRecv.uCmdID, mRecv.uSubCmd};
GetApp()->AddEvent(EVENT_CMD_WRITE, auParam, sizeof(auParam));
}
}
}
// it is a transfering command
if (!IsReturnCmd(mSend) && mSend.uCmdID != CMD_TFTP)
{
mSend.uSubCmd |= 0x40;
if(mSend.uCmdID != CMD_TEST)
{
mSend.uLength--;
}
PutMsgToHdlcQueue(mSend, mSend.uLength);
session.FreeMessage();
return TRUE;
}
mSend.uCheckSum = mSend.CheckSum();
(session.nID == -1) ? UartSend(mSend) : NetSend(mSend, session.nID);
session.FreeMessage();
return TRUE;
}
// dispatch and dispose super command. a super command is the command which does
// not need to login.
BOOL CMessage::DispatchSuperCmd(SESSION &session)
{
BOOL bRetVal = TRUE;
switch (session.mRecv.uCmdID)
{ //
case CMD_MSGMODE: OnMsgMode(session); break;
case CMD_LOGIN: OnLogin(session); break;
case CMD_LOGOUT: OnLogout(session); break;
case CMD_RLOGIN: OnRlogin(session); break;
case CMD_RLOGOUT: OnRlogout(session); break;
case CMD_SYS_CONFIG: OnSysConfig(session); break;
case CMD_USER_CONFIG: OnUserConfig(session); break;
case CMD_MSG_VERSION: OnMsgVersion(session); break;
case CMD_NET_STATUS: OnNetStatus(session); break;
default: bRetVal = FALSE; break;
}
return bRetVal;
}
// dispatch and dispose normal command. (after login)
// uSlavePort:
BOOL CMessage::DispatchNormalCmd(SESSION &session)
{
BOOL bRetVal = TRUE;
switch (session.mRecv.uCmdID)
{
case CMD_SYS_TIME: OnSysTime(session); break;
case CMD_EVENT: OnEvent(session); break;
case CMD_HOST: OnHost(session); break;
case CMD_FACTORY_CONF: OnFactoryConf(session); break;
case CMD_LOGTIME: OnLogTime(session); break;
case CMD_LOOPBACK_TIME: OnLoopbackTime(session); break;
case CMD_X: OnX(session); break;
case CMD_MASTER_STATION:OnMaster(session); break;//add by bella yu 2004/11/5
case CMD_RESET: OnReset(session); break;
case CMD_MAJOR_MINOR: OnMajorMinor(session); break;
case CMD_MINOR_UPGRADE: OnMinorUpgrade(session); break;
case CMD_ALARM: OnAlarm(session); break;
case CMD_PCMCRC: OnPcmCrc(session); break;
case CMD_LOOPBACK: OnLoopback(session); break;
case CMD_LIUSYNCMODE: OnLiuSyncMode(session); break;
case CMD_LOADDEF: OnLoadDef(session); break;
case CMD_TEST: OnTest(session); break;
case CMD_TCPIP: OnTcpip(session); break;
case CMD_MAC_ADDRESS: OnMacAddress(session); break;
case CMD_VERSION: OnSoftWareVersion(session); break;
case CMD_SAVE: OnSaveFlash(session); break;
case CMD_CLEAR: OnEventClear(session); break;
case CMD_PASSWORD: OnPassword(session); break;
case CMD_TFTP: OnTftp(session); break;
case CMD_AUTOREPORT: OnAutoReportConfig(session);break; //add by bella yu 2004/11/5 break;
default: bRetVal = FALSE; break;
}
return bRetVal;
}
// Dispose command received from RS485 or HDLC
//
// pSession: pointer to current session
// pMsgQueue: pointer to current message queue
BOOL CMessage::DisposeRemoteCmd(SESSION *pSession, MsgQueue *pMsgQueue)
{
if (GetApp()->IsDistributedSystem())
{
if (pSession->mRecv.uCmdID == CMD_TFTP)
{
m_dwLength = pMsgQueue->dwMsgLength;
DisposeCmd(*pSession);
}
else
{
DispatchDeviceCmd(*pSession, pMsgQueue->uSlavePort);
}
pSession->FreeMessage();
}
else // If it is not a distributed system, we received a command from remote host
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -