📄 dataoperator.cpp
字号:
// DataOperator.cpp: implementation of the CDataOperator class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <malloc.h>
#include "DataOperator.h"
#include "MessageEdit.h"
extern CMessageEdit m_MsgEdit;
extern CEdit m_SuccRatioEditCtrl;
#include "CrcCode.h"
static CCrcCode gCrcCode;
#define HAVE_STOP_MARK if(mExitSystemMark) throw((int)THROWMAG_STOP);
extern unsigned char gCharTimeout; //每55ms减少1,直到0为止
extern unsigned short int gIntervalTimeout; //每55ms减少1,直到0为止.
extern void ShowMessage(char *str);
unsigned char mBuffer[10240];
///////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDataOperator::CDataOperator()
{
m_uPackageSize=1024;//升级文件每包大小
}
CDataOperator::~CDataOperator()
{
}
//Datas格式:Len(2) Status(1) Func(1) Datas(N)
void CDataOperator::SendDataPackage(unsigned char *Datas)
{
//发送格式:Pro(4) Sync(2) Len(2) Status(1) Func(1) Datas(N) Crc32(4) Eof(1)
unsigned char Head[6]={0xFF,0xFF,0xFF,0xFF,0xF6,0x28};
unsigned short Len=((Datas[0]<<8)|(Datas[1]&0xFF));
if(Len<6)
{
ShowMessage("Program Error!!!!");
return ;
}
*(unsigned long int *)(Datas+Len-2)=gCrcCode.Crc32Mtt(Datas,Len-2);
Datas[Len+2]=0xFF;
sio_write((char *)Head,6);
sio_write((char *)Datas,Len+3);
}
//返回Datas格式:Len(2) Status(1) Func(1) Datas(N)
unsigned short CDataOperator::ReceiveDataPackage(unsigned char *Datas)//返回长度Func ,1秒超时
{
//接收数据格式:0xFF 0xF6 0x28 Len_H Len_L Status Func Datas(N) Crc32(4)
signed short ch;
short int Count,PackageLen;
gIntervalTimeout=18;//数据总超时,
gCharTimeout=0;
while(gIntervalTimeout || gIntervalTimeout)
{
HAVE_STOP_MARK
ch=sio_getch();
if(ch>>8) continue;
if(gCharTimeout==0) memset(Datas,0,5);
gCharTimeout=8;
Datas[0]=Datas[1];
Datas[1]=Datas[2];
Datas[2]=Datas[3];
Datas[3]=Datas[4];
Datas[4]=(unsigned char)ch;
if(Datas[0]!=0xFF ||Datas[1]!=0xF6 ||Datas[2]!=0x28) continue;
//接受到数据包头,和长度字节。
Datas[0]=Datas[3];Datas[1]=Datas[4];
PackageLen=((Datas[0]<<8) | Datas[1])+2;
Count=2;
while(gCharTimeout)
{
HAVE_STOP_MARK
ch=sio_getch();
if(ch>>8) continue;
gCharTimeout=5;
Datas[Count++]=(unsigned char)ch;
if(Count!=PackageLen) continue;
if(*(unsigned long int *)(Datas+Count-4)==gCrcCode.Crc32Mtt(Datas,Count-4))
{
m_MsgEdit.EditPrintf("<%2X> ",Datas[3]&0xFF);
return (Datas[3]&0xFF);
}
//else m_MsgEdit.AddText("\r\nCRC Error ");
}
}
//m_MsgEdit.AddText("\r\nOver Time ");
return 0;
}
void CDataOperator::RecvNewChar(unsigned char ch)
{
// const char B0[]={0xF6,0x28,0x00,0x07,0x01,0xB0,0xF0,0x18,0x5A,0xF7,0x3A};
// extern CMessageEdit m_ReceiveDataEdit;
// extern unsigned char gCharInterval;
// if(gCharInterval==0) m_MsgEdit.AddText("\r\n");
// m_MsgEdit.EditPrintf("%02X ",ch);
// gCharInterval=5;
}
void CDataOperator::Send_Stop_B9_Protocol()
{
unsigned char B0_Buf[16]={0x00,0x07,0x00,0xB9,0xF1};
SendDataPackage(B0_Buf);
}
//FF FF FF FF F6 28 00 06 01 01 79 07 B5 B3 FF
//////////////////////////////////////////////////////////////////////////
void CDataOperator::Start()
{
m_SuccRatioEditCtrl.SetWindowText("");
if(mDowloadFileMsg.Count==0) return;
m_MsgEdit.EditPrintf("\r\n--------------本次升级文件数 %d-------------",mDowloadFileMsg.Count);
try
{
CFile file;
int k;
sio_flush();
//等待B0
m_MsgEdit.AddText("\r\n等待连接,一直等待连接...");
k=0;
while(ReceiveDataPackage(mBuffer)!=0xB0)
{
k++;
if(k==5) {m_MsgEdit.AddText("+");k=0;}
}
m_MsgEdit.AddText(" OK.");
m_connComputerNo=ftonl(mBuffer+4);
if(m_ObjComputerNo && m_ObjComputerNo!=m_connComputerNo)
{
m_MsgEdit.EditPrintf("升级计算机编号(%lu %lu)不一致,不能升级!!",m_ObjComputerNo,m_connComputerNo);
if(IDYES!=MessageBox(NULL,"升级计算机编号不一致,不能升级!\n是否强行目标退出升级?","请选择",MB_YESNO|MB_SYSTEMMODAL)) return;
Send_Stop_B9_Protocol();
return;
}
else m_MsgEdit.EditPrintf("升级计算机编号%lu!",m_connComputerNo);
for(k=0;k<mDowloadFileMsg.Count;k++)
{
HAVE_STOP_MARK;
if(m_ptrFileBuffer) delete[]m_ptrFileBuffer;m_ptrFileBuffer=NULL;
m_MsgEdit.EditPrintf("\r\n▲▲▲打开升级文件%s,",mDowloadFileMsg.Name[k].srcName);
if(file.Open(mDowloadFileMsg.Name[k].srcName,CFile::modeRead))
{
m_lFileLength=file.GetLength();
m_ptrFileBuffer=new unsigned char[m_lFileLength];
file.ReadHuge(m_ptrFileBuffer,m_lFileLength);
file.Close();
m_uPackageCount=(unsigned short)((m_lFileLength+m_uPackageSize-1)/m_uPackageSize);
m_lFileCrcCode=gCrcCode.Crc32Mtt(m_ptrFileBuffer,m_lFileLength,0);
m_MsgEdit.EditPrintf("长度%lu,包大小%u,升级包数%u,目标文件%s ",m_lFileLength,m_uPackageSize,m_uPackageCount,mDowloadFileMsg.Name[k].objName);
SendFile(mDowloadFileMsg.Name[k].objName,(mDowloadFileMsg.Count-k-1));
}
else m_MsgEdit.EditPrintf("失败");
}
}
catch(int v)
{
switch(v)
{
case THROWMAG_OK:
m_MsgEdit.AddText("\r\n<<<<全部文件下载结束!!!>>>>");
break;
case THROWMAG_STOP:
{
Send_Stop_B9_Protocol();
m_MsgEdit.AddText("\r\n<<<<强行停止升级!!!>>>>");
}
break;
case THROWMAG_ERROR:
m_MsgEdit.AddText("\r\n<<<<升级错误停止!!!>>>>");
break;
case THROWMAG_OVERTTIME:
m_MsgEdit.AddText("\r\n<<<<升级数据超时停止!!!>>>>");
break;
default:
break;
}
}
if(m_ptrFileBuffer) delete[]m_ptrFileBuffer;
m_ptrFileBuffer=NULL;
return;
}
void CDataOperator::SendFile(const char *objFileName,unsigned char unSendFileCount)
{
extern unsigned long int GetSystemDefineTime();
unsigned long UprBeginTime,UprEndTime;
extern unsigned short int gSecondTimeout;
unsigned char B1_Buf[128];
//产生B1,数据包
*(unsigned short *)B1_Buf=ftons(6+18+strlen(objFileName)+1);
B1_Buf[2]=0;
B1_Buf[3]=0xB1;
B1_Buf[4]=unSendFileCount;
B1_Buf[5]=1;
*(unsigned long *)(B1_Buf+6)=ftonl(m_lFileLength);
*(unsigned short *)(B1_Buf+10)=ftons(m_uPackageSize);
*(unsigned short *)(B1_Buf+12)=ftons(m_uPackageCount);
*(unsigned long *)(B1_Buf+14)=ftonl(m_lFileCrcCode);
*(unsigned long *)(B1_Buf+18)=ftonl(m_lFileCrcCode);
memcpy(B1_Buf+22,objFileName,strlen(objFileName)+1);
//发送B1,等待B1
//开始升级
//每8秒重复发送B1,等待回答B1之F0
sio_flush();
m_SuccRatioEditCtrl.SetWindowText("");
m_MsgEdit.EditPrintf("\r\n (B1)协商发送格式 ");
for(;;)
{
m_MsgEdit.EditPrintf("B1 ");
SendDataPackage(B1_Buf);
gSecondTimeout=8;//8秒发一次
while(gSecondTimeout)
{
HAVE_STOP_MARK;
switch(ReceiveDataPackage(mBuffer))
{
case 0xB1:
if(mBuffer[4]==0xF0) goto ENTER_B2;
break;
case 0xB9://收到错误码
ReceiveErrorCode(mBuffer[4]);
throw((int)THROWMAG_ERROR);
default:
break;
}
}
}
ENTER_B2:
//发送B2,等待B2
m_MsgEdit.EditPrintf("... 协商完成\r\n (B2)开始发送文件数据:");
unsigned short int CurSendIndex=0;
unsigned short int BeingSendIndex;
UprBeginTime=GetSystemDefineTime();
m_ReSendIndex.Empty();
gSecondTimeout=60;
for(;;)
{
HAVE_STOP_MARK;
if(gSecondTimeout==0) throw((int)THROWMAG_OVERTTIME);
//如有重发序号
if(m_ReSendIndex.GetData(BeingSendIndex)==0)
{
BeingSendIndex=CurSendIndex;
if(CurSendIndex<m_uPackageCount-1) CurSendIndex++;
}
//发送B2文件数据。
SendFileData_0xB2(BeingSendIndex);
m_MsgEdit.EditPrintf("%u ",BeingSendIndex);
switch(WaitData())//等待数据
{
case 0xB0:
m_MsgEdit.AddText("\r\n集中器可能已经重新启动,升级未完成");
throw((int)THROWMAG_ERROR);
return;
case 0xB1:
gSecondTimeout=60;
break;
case 0xB2:
{
int OKCount=ftons(mBuffer+4);
short ReSendCount=ftons(mBuffer+6);
CString cs;
unsigned short int *ptrRendIndex=(unsigned short int *)(mBuffer+8);
for(int i=0;i<ReSendCount;i++,ptrRendIndex++) m_ReSendIndex.AddData(ftons(*ptrRendIndex));
gSecondTimeout=60;
cs.Format("%.2f%%",100.0*OKCount/m_uPackageCount);
m_SuccRatioEditCtrl.SetWindowText(cs);
if(OKCount==m_uPackageCount && ReSendCount==0)
{
UprEndTime=GetSystemDefineTime()-UprBeginTime;
m_MsgEdit.EditPrintf("\r\n (B3)文件升级成功(使用%lu秒),还剩%u个文件未升级.",UprEndTime,unSendFileCount);
if(unSendFileCount==0)
{
Send_Stop_B9_Protocol();
throw((int)THROWMAG_OK);
}
return;
}
}
break;
case 0xB9://收到错误码
ReceiveErrorCode(mBuffer[4]);
throw((int)THROWMAG_ERROR);
return;
default:
break;
}
}
}
void CDataOperator::SendFileData_0xB2(unsigned short int Index)
{
short int DataLen=m_uPackageSize;
unsigned long FileOffset=(long)Index*m_uPackageSize;
if(Index==m_uPackageCount-1) DataLen=(short)(m_lFileLength-FileOffset);
*(unsigned short *)mBuffer=ftons(8+DataLen);
mBuffer[2]=0;
mBuffer[3]=0xB2;
*(unsigned short *)(mBuffer+4)=ftons(Index);
memcpy(mBuffer+6,m_ptrFileBuffer+FileOffset,DataLen);
SendDataPackage(mBuffer);
};
unsigned short int CDataOperator::WaitData()
{
//交互式传输就是在没有收到数据时,等待12秒
short int V;
for(int ii=0;ii<8;ii++)
{
V=ReceiveDataPackage(mBuffer);
if(V) return V;
}
return 0;
}
void CDataOperator::ReceiveErrorCode(unsigned char ErrorCode)
{
CString cs;
cs.Format("\r\n 收到错误码:0x%02X,含义:",mBuffer[4]);
switch(ErrorCode)
{
case 0xF1:
cs+="错误或人为停止升级";
break;
case 0xF2:
cs+="协议(未知)错误";
break;
case 0xF3:
cs+="产生文件错误";
break;
case 0xF4:
cs+="升级磁盘空间不够";
break;
case 0xF5:
cs+="磁盘读写错误";
break;
case 0xF6:
cs+="两次协商状态不一致";
break;
case 0xF7:
cs+="文件传输校验码不对";
break;
case 0xF8:
cs+="升级文件长度不能为0";
break;
}
m_MsgEdit.AddText(cs);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -