123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- #include "includes.h"
- SUT_FOTA_PARA sutFotaPara;
- static void IapGetUpdateVersion(void);
- static void IapGetUpdateData(uint32_t offset,uint16_t len);
- static char IapCheckFileMD5_SPI_Flash(unsigned int dataAddr,unsigned int length,uint8_t *MD5);
- void FotaDataInit(void)
- {
- memset((unsigned char *)&sutFotaPara, 0, sizeof(sutFotaPara));
- sutFotaPara.fotaFlag=FOTA_OFF;
- }
- void TriggerFotaOption(FOTA_TYPE fotaStatus)
- {
- char buf[20];
- sutFotaPara.fotaFlag=fotaStatus;
- if(FOTA_ON==fotaStatus) return;
- if(sutFotaPara.init_tcpStatus!=0)
- {
-
- snprintf(buf,sizeof(buf), "AT+ZIPCLOSE=%c", FOTA_SOCKET);
- ModemSendAT(buf);
- sutFotaPara.init_tcpStatus=0;
- }
- sutFotaPara.fotaStatus=LOAD_GET_FILEINFO;
- }
- void FotaHandle(void)
- {
- char buf[40];
-
- if(sutFotaPara.fotaFlag == FOTA_OFF) return;
- if(sutSysStatus.init_tcpStatus!=0)
- {
- snprintf(buf,sizeof(buf), "AT+ZIPCLOSE=%c", DATA_SOCKET);
- ModemSendAT(buf);
- sutSysStatus.init_tcpStatus=0;
- }
- if(sutFotaPara.init_tcpStatus==0)
- {
- sutFotaPara.time_10ms_cnt=os_time;
- return;
- }
- switch(sutFotaPara.fotaStatus)
- {
- case LOAD_GET_FILEINFO://获取文件信息
- //最多尝试三次
- if(os_time > sutFotaPara.time_10ms_cnt)
- {
- sutFotaPara.time_10ms_cnt=os_time+TIMEOUT_10MS_FILE;//5秒进行一次文件信息获取
- if(++sutFotaPara.retryTime > MAX_TIME_GET_FILE)
- {//三次获取文件不成功
- SlwTrace(INF, "ReqFileFailed",1);
- sutFotaPara.fotaStatus=LOAD_DONE;
- }else{
- SlwTrace(INF, "FotaVersion_req",1);
- IapGetUpdateVersion();
- }
- }
- break;
- case LOAD_GET_FILEDATA://拉取文件内容
- //最多重新发起五次文件数据重传
- if(os_time > sutFotaPara.time_10ms_cnt)
- {
- sutFotaPara.time_10ms_cnt=os_time+TIMEOUT_10MS_DATA;//3秒后没有数据应答,重新发起请求
- if(++sutFotaPara.retryTime > MAX_TIME_GET_DATA)
- {//5次重传都不成功
- SlwTrace(INF, "ReqDataFailed",1);
- sutFotaPara.fotaStatus=LOAD_DONE;
- }else{
- SlwTrace(INF, "FotaData_req",1);
- IapGetUpdateData(sutFotaPara.lastOffset,DATA_DRAT_SIZE_PER_TIME);
- }
- }
- break;
- case LOAD_FILE_CHECK://较验文件MD5
- if(0!=IapCheckFileMD5_SPI_Flash(APP_FILE_DATA_ADDR, sutFotaPara.fileLength, sutFotaPara.MD5))
- {//较验成功,准备跳转到IAP前准备
- memcpy(sutProductPara.MD5, sutFotaPara.MD5,sizeof(sutProductPara.MD5));
- sutProductPara.ExAddr=APP_FILE_DATA_ADDR;
- sutProductPara.AppLen=sutFotaPara.fileLength;
- memcpy(sutProductPara.FoTaMark, "FoTa", 4);
- SaveParaToInterFlash();
- SlwTrace(INF, "GoingUpdate",1);
- WdgsFeed();
- while(1);
- }else{
- SlwTrace(INF, "Md5Err",1);
- sutFotaPara.fotaStatus=LOAD_DONE;
- }
- break;
- case LOAD_DONE://完成操作
- SlwTrace(INF, "FotaQuit",1);
- TriggerFotaOption(FOTA_OFF);
- break;
- }
- }
- void HGS_FotaHandle(unsigned char *data, unsigned short len)
- {
- unsigned char *p=data;
- unsigned short i,realDataLen,thisLen;
- unsigned char sum;
- unsigned int thisOffset;
- char info[30];
- SUT_FILE_INFO *pFileInfo;
- SUTDS ds;
- SUTDL dl1;
- SUTDL dl2;
-
- //判断包头标识
- if(PACKET_HEAD != p[0])
- {
- SlwTrace(INF, "HeaderErr",1);
- return;
- }
- //检测长度
- ds.Data.ucData.b2=p[2];
- ds.Data.ucData.b1=p[3];
- realDataLen=ds.Data.usData;
- if(len != (realDataLen+4))
- {
- SlwTrace(INF, "LenghtErr",1);
- return;
- }
- //检测校验和
- sum=0;
- for(i=0;i<len-1;i++) sum ^= p[i];
- if(sum != p[len-1])
- {
- SlwTrace(INF, "SumErr",1);
- return;
- }
- //包正常,处理数据
- switch(p[1])//cmd type
- {
- case CMD_GET_FILE_INFO_ACK:
- pFileInfo=(SUT_FILE_INFO *)&p[4];
- snprintf(info,sizeof(info), "%s_V%d.bin", sutProductPara.ProductName,sutFotaPara.targetVersion);
- if(0!=strcmp(pFileInfo->FileName, info))
- {
- SlwTrace(INF, "FNameErr",1);
- return;
- }
- dl1.Data.ulData=pFileInfo->FileLength;
- dl2.Data.ucData.b1=dl1.Data.ucData.b4;
- dl2.Data.ucData.b2=dl1.Data.ucData.b3;
- dl2.Data.ucData.b3=dl1.Data.ucData.b2;
- dl2.Data.ucData.b4=dl1.Data.ucData.b1;
- sutFotaPara.fileLength=dl2.Data.ulData;
- sutFotaPara.encrypted=pFileInfo->encrypted;
- sutFotaPara.key=pFileInfo->key;
- memcpy(sutFotaPara.MD5,pFileInfo->MD5,16);
- if(sutFotaPara.fileLength==0)
- {//服务器没有文件,退出升级
- SlwTrace(INF, "NoFileInServer",1);
- sutFotaPara.fotaStatus=LOAD_DONE;
- return;
- }
- sutFotaPara.fotaStatus=LOAD_GET_FILEDATA;
- sutFotaPara.lastOffset=0;
- sutFotaPara.time_10ms_cnt=os_time+TIMEOUT_10MS_DATA;
- IapGetUpdateData(sutFotaPara.lastOffset,DATA_DRAT_SIZE_PER_TIME);
- break;
- case CMD_GET_FILE_DATA_ACK:
- //offset
- dl1.Data.ucData.b4=p[4];
- dl1.Data.ucData.b3=p[5];
- dl1.Data.ucData.b2=p[6];
- dl1.Data.ucData.b1=p[7];
- thisOffset=dl1.Data.ulData;
- //lenght
- ds.Data.ucData.b2=p[8];
- ds.Data.ucData.b1=p[9];
- thisLen=ds.Data.usData;
- //save
- sFlash_Write(p+10,APP_FILE_DATA_ADDR+thisOffset,thisLen);
- //done?
- if((thisOffset+thisLen) >= sutFotaPara.fileLength)
- {
- snprintf(info,sizeof(info), "\r\nHBD=%d\r\nLoad done",sutFotaPara.fileLength);
- SlwTrace(INF, info, 1);
- sutFotaPara.fotaStatus=LOAD_FILE_CHECK;
- }else{
- sutFotaPara.time_10ms_cnt=os_time+TIMEOUT_10MS_DATA;
- sutFotaPara.lastOffset=thisOffset+thisLen;
- snprintf(info,sizeof(info), "\r\nHBD=%d",sutFotaPara.lastOffset);
- SlwTrace(INF, info, 1);
- IapGetUpdateData(sutFotaPara.lastOffset, DATA_DRAT_SIZE_PER_TIME);
- }
- break;
- default:
- snprintf(info,sizeof(info), "SkipCmd:0x%02x",p[1]);
- SlwTrace(INF, info,1);
- break;
- }
- }
- /////////////////////////////////////////////////////////////////
- /*******************************************************************
- 封包,获取新版本文件信息
- |Head|Cmd|length(2) | data... | Check|
- Head 包头,固定为0xAB
- Cmd 命令字
- length 后续的数据长度,包括到Check的长度 length=1+data.len
- Check 从Head开始按字节异或运算
- data:
- unsigned long PSN;//终端编号
- char FileName[20];//文件名,不够的在末尾补0
- 总长 24+5=29 bytes
- *******************************************************************/
- unsigned short PacketGetFileInfo(unsigned char *buf)
- {
- unsigned char checksum;
- unsigned short i,j,k;
- char FileName[21];
-
- SUTDL dl;
- SUTDS ds;
- j=0;
- memset(buf,0,29);
- buf[j++]=PACKET_HEAD;
- buf[j++]=CMD_GET_FILE_INFO;
- buf[j++]=0;
- buf[j++]=24+1;//数据24字节,1字节checksum
- //PSN
- dl.Data.ulData=sutProductPara.PSN; //因为协议要求大端模式传输,所以需要转一下
- buf[j++]=dl.Data.ucData.b4;
- buf[j++]=dl.Data.ucData.b3;
- buf[j++]=dl.Data.ucData.b2;
- buf[j++]=dl.Data.ucData.b1;
- //FileName
- snprintf(FileName,sizeof(FileName), "%s_V%d.bin", sutProductPara.ProductName,sutFotaPara.targetVersion);
- for(i=0;i<20;i++){
- buf[j++]=FileName[i];
- }
- //校验
- checksum=0;
- for(i=0;i<j;i++){
- checksum=checksum^buf[i];
- }
- buf[j++]=checksum;
- return j;
- }
- static void IapGetUpdateVersion(void)
- {
- unsigned short len;
- unsigned char txbuf[29];
- len=PacketGetFileInfo(txbuf);
- ModemSendData(FOTA_SOCKET,txbuf,len);
- }
- /*******************************************************************
- 封包,获取新版本
- |Head|Cmd|length(2) | data... | Check|
- Head 包头,固定为0xAB
- Cmd 命令字
- length 后续的数据长度,包括到Check的长度 length=1+data.len
- Check 从Head开始按字节异或运算
- data:
- unsigned long PSN; //终端编号
- unsigned char FileName[20]; //文件名 如:RT101_V102.bin
- unsigned long offset; //请求数据在文件中的开始位置
- unsigned short len; //请求数据的长度,服务器返回的数据可能小于等于此长度
- *******************************************************************/
- unsigned short PacketGetFileData(unsigned char *buf,unsigned int offset,unsigned short len)
- {
- unsigned char checksum;
- unsigned short i,j;
- char FileName[21];
- SUTDL dl;
- SUTDS ds;
- j=0;
- memset(buf,0,35);
- buf[j++]=PACKET_HEAD;
- buf[j++]=CMD_GET_FILE_DATA;
- buf[j++]=0;
- buf[j++]=30+1;//数据18字节,1字节checksum
- //PSN
- dl.Data.ulData=sutProductPara.PSN; //因为协议要求大端模式传输,所以需要转一下
- buf[j++]=dl.Data.ucData.b4;
- buf[j++]=dl.Data.ucData.b3;
- buf[j++]=dl.Data.ucData.b2;
- buf[j++]=dl.Data.ucData.b1;
- //FileName
- snprintf(FileName,sizeof(FileName), "%s_V%d.bin", sutProductPara.ProductName,sutFotaPara.targetVersion);
- for(i=0;i<20;i++){
- buf[j++]=FileName[i];
- }
- //offset
- dl.Data.ulData=offset; //因为协议要求大端模式传输,所以需要转一下
- buf[j++]=dl.Data.ucData.b4;
- buf[j++]=dl.Data.ucData.b3;
- buf[j++]=dl.Data.ucData.b2;
- buf[j++]=dl.Data.ucData.b1;
- //len
- ds.Data.usData=len;
- buf[j++]=ds.Data.ucData.b2;
- buf[j++]=ds.Data.ucData.b1;
- //校验
- checksum=0;
- for(i=0;i<j;i++){
- checksum=checksum^buf[i];
- }
- buf[j++]=checksum;
- return j;
- }
- static void IapGetUpdateData(uint32_t offset,uint16_t len)
- {
- unsigned short subLen;
- unsigned char txbuf[35];
- subLen=PacketGetFileData(txbuf,offset,len);
- ModemSendData(FOTA_SOCKET,txbuf,subLen);
- }
- static char IapCheckFileMD5_SPI_Flash(unsigned int dataAddr,unsigned int length,uint8_t *MD5)
- {
- MD5_CTX mdContext;
- unsigned char data[1024];
- unsigned long len,l;
- char tembuf[5];
- int i;
- MD5Init(&mdContext);
- len=0;
- while(len<length)
- {
- if((length-len)>1024)l=1024;
- else l=length-len;
- sFlash_Read(data,dataAddr+len,l);
- MD5Update(&mdContext,data,l);
- len+=l;
- }
- MD5Final(&mdContext);
- //check
- for(i=0;i<16;i++){
- if(MD5[i]!=mdContext.digest[i])break;
- }
- if(i<16)return 0;
- else return 1;
- }
- void FotaTest(void)
- {
- #if(FOTA_DEBUG==1) //测试空中升级用
- static unsigned char flag=0;
- static unsigned char tick=0;
- char info[30];
-
- if(flag!=0) return;
- if(++tick > 60)
- {
- SlwTrace(INF, "Test FotaOn",1);
- sutFotaPara.targetVersion=3000;
- flag=1;
- TriggerFotaOption(FOTA_ON);
- }else{
- snprintf(info,sizeof(info), "Tick:%d",tick);
- SlwTrace(INF, info, 1);
- }
- #endif
- }
|