📄 message.cpp
字号:
if (pSession->mRecv.uCmdID == CMD_REPORT)
{ // Auto report from HDLC
DispatchAutoReport(*pSession);
}
else if (SUBCMD_RETURN(pSession)) // This message was processed, so we send it to uart or ethernet.
{
pSession->mRecv.uLength++;
pSession->mRecv.uCheckSum = pSession->mRecv.CheckSum();
if(pSession->mRecv.uPacket >= UART_USER && pSession->mRecv.uPacket <= NET_USER_MAX)
{
if (pSession->mRecv.uPacket == UART_USER)
{
UartSend(pSession->mRecv);
}
else
{
DWORD dwPath = m_muUsers[pSession->mRecv.uPacket].dwPath;
if (dwPath)
{
NetSend(pSession->mRecv, dwPath);
}
}
}
else
{
#ifdef _DEBUG
printf("Return CMD packet error\n");
#endif
}
pSession->FreeMessage();
}
else // This command was not processed, we must dispose it.
{ // remote command
if (pSession->mRecv.uCmdID == CMD_TFTP)
{
m_dwLength = pMsgQueue->dwMsgLength;
}
DisposeCmd(*pSession);
}
}
return TRUE;
}
// Firmware upgrade from TFTP server
// Process command CMD_TFTP
void CMessage::OnTftp(SESSION &session)
{
MESSAGE &mSend = session.mSend;
MESSAGE &mRecv = session.mRecv;
// Only one task is permitted at one time
if ((FindTask("TFTPClientPutTask") != NULL)
|| (FindTask("TFTPClientGetTask") != NULL)
|| (FindTask("ModermGetTask") != NULL)
|| (FindTask("ModermPutTask") != NULL))
{
mSend.puData[0] = (BYTE)-1;// too many users
return;
}
TASKPARAM *pParam = new TASKPARAM; // delete is in task
ASSERT(pParam);
pParam->pParam = GetApp();
memcpy(&pParam->dwParam, mRecv.puData, 4);
pParam->strParam = &mRecv.puData[4]; // file name
pParam->dwOther = mRecv.puData[17]; // file type
pParam->nParam = session.nID;
pParam->nOther = 0; // Default is MCU TFTP uploading
mSend.SetLength(12);
if (pParam->dwOther == TFTP_FPGA) // FPGA upload or backup
{
CFlash *pcFlash = m_pcdDevice->GetFlash();
ASSERT(pcFlash);
FLASH_SECTOR fs; // flash sector information
VERIFY(pcFlash->Lookup(SECTOR_FPGA_MIN, fs));
for(int i = 0; i < 4; i++)
{
if(VPbyte(fs.dwAddr) != 0x5A)
{
mSend.puData[0] = 1; // no Fpga data
delete pParam;
return;
}
}
}
if (mRecv.uSubCmd & 0x01) // It is a distributed system
{
if ((mRecv.uSubCmd & 0x06) == 0)//uart
{
if (mRecv.puData[18] == 0x0) //mcu
{
if (SUBCMD_READ) // Backup
{
VERIFY(CreateTask("ModermPutTask", (PFNTASK)&CMessage::ModermPutTask,
0, pParam));
}
else // Upload
{
VERIFY(CreateTask("ModermGetTask", (PFNTASK)&CMessage::ModermGetTask,
0, pParam));
m_pcdDevice->SetRedLed(TRUE);
}
}
else//swh and liu
{
pParam->nOther = 1; // Sub board uploading
}
mSend.puData[0] = 0; // Thread started successfully.
}
else//net
{
if (mRecv.puData[18] == 0x0)//mcu
{
if (SUBCMD_READ) // backup file
{
VERIFY(CreateTask("TFTPClientPutTask",
(PFNTASK)&CMessage::TFTPClientPutTask, 0, pParam));
}
else // upgrade
{
VERIFY(CreateTask("TFTPClientGetTask",
(PFNTASK)&CMessage::TFTPClientGetTask, 0, pParam));
m_pcdDevice->SetRedLed(TRUE);
}
}
else if (SUBCMD_WRITE) // sub board upload
{
pParam->nOther = 1; // Sub board uploading
VERIFY(CreateTask("TFTPClientGetTask",
(PFNTASK)&CMessage::TFTPClientGetTask, 0, pParam));
}
mSend.puData[0] = 0; // Thread started successfully.
}
}
//no slave board
else
{
if ((mRecv.uSubCmd & 0x06) == 0) // Uart
{
if (SUBCMD_READ) // Backup
{
VERIFY(CreateTask("ModermPutTask", (PFNTASK)&CMessage::ModermPutTask,
0, pParam));
}
else // Upgrade
{
VERIFY(CreateTask("ModermGetTask", (PFNTASK)&CMessage::ModermGetTask,
0, pParam));
m_pcdDevice->SetRedLed(TRUE);
}
}
else // Net
{
if (SUBCMD_READ) // Backup
{
VERIFY(CreateTask("TFTPClientPutTask",
(PFNTASK)&CMessage::TFTPClientPutTask, 0, pParam));
}
else // Upgrade
{
VERIFY(CreateTask("TFTPClientGetTask",
(PFNTASK)&CMessage::TFTPClientGetTask, 0, pParam));
m_pcdDevice->SetRedLed(TRUE);
}
}
mSend.puData[0] = 0;// Thread started successfully.
}
}
// Moderm Protocol Get Task
void CMessage::ModermGetTask(DWORD argc, void *argv)
{
UNUSED(argc);
ASSERT(argv);
//
// get the parameters passed by argv
//
TASKPARAM *pParam = (TASKPARAM*)argv; // task parameter
DWORD dwType = pParam->dwOther; // file type (0:app, 1:bios, 2:system.ini)
// BOOL bSlaveUpload = (pParam->nOther == 1) ? TRUE : FALSE;
int nID = pParam->nParam; // session id, it should be -1.
delete pParam;
SESSION *pSession = NULL;
m_mapSessions.Lookup(nID, pSession);
ASSERT(pSession);
ASSERT(pSession->nID == nID);
// Delay 100ms to make sure sending completely to console.
Sleep(100);
m_bModemUsing = TRUE; // Uart is using by modem protocol.
// Initiailize Y modem protocol
xyModem_Init(PROTOCOL_YMODEM, COMM_SERIAL, 0);
int nReadCount = xyModem_Get(); // Get data by modem protocol
if (nReadCount <= 0) // Error occured.
{
TRACE("Upload failed.(%d)\n", nReadCount);
}
else
{
if (dwType == TFTP_APP || dwType == TFTP_BIOS || dwType == TFTP_FPGA)
{// bios or application
///////////////////////////////////////////////////////////////////////
// insure that data area not to be destroied.
if (nReadCount > (SECTOR_APP_MAX - SECTOR_APP_MIN + 1) << 16)
nReadCount = (SECTOR_APP_MAX - SECTOR_APP_MIN + 1) << 16;
///////////////////////////////////////////////////////////////////////
// get system flash chip object
ASSERT(m_pcdDevice);
CFlash *pcFlash = m_pcdDevice->GetFlash();
ASSERT(pcFlash);
FLASH_SECTOR fs; // flash sector information
// Calculate the min. & max. sector number required by bios or app.
UINT nMinSector = (dwType == TFTP_APP) ? SECTOR_APP_MIN : SECTOR_BIOS_MIN;
nMinSector = (dwType == TFTP_FPGA) ? SECTOR_FPGA_MIN : nMinSector;
UINT nMaxSector = nMinSector - 1;
for (DWORD dwSize = 0; dwSize < (DWORD)nReadCount;)
{
nMaxSector++;
if (!pcFlash->Lookup(nMaxSector, fs))
{// sector not found
nMaxSector--;
break;
}
dwSize += fs.dwSize;
}
ASSERT(dwType == TFTP_APP || dwType == TFTP_FPGA || nMaxSector < 4); // sectors for bios: 0-3
// percent increment of every step.
BYTE uIncrement = 100 / (nMaxSector - nMinSector + 1);
BYTE uPercent = 0; // progress percent.
for (UINT nSec = nMinSector; nSec <= nMaxSector; nSec++)
{// erase the required sectors
VERIFY(pcFlash->EraseSector(nSec));
// auto report progress of erasing flash.
uPercent += uIncrement;
ProgressReport(1, uPercent, *pSession);
Sleep(2); // sleep so other task can run.
}
if (uPercent < 100)
{// auto report that flash erasing finished.
ProgressReport(1, 100, *pSession);
Sleep(2); // sleep so other task can run.
}
// file is divided to 100 parts
if(dwType == TFTP_FPGA)
{
nReadCount += 0x10; // add Flag and length
}
int nBlockSize = nReadCount / 100 + ((nReadCount % 100) ? 1 : 0);
ASSERT(nBlockSize * 100 >= nReadCount);
BYTE *puBuff = new BYTE[nBlockSize];// buffer used to program to flash
ASSERT(puBuff);
VERIFY(pcFlash->Lookup(nMinSector, fs));
for (uPercent = 1; uPercent <= 100; uPercent++)
{// Program binary file to flash
if(uPercent == 1 && dwType == TFTP_FPGA)
{ // write FPGA head frame
memset(puBuff, 0x5A, 0x10); // write Flag
memcpy(&puBuff[12], &nReadCount, 4); // write length
nReadCount = xyModem_GetData(&puBuff[0x10], nBlockSize - 0x10);
nReadCount += 0x10;
}
else
{
nReadCount = xyModem_GetData(puBuff, nBlockSize);
}
VERIFY(pcFlash->Write(fs.dwAddr, puBuff, nReadCount));
fs.dwAddr += nReadCount;
// report current progress to console.
ProgressReport(2, uPercent, *pSession);
Sleep(2); // sleep so other task can run
}
delete[] puBuff;
}
else if (dwType == TFTP_FILE)
{
// data file: System.ini
CMemFile file;
BYTE buff[1024]; // buffer used to program to flash
do
{
nReadCount = xyModem_GetData(buff, sizeof(buff));
file.Write(buff, nReadCount);
} while (nReadCount > 0);
file.SeekToBegin();
// Get system data
OnGetSysDataFromFile(file);
// Set save flag
m_pcdDevice->SetFlagLoaddef(pSession->mRecv.uPacket);
GetApp()->SetModifiedFlag();
}
}
// Free the memory allocated by modem protocol.
xyModem_Free();
m_bModemUsing = FALSE;
// If it is not uploading user data,
// we must restart system by disable watchdog.
if (dwType != TFTP_FILE)
{
Sleep(1000); // sleep 1s
Disable_Int(nGLOBAL_INT); // disable INT so watchdog can work.
}
else
m_pcdDevice->SetRedLed(FALSE);
// Deletes the finished task.
VERIFY(DeleteTask("ModermGetTask"));
ASSERT(m_bModemUsing == FALSE);
}
//Modem Protocol Put Task
void CMessage::ModermPutTask(DWORD argc, void *argv)
{
UNUSED(argc);
TASKPARAM *pParam = (TASKPARAM*)argv; // task parameter
CString strFileName = pParam->strParam; // name of the file
DWORD dwType = pParam->dwOther; // file type (0:app, 1:bios, 2:system.ini)
int nID = pParam->nParam; // session id
delete pParam;
SESSION *pSession = NULL;
m_mapSessions.Lookup(nID, pSession);
ASSERT(pSession);
ASSERT(pSession->nID == nID);
LPSTR lpszFile = (LPSTR)(LPCSTR)strFileName;// name of the file
BYTE *puSend = NULL; // The data to send by modem protocol.
DWORD dwTotalLen = 0; // The total bytes of sending by modem protocol.
// Delay 100ms to make sure sending completely to console.
Sleep(100);
m_bModemUsing = TRUE; // Uart is using by modem protocol.
// Initialize modem protocol, Y modem with uart port 0.
xyModem_Init(PROTOCOL_YMODEM, COMM_SERIAL, 0);
//App
if ((dwType == TFTP_APP) || (dwType == TFTP_BIOS))
{
CFlash *pcFlash = m_pcdDevice->GetFlash();
ASSERT(pcFlash);
FLASH_SECTOR fs; // flash sector information
UINT nMinSector = (dwType == TFTP_APP) ? SECTOR_APP_MIN : SECTOR_BIOS_MIN;
UINT nMaxSector = (dwType == TFTP_APP) ? SECTOR_APP_MAX : SECTOR_BIOS_MAX;
// Get total data length.
for (UINT i = nMinSector; i <= nMaxSector; i++)
{
VERIFY(pcFlash->Lookup(i, fs));
dwTotalLen += fs.dwSize;
}
puSend = new BYTE[dwTotalLen];
ASSERT(puSend);
// Copy data from flash
VERIFY(pcFlash->Lookup(nMinSector, fs));
memcpy(puSend, (char*)fs.dwAddr, dwTotalLen);
}
//File
else if (dwType == 0x02)
{
// data file
BYTE buff[1024];
CMemFile file;
UINT nCount = 0;
// Put user data to a file.
OnPutSysDataToFile(file);
dwTotalLen = file.GetLength();
file.SeekToBegin();
puSend = new BYTE[dwTotalLen];
ASSERT(puSend);
BYTE *pBuf = puSend;
do
{
nCount = file.Read(buff, sizeof(buff));
memcpy(pBuf, buff, nCount);
pBuf += nCount;
} while (nCount > 0);
}
else
{
TRACE("Nonsupport uploading!\n");
}
if (dwTotalLen > 0)
{
// Sending data by modem protocol
xyModem_Put(puSend, dwTotalLen, lpszFile);
m_bModemUsing = FALSE;
delete [] puSend;
}
DeleteTask("ModermPutTask");
ASSERT(m_bModemUsing == FALSE);
}
// Get system data from a file
BOOL CMessage::OnGetSysDataFromFile(CFile &file)
{
GetApp()->LoadFromFile(file, 1);
return TRUE;
}
// Put system data to a file
BOOL CMessage::OnPutSysDataToFile(CFile &file)
{
GetApp()->SaveToFile(file, 1);
return TRUE;
}
// auto report the progress of firmware upgrading.
void CMessage::ProgressReport(BYTE uType, BYTE uProgress, SESSION &session)
{
session.mSend.SetLength(13);
m_pcdDevice->GetAddr(session.mSend.aSrcAddr);
session.mSend.uCmdID = CMD_TFTP;
session.mSend.uSubCmd = 0xC0;
session.mSend.puData[0] = uType;
session.mSend.puData[1] = uProgress;
(session.nID == -1) ?
UartSend(session.mSend) : NetSend(session.mSend, session.nID);
session.FreeMessage();
}
// Mac address
// Process command CMD_MAC_ADDRESS
void CMessage::OnMacAddress(SESSION &session)
{
MESSAGE &mRecv = session.mRecv;
MESSAGE &mSend = session.mSend;
ASSERT(m_pcdDevice);
NETDEVICE ndDevice;
m_pcdDevice->GetNetDevice(ndDevice);
if (SUBCMD_WRITE)
{
memcpy(ndDevice.auMac, mRecv.puData, sizeof(ndDevice.auMac));
m_pcdDevice->SetNetDevice(ndDevice, CONFIG_MAC);
}
else
{
mSend.SetLength(17);
memcpy(mSend.puData, ndDevice.auMac, sizeof(ndDevice.auMac));
}
}
// TCP/IP Property
// Process command CMD_TCPIP
void CMessage::OnTcpip(SESSION &session)
{
MESSAGE &mRecv = session.mRecv;
MESSAGE &mSend = session.mSend;
ASSERT(m_pcdDevice);
NETDEVICE ndDevice;
m_pcdDevice->GetNetDevice(ndDevice);
int i;
if (SUBCMD_WRITE)
{
for (i = 0; i < 4; i++)
{// copy ip address, subnet mask & gateway
ndDevice.auIP[i] = mRecv.puData[i];
ndDevice.auSubnet[i] = mRecv.puData[4 + i];
ndDevice.auGateway[i] = mRecv.puData[8 + i];
}
UINT nPort = MAKEWORD(mRecv.puData[13], mRecv.puData[12]);
if (nPort != ndDevice.nPort)
{// restarting system is required when port is modified.
ndDevice.nPort = nPort;
m_pcdDevice->Reset(1);
}
m_pcdDevice->SetNetDevice(ndDevice, CONFIG_IP);
}
else
{
mSend.SetLength(25);
for (i = 0; i < 4; i++)
{
mSend.puData[i] = ndDevice.auIP[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -