/***************************************************************************** DownFiles.C *****************************************************************************/ #include "includes.h" #include "DownFiles.h" #include "IAP.h" //static SUT_FILE_LIST sutFileList;//临时文件列表 只用于传输文件用,注意不要与FileSys.c定义的g_sutFilesList混淆! static uint16_t sFileIndex; //当前传输的文件在文件列表中的索引位置 static uint32_t sFileDataOffset; //当前传输的文件偏移 static uint32_t sFileDataLength; //当前传输的文件长度 /***************************************************************************************** MakePCTFlistReq 生成请求文件列表数据 ******************************************************************************************/ int MakePctflistReq(char *txbuf) { SUT_DF_LIST_REQ *pDFListReq; pDFListReq=(SUT_DF_LIST_REQ *)txbuf; memset(pDFListReq,0,sizeof(SUT_DF_LIST_REQ)); pDFListReq->Head.magic=PCTA_MAGIC; pDFListReq->Head.protocol=UPDATE_PROTOCOL_RFILE; pDFListReq->Head.code=DOWNLOAD_FILE_LIST_REQ; pDFListReq->Head.tid=0; pDFListReq->Head.count=sizeof(SUT_DF_LIST_REQ)-sizeof(SUT_DF_HEAD); pDFListReq->FileCountMax=FILE_COUNT_MAX; pDFListReq->FileNameLenMax=FILE_NAME_LEN_MAX; pDFListReq->FileAllDataLenMax=FILE_ALL_DATA_LEN_MAX; return sizeof(SUT_DF_LIST_REQ); } /***************************************************************************************** DFGetFileList 请求文件列表 ******************************************************************************************/ void DFGetFileList(void) { int len; len=MakePctflistReq((char *)TxBuffer1); Uart1Send((char *)TxBuffer1,len); } /***************************************************************************************** MakePCTFlistReq 生成请求文件列表数据 ******************************************************************************************/ int MakePctfFileDataReq(char *txbuf,uint16_t FileIndex,uint32_t offset,uint32_t length) { SUT_DF_DATA_REQ *pFileDataReq; pFileDataReq=(SUT_DF_DATA_REQ *)txbuf; memset(pFileDataReq,0,sizeof(SUT_DF_DATA_REQ)); pFileDataReq->Head.magic=PCTA_MAGIC; pFileDataReq->Head.protocol=UPDATE_PROTOCOL_RFILE; pFileDataReq->Head.code=DOWNLOAD_FILE_DATA_REQ; pFileDataReq->Head.tid=0; pFileDataReq->Head.count=sizeof(SUT_DF_DATA_REQ)-sizeof(SUT_DF_HEAD); pFileDataReq->FileIndex=FileIndex; memcpy(&pFileDataReq->FileInfo,&g_sutFilesList.FileInfo[FileIndex],sizeof(SUT_FILE_INFO)); pFileDataReq->length=length; pFileDataReq->offset=offset; return sizeof(SUT_DF_DATA_REQ); } /***************************************************************************************** DFGetFileData 请求文件数据 ******************************************************************************************/ void DFGetFileData(uint16_t FileIndex,uint32_t offset,uint32_t length) { int len; len=MakePctfFileDataReq((char *)TxBuffer1,FileIndex,offset,length); Uart1Send((char *)TxBuffer1,len); } /************************************************************************************ *找出第一个不同的文件索引 *************************************************************************************/ int FindFirstDiffIndex(SUT_FILE_LIST *FileList) { int i; int j; for(i=0;iFileInfo[i].FileLen)break; for(j=0;j<16;j++){ if(g_sutFilesList.FileInfo[i].FileMD5[j]!=FileList->FileInfo[i].FileMD5[j])break; } if(j!=16)break; if(0!=strcmp(g_sutFilesList.FileInfo[i].FileName,FileList->FileInfo[i].FileName))break; } return i; } /************************************************************************************ IapRecvMsgHandle 处理接收到的数据 ************************************************************************************* int DFRecvMsgHandle(unsigned char *pData, unsigned short DataLen) { int i; unsigned short crc,CRC16; unsigned short ReadBuf[4]; char buf[200]; uint32_t addr,len,offset; unsigned char code; unsigned short count; SUT_DF_HEAD *pHeader; SUT_DF_LIST_RSP *pListRsp; SUT_DF_DATA_RSP *pDataRsp; pHeader=(SUT_DF_HEAD *)pData; if(pHeader->magic != PCTA_MAGIC)return -1; if(pHeader->protocol != UPDATE_PROTOCOL_RFILE )return -2; code= pHeader->code; count= pHeader->count; if(code==DOWNLOAD_FILE_LIST_REQ){//PC响应文件列表 if(count!=(sizeof(SUT_DF_LIST_RSP)-sizeof(SUT_DF_HEAD)))return -4; pListRsp= (SUT_DF_LIST_RSP *)pData; CRC16=pListRsp->FileListCRC; crc=crc16_calc(0,(uint8_t *)&pListRsp->FileList,sizeof(SUT_FILE_LIST)); if(crc!=CRC16)return -5; if(pListRsp->FileList.FileCount==0)return 0;//文件个数为0,不用更新,直接完成 #ifdef DOWNLOAD_DIFFERENT_FILE_ONLY //跳过前面相同的文件,只从第一个不相同的文件开始更新 sFileIndex=FindFirstDiffIndex(&pListRsp->FileList);//即将更新文件的索引 if(sFileIndex >= pListRsp->FileList.FileCount){//没有需要更新的,结束 g_sutFilesList.FileCount=pListRsp->FileList.FileCount; g_sutFilesList.Mark=STORAGE_MARK; FileSysSaveIndex();//保存索引 return 0; } g_sutFilesList.FileCount=pListRsp->FileList.FileCount; memcpy(&g_sutFilesList.FileInfo[sFileIndex],&pListRsp->FileList.FileInfo[sFileIndex],(pListRsp->FileList.FileCount-sFileIndex)*sizeof(SUT_FILE_INFO)); #else //不判断是否文件相同都更新 sFileIndex=0; memcpy(&g_sutFilesList,&pListRsp->FileList,sizeof(SUT_FILE_LIST)); #endif sFileDataOffset=0;//即将更新文件数据的位置 sprintf(buf,"RF Count=%lu\r\n",g_sutFilesList.FileCount); IapTrace(buf); sprintf(buf,"RF[%d]:%s len=%lu\r\n",sFileIndex,g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen); IapTrace(buf); DFGetFileData(sFileIndex,sFileDataOffset,4096); return 1; }else if(code == DOWNLOAD_FILE_DATA_REQ){//PC响应文件数据申请 pDataRsp = (SUT_DF_DATA_RSP*)pData; if(pDataRsp->FileInfo.FileLen!=g_sutFilesList.FileInfo[pDataRsp->FileIndex].FileLen \ || pDataRsp->offset != sFileDataOffset || sFileIndex!=pDataRsp->FileIndex){//文件长度or 索引 or 偏移 不对?重新更新 IapTrace("F-LEN-OFF err!ReDO!\r\n"); DFGetFileData(sFileIndex,sFileDataOffset,4096); return -6; } len=pDataRsp->length; len-=2;//实际数据长度应去掉2字节的CRC //CRC校验 CRC16=crc16_calc(0,pDataRsp->data,len); crc=((unsigned short)pDataRsp->data[len+1]&0xff)<<8; crc+=(unsigned short)pDataRsp->data[len]&0xff; if(crc!=CRC16){ //校验错误,申请重新下载 IapTrace("CRC error!ReDO!\r\n"); DFGetFileData(sFileIndex,sFileDataOffset,4096); return -8; } //==CRC校验成功,更新FLASH === sFlash_Write(pDataRsp->data,g_sutFilesList.FileInfo[sFileIndex].FileAddr+sFileDataOffset,len); if((len+sFileDataOffset)>=pDataRsp->FileInfo.FileLen){//完成当前文件下载 if(sFileIndex==(g_sutFilesList.FileCount-1)){//判断所有文件是否下载完毕? //所有文件下载完毕,结束 g_sutFilesList.Mark=STORAGE_MARK; FileSysSaveIndex();//保存索引 return 0; }else{ //校验本文件的MD5码,看是否正确,如不正确则重新下载本文件,如正确则切换下一文件 if(0==FileCheckMD5(sFileIndex)){//MD5错误 //重新下载 sFileDataOffset=0;//即将更新文件数据的位置 sprintf(buf,"RF[%d]:%s len=%lu\r\n",sFileIndex,g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen); IapTrace(buf); DFGetFileData(sFileIndex,sFileDataOffset,4096); }else{//MD5正确 //启动下一文件传输 sFileIndex++; //下一个文件地址为上一个文件地址加上一个文件的长度 g_sutFilesList.FileInfo[sFileIndex].FileAddr=g_sutFilesList.FileInfo[sFileIndex-1].FileAddr+g_sutFilesList.FileInfo[sFileIndex-1].FileLen; sFileDataOffset=0;//即将更新文件数据的位置 sprintf(buf,"RF[%d]:%s len=%lu\r\n",sFileIndex,g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen); IapTrace(buf); DFGetFileData(sFileIndex,sFileDataOffset,4096); } } }else{ //本文件传输未结束,启动下一包下载 sFileDataOffset+=len; sprintf(buf,"offset=%d\r\n",sFileDataOffset); IapTrace(buf); DFGetFileData(sFileIndex,sFileDataOffset,4096); } return 2; } } */