📄 message.cpp
字号:
else
{
mSend.SetErrorCmd(CMD_BAD_COMMAND);
}
}
// Command reset
// Process command CMD_RESET
void CMessage::OnReset(SESSION &session)
{
MESSAGE &mSend = session.mSend;
MESSAGE &mRecv = session.mRecv;
if ((mRecv.uSubCmd & 0x87) == 0x87)
{// Reset all boards
m_pcdDevice->Reset(1);
}
else
{
mSend.SetErrorCmd(CMD_BAD_COMMAND);
}
}
// Factory configurations (install/uninstall interfaces)
// Process command CMD_FACTORY_CONF
void CMessage::OnFactoryConf(SESSION &session)
{
MESSAGE &mSend = session.mSend;
MESSAGE &mRecv = session.mRecv;
ASSERT(m_pcdDevice);
CBoard *pcbBoard = NULL;
BYTE uInstalled = 0; // Installing information
BYTE uBoard = mRecv.puData[0];
WORD wType = mRecv.puData[1];
BYTE uIndex = mRecv.puData[2];
mSend.SetLength(12);
if (SUBCMD_WRITE)
{
if ((pcbBoard = m_pcdDevice->GetBoard(uBoard)) != NULL)
{
if (mRecv.puData[3])
{
uInstalled = pcbBoard->Install(wType, uIndex);
if (uInstalled == 0 || uInstalled == -1)
{// Installed successfully or old interface exists
uInstalled = 1;
}
}
else
{
pcbBoard->Uninstall(wType, uIndex);
}
}
mSend.puData[0] = uInstalled;
// GetApp()->SetModifiedFlag();
}
else
{
if (m_pcdDevice->GetInterface(uBoard, wType, uIndex) != NULL)
{
uInstalled = 1;
}
mSend.puData[0] = uInstalled;
}
}
///////////////////////////////////////////////////////////////////////////////
// Parameters:
// nIDEvent Specifies the identifier of the timer.
// Remarks:
// The framework calls this member function after each interval specified
// in the CreateTimer member function of CRTApp used to install a timer.
void CMessage::OnTimer(UINT nIDEvent)
{// default interval: 1 second
// Login time-out
if ((nIDEvent == TIMER_MESSAGE) && (SESSION::nTimeout != 0))
{
int key;
SESSION *pSession = NULL;
POSITION pos = m_mapSessions.GetStartPosition();
while (pos != NULL)
{
m_mapSessions.GetNextAssoc(pos, key, pSession);
ASSERT(pSession);
if (pSession->bLogin && ++pSession->nIdleTime > SESSION::nTimeout)
{// login timeout
pSession->bLogin = FALSE;
pSession->strUser.Empty();
pSession->uLevel = ACCESS_LEVEL_DENIED;
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
// Return Value:
// TRUE if initialization successful, otherwise FALSE.
// Remarks:
// frameworks call this to initialize the CMessage object.
BOOL CMessage::OnInitMessage()
{
m_usUart[0].uPort = 0;
m_usUart[0].dwBaudRate = 9600;
m_usUart[0].uDataBits = 8;
m_usUart[0].uParity = 0;
m_usUart[0].uStopBits = 1;
VERIFY(uart4510_Init(&m_usUart[0]) == 0);
// Create a task to process Uart
VERIFY(CreateTask("UartTask", (PFNTASK)&CMessage::UartTask, 0));
// Create a task to process tcp listening
ASSERT(m_pcdDevice);
VERIFY(CreateTask("TCPServerTask", (PFNTASK)&CMessage::TCPServerTask, m_pcdDevice->GetNetPort()));
// Create a task to process logout timeout
VERIFY(CreateTimer("MessageTimer", TIMER_MESSAGE, 1000, 1000));
// If it is not a sub system,
// we must create a task to receive data from remote host or sub board.
if (!GetApp()->IsSubSystem())
{
// Create a task to receive HDLC data from sub system
VERIFY(CreateTask("RemoCommandTask", (PFNTASK)&CMessage::RemoCommandTask, 0));
}
// Create send and receive queue for HDLC protocol
m_pcqQueueRece = CreateQueue("RecvQueue", MESSAGE_QUEUE_SIZE,
NU_FIXED_SIZE, sizeof(MsgQueue));
m_pcqQueueSend = CreateQueue("SendQueue", MESSAGE_QUEUE_SIZE,
NU_FIXED_SIZE, sizeof(MsgQueue));
NU_Reset_Queue(m_pcqQueueRece);
NU_Reset_Queue(m_pcqQueueSend);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// Parameters:
// argc An DWORD data element that may be used to pass initial
// information to the task (here it's the uart port number: 0/1).
// argv A pointer that may be used to pass information to the task.
// Remarks:
// This is the uart task of the console.
void CMessage::UartTask(DWORD argc, void *argv)
{
UNUSED(argv);
ASSERT(argc == 0 || argc == 1);
// data received from uart
BYTE uByte;
// Receiving flag
SRecvFlag rfFlag;
rfFlag.bPrevSOM = FALSE;
rfFlag.bStarted = FALSE;
rfFlag.nCount = 0;
// Connection session
SESSION *pSession = new SESSION;
ASSERT(pSession);
pSession->nID = -1;
pSession->nIdleTime = 0;
pSession->bLogin = FALSE;
pSession->uLevel = ACCESS_LEVEL_DENIED;
m_mapSessions.SetAt(pSession->nID, pSession);
while (1)
{
Sleep(10);
/*
//add by bella yu 2004/08/25
if (m_bModerm_r)
{
if (Xmodem(1))
{
Sleep(500);
if ((FindTask("ModermGetTask") != NULL)|
(FindTask("RemoteModermGetTask") != NULL))
{
NU_Resume_Task(m_pModermTask);
}
else
{
m_pBuff.dwSize = GetSizeModerm();
char *pchBuff = new char[m_pBuff.dwSize];
GetDataModerm(pchBuff, m_pBuff.dwSize);
m_pBuff.puBuff = pchBuff;
m_pBuff.bEnd = TRUE;
}
}
m_bModerm_r = FALSE;
}
if (m_bModerm_t)
{
Xmodem(0);
//Added by bella yu 2005/01/18
if (m_bUpbackApp)
{
m_Session.FreeMessage();
m_bUpbackApp = FALSE;
}
else if (!JudgeMemoryIsValid())
{
DeleteDataBuffer();
}
InitModermStru();
m_bModerm_t = FALSE;
m_bConsole = TRUE;
}
*/
do
{
if (m_bModemUsing) // Uart is using by modem protocol.
break;
// uart4510 command task
if (!uart4510_GetByte((BYTE)argc, &uByte))
break;
if (Receive(uByte, rfFlag, pSession->mRecv))
{
if(pSession->mRecv.CheckSum() != pSession->mRecv.uCheckSum)
{ // Checksum error
pSession->mSend.uCmdID = CMD_ERROR;
pSession->mSend.aDesAddr= pSession->mRecv.aSrcAddr;
pSession->mSend.uSubCmd = pSession->mRecv.uSubCmd | 0x40;
pSession->mSend.SetLength(MESSAGE_FRAME_SIZE);
pSession->mSend.SetErrorCmd(CMD_TRANSFER_ERR);
pSession->mSend.uCheckSum = pSession->mSend.CheckSum();
UartSend(pSession->mSend);
pSession->FreeMessage();
break;
}
pSession->mRecv.uPacket = UART_USER; // Uart
pSession->mRecv.uLength--; // Decrement message length to using Link protocol
DisposeCmd(*pSession);
}
} while(1);
}
}
// Receive command from remote host or sub board Task
void CMessage::RemoCommandTask(DWORD argc, void *argv)
{
UNUSED(argc);
UNUSED(argv);
ASSERT(argc == 0 || argc == 1);
SESSION *pSession = new SESSION;
MsgQueue sMsgQueue[4];
DWORD dwSize;
ASSERT(pSession);
while(1)
{
if(NU_Receive_From_Queue(m_pcqQueueRece, &sMsgQueue[0],
sizeof(MsgQueue), &dwSize, NU_SUSPEND) == NU_SUCCESS)
{
// Get message from queue.
GetMsgFromHdlcQueue(pSession->mRecv, &sMsgQueue[0]);
// Dispose command
DisposeRemoteCmd(pSession, &sMsgQueue[0]);
// Free message
pSession->FreeMessage();
}
}
}
// TCP server task entry function
void CMessage::TCPServerTask(DWORD dwPort, void *argv)
{
ASSERT(m_pcdDevice);
UNUSED(argv);
int socketd, newsock, nPos; // the socket descriptor
struct addr_struct asServer; // holds the server address structure
struct addr_struct asClient; // holds the client address structure
CString strTaskName; // name of the echo task
// open a connection via the socket interface
if ((socketd = NU_Socket(NU_FAMILY_IP, NU_TYPE_STREAM, NU_NONE)) >=0 )
{
// fill in a structure with the server address
asServer.family = NU_FAMILY_IP;
asServer.port = (WORD)dwPort;
*(DWORD*)asServer.id.is_ip_addrs = IP_ADDR_ANY;
asServer.name = (LPSTR)"TCPServer";
// To bind the server's address
if ((NU_Bind(socketd, &asServer, 0)) >= 0)
{
// be ready to accept connection requests
if (NU_Listen(socketd, 10) == NU_SUCCESS)
{
while (1)
{
// block in NU_Accept until a client attempts connection
newsock = NU_Accept(socketd, &asClient, 0);
nPos = GetUserIndex();
if (nPos)
{
if (newsock >= 0)
{
m_muUsers[nPos].dwPath = newsock;
memcpy(&m_muUsers[nPos].uVal, asClient.id.is_ip_addrs, sizeof(asClient.id));
// process the new connection
strTaskName.Format("TCPEchoTask%d", newsock);
VERIFY(CreateTask(strTaskName,
(PFNTASK)&CMessage::TCPEchoTask, newsock));
// Sleep 20ms so that other tasks can run.
Sleep(20);
}
}
else
{
SESSION *pSession = new SESSION;
ASSERT(pSession);
pSession->mSend.uCmdID = CMD_MSGMODE;
pSession->mSend.aDesAddr.uAddrH = 0;
pSession->mSend.aDesAddr.uAddrL = 1;
pSession->mSend.aDesAddr.uGroup = 0;
pSession->mSend.uSubCmd = 0x40;
pSession->mSend.SetLength(MESSAGE_FRAME_SIZE);
pSession->mSend.SetErrorCmd(CMD_USER_LIMIT);
pSession->mSend.uCheckSum = pSession->mSend.CheckSum();
NetSend(pSession->mSend,newsock);
pSession->FreeMessage();
NU_Close_Socket(newsock);
}
}
}
}
}
// ASSERT(FALSE);
}
// TCP echo task entry function
void CMessage::TCPEchoTask(DWORD dwSocketd, void *argv)
{
UNUSED(argv);
// Data received from uart
BYTE uByte;
// Receiving flag
SRecvFlag rfFlag;
rfFlag.bPrevSOM = FALSE;
rfFlag.bStarted = FALSE;
rfFlag.nCount = 0;
// Connection session
SESSION *pSession = new SESSION;
ASSERT(pSession);
pSession->nID = dwSocketd;
pSession->nIdleTime = 0;
pSession->bLogin = FALSE;
pSession->uLevel = ACCESS_LEVEL_DENIED;
m_mapSessions.SetAt(pSession->nID, pSession);
// turn on the "block during a read" flag
NU_Fcntl(dwSocketd, NU_SETFLAG, NU_BLOCK);
while (1)
{
if (NU_Recv(dwSocketd, (char*)&uByte, 1, 0) > 0)
{
if (Receive(uByte, rfFlag, pSession->mRecv))
{
if(pSession->mRecv.CheckSum() != pSession->mRecv.uCheckSum)
{ // Checksum error
pSession->mSend.uCmdID = CMD_ERROR;
pSession->mSend.aDesAddr= pSession->mRecv.aSrcAddr;
pSession->mSend.uSubCmd = pSession->mRecv.uSubCmd | 0x40;
pSession->mSend.SetLength(MESSAGE_FRAME_SIZE);
pSession->mSend.SetErrorCmd(CMD_TRANSFER_ERR);
pSession->mSend.uCheckSum = pSession->mSend.CheckSum();
NetSend(pSession->mSend,dwSocketd);
// pSession->FreeMessage(); // Comment by Bozhong xu
#ifdef _DEBUG
printf("Net CheckSum error\n");
#endif
break;
}
pSession->mRecv.uLength--;
if (GetSocketIndex(dwSocketd))
{
pSession->mRecv.uPacket = GetSocketIndex(dwSocketd);
DisposeCmd(*pSession);
}
else
{
#ifdef _DEBUG
printf("error socket\n");
#endif
}
}
}
else // error or client closed.
{
break;
}
}
// clear MultiUser system
memset(&m_muUsers[GetSocketIndex(dwSocketd)], 0, sizeof(MultiUser));
NU_Close_Socket(dwSocketd);
// Remove session
pSession->FreeMessage();
delete pSession;
m_mapSessions.RemoveKey(dwSocketd);
// Deletes the finished task.
CString strTaskName;
strTaskName.Format("TCPEchoTask%d", dwSocketd);
VERIFY(DeleteTask(strTaskName));
}
///////////////////////////////////////////////////////////////////////////////
// The following two functions are an extension of Nucleus FAL system.
// Purpose: (a) Insure to initialize FAL system only once
// (b) UnInitialize the FAL system when operation finished. This can
// free a big block of memory occupied by FAL.
// Initialize the Nucleus fal system used by TFTP client
static BOOL s_bFalSysInitialized = FALSE;
static STATUS FAL_Sys_InitEx(int ram_disk)
{
STATUS status = NU_SUCCESS;
if (!s_bFalSysInitialized)
{// Initialize FAL with memory allocated.
status = FAL_Sys_Init(ram_disk); // disk 'A'
if (status == NU_SUCCESS)
{
s_bFalSysInitialized = TRUE;
}
}
else
{
for (int i = 0; i < MAX_FILES; i++)
{// Initialize FAL without memory allocated. (use it of last time)
file_desc_ary[i].end = file_desc_ary[i].start + MAX_FILE_SIZE;
file_desc_ary[i].length = 0;
file_desc_ary[i].max_length = MAX_FILE_SIZE;
file_desc_ary[i].file_ptr = file_desc_ary[i].start;
file_desc_ary[i].eof_ptr = file_desc_ary[i].start;
file_desc_ary[i].used = 0;
file_desc_ary[i].open = 0;
file_desc_ary[i].name[0] = 0;
}
}
return status;
}
// UnInitialize the Nucleus FAL system: free the memory occupied by FAL system.
static STATUS FAL_Sys_UnInit(void)
{
STATUS status = NU_SUCCESS;
for (int i = 0; i < MAX_FILES; i++)
{
if (file_desc_ary[i].start)
{// free memory & clear variables
status = NU_Deallocate_Memory(file_desc_ary[i].start);
if (status == NU_SUCCESS)
{
memset(file_desc_ary, 0, sizeof(MEM_FILE));
}
else
{
break;
}
}
}
if (status == NU_SUCCESS)
{
s_bFalSysInitialized = FALSE;
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// TFTP Client Get task
void CMessage::TFTPClientGetTask(DWORD argc, void *argv)
{
UNUSED(argc);
ASSERT(argv);
//
// get the parameters passed by argv
//
TASKPARAM *pParam = (TASKPARAM*)argv; // task parameter
CString strFileName = pParam->strParam; // name of the file
BYTE auIP[4]; // ip address of the TFTP server
memcpy(auIP, &pParam->dwParam, 4);
DWORD dwType = pParam->dwOther; // file type
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -