?? upgrade.cpp
字號:
// Upgrade.cpp: implementation of the CUpgradeFile class.
//
//////////////////////////////////////////////////////////////////////
#include "public.h"
#include "Upgrade.h"
#include "DataPort.h"
extern CDataPort gDataPort;
#include "CrcCode.h"
extern CCrcCode gCrcCode;
unsigned char mBuffer[10240];
extern unsigned short int gSecondTimeout;
extern const unsigned short int gUSecond;
extern void Teststack();
extern unsigned char gArriveAnswerTime;
CUpgradeFile::CUpgradeFile()
{
}
CUpgradeFile::~CUpgradeFile()
{
DELETE(m_ptrSuccPackMark);
}
/////////////////////////////////////////////////////////////
void CUpgradeFile::SendErrorMessagePackage(unsigned char ErrorCode)
{
extern unsigned short int gIntervalTimeout;
unsigned char SendBuffer[12]={0x0,0x07,0x01,0xB9,ErrorCode};
cprintf("\r\n\tSend Error Code %02X ",ErrorCode);
RuningOK();
gDataPort.SendDataPackage(SendBuffer);
gIntervalTimeout=18;while(gIntervalTimeout) ;
gDataPort.SendDataPackage(SendBuffer);
gIntervalTimeout=9;while(gIntervalTimeout) ;
}
//從數據包獲得升級數據參數0=OK 1=ERROR
short CUpgradeFile::ReadUpgradeParameter(const unsigned char *ptrData)
{
m_UnSuccFileCount=*(ptrData+0);//最后文件(標識)
m_UprModel=*(ptrData+1);//升級模式 1=單工 2=其他
m_lFileLen=ftonl(ptrData+2);//升級文件長度
m_uPackageSize=ftons(ptrData+6);//升級文件每包大小
m_uPackageCount=ftons(ptrData+8);;//升級包數。
m_lFileCrcCode1=ftonl(ptrData+10);//升級文件最終校驗碼
m_lFileCrcCode2=ftonl(ptrData+14);//升級文件最終校驗碼
memcpy(m_strFileName,ptrData+18,64);//升級文件名
m_strFileName[64]=0;
if(m_lFileCrcCode1!=m_lFileCrcCode2
|| m_uPackageSize==0
|| m_uPackageSize%512!=0
|| (m_lFileLen+m_uPackageSize-1)/m_uPackageSize!=m_uPackageCount
|| strlen(m_strFileName)==0)
{
m_lFileLen=m_uPackageSize=m_uPackageCount=0;
m_strFileName[0]=0;
return 1;
}
return 0;
}
short CUpgradeFile::CheckDiskFreeSpace(unsigned long newFileLen)//0=OK 1=不足
{
struct dfree free;
getdfree(getdisk()+1, &free);//獲得當前磁盤的基本信息。
//每族字節數.每一文件按簇分配,不足一簇使用一簇
unsigned short BytesPerCluster=free.df_bsec*free.df_sclus;
newFileLen=(newFileLen+BytesPerCluster-1)/BytesPerCluster;//升級文件占有簇數
if(free.df_avail<newFileLen) return 1;
return 0;
}
/////////////////////////////////////////////////////////////
void CUpgradeFile::CreateSuccMarkFile()
{
FILE *fp;
cprintf("\r\n ----Create Succ Mark File \\\\uprade!!.OK----");
fp=fopen(constUpgradeOKFileName,"w");
fprintf(fp,"OK");
fclose(fp);
}
//主動發送連接信息(計算機編號)和上位通信協商,每550毫秒發送一次,等待0xB1協議或等待50秒。
short CUpgradeFile::Operate_SendB0_WaitB1()//發送B0等待連接協商
{
extern unsigned long GetCurComputerNo();
static unsigned long ComputerNo=GetCurComputerNo();
unsigned char SendBuffer[16]={0x0,0x0A,0x01,0xB0};
*(unsigned long*)(SendBuffer+4)=ftonl(ComputerNo);
cprintf("\r\nWait Connect.");
int k=12;
unsigned char ReturnCode;
while(k)
{
RuningOK();
gDataPort.SendDataPackage(SendBuffer);
ReturnCode=gDataPort.ReceiveDataPackage(mBuffer);
if(ReturnCode==0xB1)
{
cprintf("..OK. ");
return 0;
}
else if(ReturnCode==0xB9)
{
cprintf("\r\n...Fail(Recv Stop Command).");
return 1;
}
k--;
cprintf("%u ",k);
}
cprintf("..Fail(Over Time). ");
return 1;
}
//收到B1協商數據,建立文件等等。直到收到B2數據包為止。
short CUpgradeFile::Operate_SendB1_WaitB2()//發送B1等待傳輸數據
{
unsigned char SendBuffer[12]={0x0,0x07,0x01,0xB1,0xF0};
unsigned char ReturnCode;
if(mBuffer[3]!=0xB1) return 1;
//準備建立升級文件
ReturnCode=Handle_0xB1();
if(ReturnCode) {SendErrorMessagePackage(ReturnCode);return 1;}
DELETE(m_ptrSuccPackMark);
m_ptrSuccPackMark=new char[m_uPackageCount];
if(m_ptrSuccPackMark==NULL){SendErrorMessagePackage(0xF1);return 1;}
memset(m_ptrSuccPackMark,0,m_uPackageCount);
m_SuccPackCount=0;
m_CurRecvFileIndex=0;
//產生wenjianOK,等待發送數據
gDataPort.SendDataPackage(SendBuffer);//發送
gSecondTimeout=60;
while(gSecondTimeout)
{
RuningOK();
ReturnCode=gDataPort.ReceiveDataPackage(mBuffer);
if(ReturnCode==0xB2) return 0;
else if(ReturnCode==0xB9)
{
cprintf("\r\n...Fail(Recv Stop Command).");
return 1;
}
else if(ReturnCode) gDataPort.SendDataPackage(SendBuffer);//發送
else cprintf("+");
}
cprintf("..Fail(Over Time). ");
SendErrorMessagePackage(0xF1);
return 1;
}
//收到數據包回答是否學要需要數據,直到所有數據全部收到。只能接受B2或B9。
short CUpgradeFile::Operate_SendB2_WaitTransDataEND()//發送B2等待傳輸數據或新協商
{
unsigned char ReturnCode;
HAVE_NEW_DATA:
if(mBuffer[3]==0xB2)//肯定是數據包B2協議。本來是多余,為了防止程序有錯
{
Handle_0xB2();
if(m_SuccPackCount==m_uPackageCount) return 0;//升級數據接受完成,等待校驗。
Handle_Answer_0xB2();
}
//等待新數據
gSecondTimeout=60;
for(;;)
{
RuningOK();
if(gSecondTimeout==0)
{
cprintf("...Over Time.");
SendErrorMessagePackage(0xF1);
break;
}
ReturnCode=gDataPort.ReceiveDataPackage(mBuffer);
if(ReturnCode==0xB2) goto HAVE_NEW_DATA;
else if(ReturnCode==0xB9)
{
cprintf("\r\n...Fail(Recv Stop Command).");
break;
}
else if(ReturnCode)
{
SendErrorMessagePackage(0xF2);
break;
}
else cprintf("+");
}
return 1;
}
//數據已經接受完成,等待檢驗文件CRC碼,等待新的協商
short CUpgradeFile::Operate_SendTransDataEND_WaitB1()//發送傳輸數據結束等待新文件協商
{
unsigned char ReturnCode;
//回答數據包
unsigned char SendBuffer[12]={0x0,0x0A,0x01,0xB2};
*(unsigned short *)(SendBuffer+4)=ftons(m_SuccPackCount);//正確包數
*(unsigned short *)(SendBuffer+6)=0L;//需重發包數
//校驗文件CRC碼。
FCLOSE(ptrFile);
if(CheckFileCrcCode()) //文件校驗碼錯
{
cprintf("\r\nFile CRC Error");
SendErrorMessagePackage(0xF7);
return 1;
}
cprintf("\r\nFile %s Uprgade OK!!!",m_strFileName);
DELETE(m_ptrSuccPackMark);
gDataPort.SendDataPackage(SendBuffer);
cprintf("%4c",'O');
//如果是最后一個文件。
if(m_UnSuccFileCount==0)//最后一文件。
{
CreateSuccMarkFile();
gSecondTimeout=20;
while(gSecondTimeout)
{
ReturnCode=gDataPort.ReceiveDataPackage(mBuffer);
if(ReturnCode==0xB9) break;
else if(ReturnCode)
{
gDataPort.SendDataPackage(SendBuffer);
cprintf("%4c",'O');
}
else cprintf("+");
}
cprintf("\r\nUprgade Succeed!!!");
return 1;
}
gSecondTimeout=60;
for(;;)
{
if(gSecondTimeout==0)
{
cprintf("..Fail(Over Time). ");
SendErrorMessagePackage(0xF1);
break;
}
ReturnCode=gDataPort.ReceiveDataPackage(mBuffer);
if(ReturnCode==0xB1) return 0;
else if(ReturnCode==0xB9)
{
cprintf("\r\n...Fail(Recv Stop Command).");
break;
}
else if(ReturnCode)
{
gDataPort.SendDataPackage(SendBuffer);
cprintf("%4c",'A');
}
else cprintf("+");
}
return 1;
}
void CUpgradeFile::Start()
{
Teststack();
//刪除文件 \\uprade!!.OK
unlink(constUpgradeOKFileName); //刪除文件uprade!!.OK
m_ptrSuccPackMark=NULL;
m_SuccPackCount=0;
if(Operate_SendB0_WaitB1()) return ;
RuningOK();
for(;;)
{
RuningOK();
if(Operate_SendB1_WaitB2()) return ;//返回數據B2協議,發送B1等待傳輸數據
if(Operate_SendB2_WaitTransDataEND()) return ;//發送B2等待傳輸數據結束,
if(Operate_SendTransDataEND_WaitB1()) return;//校驗文件CRC,發送傳輸數據結束等待新文件協商
}
DELETE(m_ptrSuccPackMark);
FCLOSE(ptrFile);
cprintf("\r\n");
}
////////////////////////////////////////////////////////////////////
//F1=錯誤或人為停止升級、F2=協議(未知)錯誤
//F3=產生文件錯誤、F4=升級磁盤空間不夠、F5=磁盤讀寫錯誤、
unsigned char CUpgradeFile::Handle_0xB1()//返回0=OK,其它=錯誤碼
{
//從0xB1協議數據mBuffer中獲得升級參數。
if(ReadUpgradeParameter(mBuffer+4)) return 0xF2;//F2=協議(未知)錯誤
//產生一個升級空文件
cprintf("\r\n Create Upgrade File %s..",m_strFileName);
cprintf("\r\n(%u)Len %lu,PackageSize %u ,PackCount %u,Name:%s",m_UnSuccFileCount,m_lFileLen, m_uPackageSize,m_uPackageCount,m_strFileName);
if(m_lFileLen==0 ||m_uPackageCount==0)
{
cprintf("\r\n\t!!!FileLen=0,Upgrade Fail!!! ");
return 0xF8;//升級文件,包數不能為0
}
ptrFile=fopen(m_strFileName,"wb");
if(!ptrFile)
{
cprintf("..Error(File Name Error).");
return 0xF3;//F3=產生文件錯誤
}
RuningOK();
//檢查磁盤空間是否夠。
if(CheckDiskFreeSpace(m_lFileLen))
{
FCLOSE(ptrFile);
unlink(m_strFileName);
cprintf("..Error(disk Free Space too small).");
return 0xF4;//F4=升級磁盤空間不夠
}
cprintf("..OK");
//產生給定大小的磁盤文件
unsigned long k=m_lFileLen;
memset(mBuffer,0,2048);
while(k>=2048)
{
RuningOK();
if(fwrite(mBuffer,2048,1,ptrFile)!=1) goto CREATE_ERROR_END;
k-=2048;
}
if(k) if(fwrite(mBuffer,(unsigned short)k,1,ptrFile)!=1) goto CREATE_ERROR_END;
FCLOSE(ptrFile);
//檢驗產生文件大小是否成功,并打開讀寫。
ptrFile=fopen(m_strFileName,"rb+");
if(ptrFile)
{
fseek(ptrFile,0,SEEK_END);
if(ftell(ptrFile)!=(long)m_lFileLen) goto CREATE_ERROR_END;
}
cprintf("\r\n Waiting Transmit File Data(Succ Count): \r\n");
return 0;
CREATE_ERROR_END:
FCLOSE(ptrFile);
unlink(m_strFileName);
cprintf("\r\n...Disk have Error!!!!");
return 0xF5;//F5=磁盤讀寫錯誤
}
short CUpgradeFile::Handle_Check_0xB1()//返回0=和上次協商一致,1=不一致
{
const unsigned char *ptrData=mBuffer+4;
if(m_UnSuccFileCount==*(ptrData+0)
&&m_UprModel==*(ptrData+1)
&&m_lFileLen==ftonl(ptrData+2)
&&m_uPackageSize==ftons(ptrData+6)
&&m_uPackageCount==ftons(ptrData+8)
&&m_lFileCrcCode1==ftonl(ptrData+10)
&&m_lFileCrcCode2==ftonl(ptrData+14)
&& stricmp(m_strFileName,(char*)(ptrData+18))==0
) return 0;
return 1;
}
short CUpgradeFile::Handle_0xB2()//0=數據OK 其它=錯誤。
{
unsigned short int FileDataLen=((mBuffer[0]<<8)|mBuffer[1])-6-2;
unsigned short int FileIndex=((mBuffer[4]<<8)|mBuffer[5]);
unsigned char *ptrFileData=(mBuffer+6);
if(FileIndex>=m_uPackageCount)
{
return 1;
}
else if(FileIndex==m_uPackageCount-1) //最后一包
{
if(m_lFileLen!=(m_uPackageCount-1)*(unsigned long)m_uPackageSize+FileDataLen) return 1;
gArriveAnswerTime=0;
}
else//其他包
{
if(FileDataLen!=m_uPackageSize ) return 1;
}
if(m_ptrSuccPackMark[FileIndex]==0)
{
m_SuccPackCount++;
m_ptrSuccPackMark[FileIndex]=1;
fseek(ptrFile,(long)FileIndex*m_uPackageSize,SEEK_SET);
fwrite(ptrFileData,FileDataLen,1,ptrFile);
cprintf("%4u",m_SuccPackCount);
}
m_CurRecvFileIndex=FileIndex;
return 0;
}
short CUpgradeFile::Handle_Answer_0xB2()//每5秒會一包數據包。單工沒收到一包就就回一包
{
short ReSendCount=0;
if(m_SuccPackCount<(m_CurRecvFileIndex+1))//需重發包數
{
unsigned short *ptrReSendIndex=(unsigned short *)(mBuffer+8);
unsigned short int i;
for(i=0;i<=m_CurRecvFileIndex && ReSendCount<16;i++)
{
if(m_ptrSuccPackMark[i]==0)
{
*ptrReSendIndex=ftons(i);
ptrReSendIndex++;
ReSendCount++;
}
}
}
*(unsigned short *)mBuffer=ftons(6+4+ReSendCount*2);//長度
mBuffer[2]=0x01;
mBuffer[3]=0xB2;
*(unsigned short *)(mBuffer+4)=ftons(m_SuccPackCount);//正確包數
*(unsigned short *)(mBuffer+6)=ftons(ReSendCount);//需重發包數
gDataPort.SendDataPackage(mBuffer);
cprintf("%4c",'A');
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////
short CUpgradeFile::CheckFileCrcCode()//0=OK 1=錯誤
{
unsigned long CrcCode=0;
long k=0;
FILE *fp;
fp=fopen(m_strFileName,"rb");
if(!fp) return 1;
fseek(fp,0,SEEK_END);
if(ftell(fp)!=(long)m_lFileLen) {FCLOSE(fp);return 1;}
fseek(fp,0,SEEK_SET);
for(k=m_lFileLen;k>=2048;k-=2048)
{
RuningOK();
fread(mBuffer,2048,1,fp);
CrcCode=gCrcCode.Crc32Mtt(mBuffer,2048,CrcCode);
}
if(k) fread(mBuffer,(short)k,1,fp);
CrcCode=gCrcCode.Crc32Mtt(mBuffer,k,CrcCode);
FCLOSE(fp);
// cprintf("\r\nCRC=%lX CRc1=%lX CRC2=%lX",CrcCode,m_lFileCrcCode1,m_lFileCrcCode2);
if(CrcCode==m_lFileCrcCode1 && CrcCode==m_lFileCrcCode2) return 0;
return 1;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -