| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- /*****************************************************************************
- DownFiles.C
- *****************************************************************************/
- #include "includes.h"
- #include "DownFiles.h"
- #include "IAP.h"
- unsigned short newListIndex[FILE_COUNT_MAX];//临时保存置换位置后的索引
- //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);
- #ifdef USE_NEW_FILE_SYSTEM
- pFileDataReq->FileIndex=newListIndex[FileIndex];
- #else
- pFileDataReq->FileIndex=FileIndex;
- #endif
- 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;i<g_sutFilesList.FileCount;i++){
- if(g_sutFilesList.FileInfo[i].FileLen!=FileList->FileInfo[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;
- }
- void RerangeList(SUT_FILE_LIST *FileList)
- {
- int i,j,w;
- SUT_FILE_INFO temp;
- for(w=0;w<FileList->FileCount;w++) newListIndex[w]=w;
- for(i=0;i<FileList->FileCount-1;i++){//如果刚好是最后那个是SYS_CONFIG,那不用置换了,故减1操作
- if(0==strcmp(FileList->FileInfo[i].FileName, SYS_CONFIG)){//找到了后,放在最后
- memcpy((unsigned char *)&temp, (unsigned char *)&FileList->FileInfo[i], sizeof(SUT_FILE_INFO));//备份
- for(j=i;j<FileList->FileCount-1;j++) memcpy((unsigned char *)&FileList->FileInfo[j], (unsigned char *)&FileList->FileInfo[j+1], sizeof(SUT_FILE_INFO));//结构体前移1
- memcpy((unsigned char *)&FileList->FileInfo[FileList->FileCount-1], (unsigned char *)&temp, sizeof(SUT_FILE_INFO));//备份的放最后
- for(w=i;w<FileList->FileCount-1;w++) newListIndex[w] = newListIndex[w+1];//文件索引前移1
- newListIndex[FileList->FileCount-1]=i;//备份索引放最后
- return;
- }
- }
- }
- void MakeTheEndFileIndicator(void)
- {
- //清除未使用的页,防止影响恢复逻辑
- SUT_FILE_PAGE_HEAD pageInfo;
- u32 endAddr;
-
- endAddr=g_sutFilesList.FileInfo[g_sutFilesList.FileCount-1].FileAddr+4096;
- endAddr += g_sutFilesList.FileInfo[g_sutFilesList.FileCount-1].FileLen;
- endAddr +=4096-(endAddr%4096) ;
- if(endAddr >= FILE_DATA_ADDR_END) return;//已到文件结尾,则不需要再生成结束标识
- pageInfo.mark=FILE_HEAD_END;
-
- sFlash_Write((unsigned char *)&pageInfo, endAddr, sizeof(SUT_FILE_PAGE_HEAD));
- }
- unsigned char buf[1024];//1024
- void CopyConfiToBckupFile(void)
- {
- unsigned int sourceAddr, desAddr, i,j;
- char ret=0;
-
- if(0 !=strcmp(g_sutFilesList.FileInfo[g_sutFilesList.FileCount-1].FileName, SYS_CONFIG)) ret=1;
- else if(g_sutFilesList.FileInfo[g_sutFilesList.FileCount-1].FileLen > 4096) ret=2;
-
- if(ret != 0){
- while(1){
- IapTrace("sys.ini err, stop\r\n");
- DelayMs(500);
- }
- }
-
- for(j=0;j<2;j++){
- sourceAddr=g_sutFilesList.FileInfo[g_sutFilesList.FileCount-1].FileAddr;
- desAddr=FILE_DATA_ADDR_END+1;
- if(j==0){//先拷贝数据区
- sourceAddr += 4096;
- desAddr += 4096;
- }
- for(i=0;i<4;i++){
- sFlash_Read(buf, sourceAddr, 1024);
- sFlash_Write(buf, desAddr, 1024);
- sourceAddr += 1024;
- desAddr += 1024;
- }
- }
- }
- /************************************************************************************
- IapRecvMsgHandle
- 处理接收到的数据
- *************************************************************************************/
- int DFRecvMsgHandle(unsigned char *pData, unsigned short DataLen)
- {
- int i,temp;
- unsigned short crc,CRC16;
- unsigned short ReadBuf[4];
- uint32_t addr,len,offset;
- unsigned char code;
- unsigned short count;
- #ifdef USE_NEW_FILE_SYSTEM
- SUT_FILE_PAGE_HEAD pageInfo;
- #endif
-
- 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 USE_NEW_FILE_SYSTEM
- //重新对PC响应过来的文件列表进行排序,将SYS_CONFIG_A与SYS_CONFIG_B放在最后
- RerangeList(&pListRsp->FileList);
- #endif
-
- #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;
- #ifndef USE_NEW_FILE_SYSTEM
- memcpy(&g_sutFilesList.FileInfo[sFileIndex],&pListRsp->FileList.FileInfo[sFileIndex],(pListRsp->FileList.FileCount-sFileIndex)*sizeof(SUT_FILE_INFO));
- #endif
- #else //不判断是否文件相同都更新
- sFileIndex=0;
- #ifndef USE_NEW_FILE_SYSTEM
- memcpy(&g_sutFilesList,&pListRsp->FileList,sizeof(SUT_FILE_LIST));
- #endif
- #endif
- #ifdef USE_NEW_FILE_SYSTEM
- for(i=sFileIndex;i<g_sutFilesList.FileCount;i++){
- if(i==0) g_sutFilesList.FileInfo[i].FileAddr=0;//从页头开始
- else{//下一个文件的首地址是前一个文件首地址加上页头加上文件长度
- temp=g_sutFilesList.FileInfo[i-1].FileLen%4096;
- g_sutFilesList.FileInfo[i].FileAddr=g_sutFilesList.FileInfo[i-1].FileAddr+4096+g_sutFilesList.FileInfo[i-1].FileLen;
- if(temp !=0) g_sutFilesList.FileInfo[i].FileAddr += (4096-temp);//非4K页首,再向后偏移至4K页首
- }
- g_sutFilesList.FileInfo[i].FileLen=pListRsp->FileList.FileInfo[i].FileLen;
- memcpy(g_sutFilesList.FileInfo[i].FileMD5, pListRsp->FileList.FileInfo[i].FileMD5, sizeof(g_sutFilesList.FileInfo[i].FileMD5));
- memcpy(g_sutFilesList.FileInfo[i].FileName, pListRsp->FileList.FileInfo[i].FileName, sizeof(g_sutFilesList.FileInfo[i].FileName));
- }
- #endif
- sFileDataOffset=0;//即将更新文件数据的位置
- sprintf(buf,"RFile Count=%lu\r\n",g_sutFilesList.FileCount);
- IapTrace(buf);
- sprintf(buf,"RFile[%d]:%s len=%lu\r\n",newListIndex[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;
- //sprintf(buf, "flen=%ld,%ld,index=%d,%d,%d,name=%s\r\n",pDataRsp->FileInfo.FileLen,g_sutFilesList.FileInfo[pDataRsp->FileIndex].FileLen,sFileIndex,newListIndex[sFileIndex],pDataRsp->FileIndex,pDataRsp->FileInfo.FileName);
- //IapTrace(buf);
- #ifdef USE_NEW_FILE_SYSTEM
- if(pDataRsp->FileInfo.FileLen!=g_sutFilesList.FileInfo[sFileIndex].FileLen ||
- #else
- if(pDataRsp->FileInfo.FileLen!=g_sutFilesList.FileInfo[pDataRsp->FileIndex].FileLen ||
- #endif
- pDataRsp->offset != sFileDataOffset ||
- newListIndex[sFileIndex]!=pDataRsp->FileIndex){//文件长度or 索引 or 偏移 不对?重新更新
- IapTrace("FLen or Offset 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 err!ReDO!\r\n");
- DFGetFileData(sFileIndex,sFileDataOffset,4096);
- return -8;
- }
- //==CRC校验成功,更新FLASH ===
- #ifndef USE_NEW_FILE_SYSTEM
-
- sFlash_Write(pDataRsp->data,g_sutFilesList.FileInfo[sFileIndex].FileAddr+sFileDataOffset,len);
- #else
- sFlash_Write(pDataRsp->data,g_sutFilesList.FileInfo[sFileIndex].FileAddr+4096+sFileDataOffset,len);//数据内容要偏移出页头
- #endif
- if((len+sFileDataOffset)>=pDataRsp->FileInfo.FileLen){//完成当前文件下载
- #ifdef USE_NEW_FILE_SYSTEM
- //校验本文件的MD5码,看是否正确,如果不正确则重新下载本文件,如正确则切换下一文件
- if(0==FileCheckMD5(sFileIndex)){//MD5错误
- //重新下载
- sFileDataOffset=0;//即将更新文件数据的位置
- sprintf(buf,"RFile[%d]:%s len=%lu\r\n",newListIndex[sFileIndex],g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen);
- IapTrace(buf);
- DFGetFileData(sFileIndex,sFileDataOffset,4096);
- }else{
- //MD5正确
- //更新信息页头并保存起来
- pageInfo.fLength=g_sutFilesList.FileInfo[sFileIndex].FileLen;
- memcpy(pageInfo.fName, g_sutFilesList.FileInfo[sFileIndex].FileName, sizeof(pageInfo.fName));
- memcpy(pageInfo.md5, g_sutFilesList.FileInfo[sFileIndex].FileMD5, sizeof(pageInfo.md5));
- pageInfo.mark=FILE_HEAD_MARK;
- if(sFileIndex==0) pageInfo.nextFileHeadAddr=FILE_INDEX_ADDR;
- else pageInfo.nextFileHeadAddr=g_sutFilesList.FileInfo[sFileIndex].FileAddr;
- temp=pageInfo.fLength%4096;
- pageInfo.nextFileHeadAddr += (pageInfo.fLength+4096);
- if(temp != 0) pageInfo.nextFileHeadAddr += (4096-temp);
- if((sFileIndex+1) >= g_sutFilesList.FileCount) pageInfo.nextFileHeadAddr=0;
-
-
- sFlash_Write((uint8_t *)&pageInfo, g_sutFilesList.FileInfo[sFileIndex].FileAddr, sizeof(SUT_FILE_PAGE_HEAD));
-
- if(++sFileIndex >= g_sutFilesList.FileCount){//判断所有文件是否下载完毕?
- //下载完毕,拷贝复制配置文件到备份区
- //CopyConfiToBckupFile();
- //结束
- return 0;
- }
- //未结束,启动下一个文件传输
- sFileDataOffset=0;//即将更新文件数据的位置
- sprintf(buf,"RFile[%d]:%s len=%lu\r\n",newListIndex[sFileIndex],g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen);
- IapTrace(buf);
- DFGetFileData(sFileIndex,sFileDataOffset,4096);
- }
- #else //旧文件格式时有一个问题:最后一个文件没有校验MD5的正确性
- 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,"RFile[%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,"RFile[%d]:%s len=%lu\r\n",sFileIndex,g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen);
- IapTrace(buf);
- DFGetFileData(sFileIndex,sFileDataOffset,4096);
- }
- }
- #endif
- }else{
- //本文件传输未结束,启动下一包下载
- sFileDataOffset+=len;
- sprintf(buf,"offset=%d %d%%\r\n",sFileDataOffset,100*sFileDataOffset/g_sutFilesList.FileInfo[sFileIndex].FileLen);
- //sprintf(buf,"offset=%d\r\n",sFileDataOffset);
- IapTrace(buf);
- DFGetFileData(sFileIndex,sFileDataOffset,4096);
- }
- return 2;
- }
- }
|