DownFiles.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*****************************************************************************
  2. DownFiles.C
  3. *****************************************************************************/
  4. #include "includes.h"
  5. #include "DownFiles.h"
  6. #include "IAP.h"
  7. //static SUT_FILE_LIST sutFileList;//临时文件列表 只用于传输文件用,注意不要与FileSys.c定义的g_sutFilesList混淆!
  8. static uint16_t sFileIndex; //当前传输的文件在文件列表中的索引位置
  9. static uint32_t sFileDataOffset; //当前传输的文件偏移
  10. static uint32_t sFileDataLength; //当前传输的文件长度
  11. /*****************************************************************************************
  12. MakePCTFlistReq
  13. 生成请求文件列表数据
  14. ******************************************************************************************/
  15. int MakePctflistReq(char *txbuf)
  16. {
  17. SUT_DF_LIST_REQ *pDFListReq;
  18. pDFListReq=(SUT_DF_LIST_REQ *)txbuf;
  19. memset(pDFListReq,0,sizeof(SUT_DF_LIST_REQ));
  20. pDFListReq->Head.magic=PCTA_MAGIC;
  21. pDFListReq->Head.protocol=UPDATE_PROTOCOL_RFILE;
  22. pDFListReq->Head.code=DOWNLOAD_FILE_LIST_REQ;
  23. pDFListReq->Head.tid=0;
  24. pDFListReq->Head.count=sizeof(SUT_DF_LIST_REQ)-sizeof(SUT_DF_HEAD);
  25. pDFListReq->FileCountMax=FILE_COUNT_MAX;
  26. pDFListReq->FileNameLenMax=FILE_NAME_LEN_MAX;
  27. pDFListReq->FileAllDataLenMax=FILE_ALL_DATA_LEN_MAX;
  28. return sizeof(SUT_DF_LIST_REQ);
  29. }
  30. /*****************************************************************************************
  31. DFGetFileList
  32. 请求文件列表
  33. ******************************************************************************************/
  34. void DFGetFileList(void)
  35. {
  36. int len;
  37. len=MakePctflistReq((char *)TxBuffer1);
  38. Uart1Send((char *)TxBuffer1,len);
  39. }
  40. /*****************************************************************************************
  41. MakePCTFlistReq
  42. 生成请求文件列表数据
  43. ******************************************************************************************/
  44. int MakePctfFileDataReq(char *txbuf,uint16_t FileIndex,uint32_t offset,uint32_t length)
  45. {
  46. SUT_DF_DATA_REQ *pFileDataReq;
  47. pFileDataReq=(SUT_DF_DATA_REQ *)txbuf;
  48. memset(pFileDataReq,0,sizeof(SUT_DF_DATA_REQ));
  49. pFileDataReq->Head.magic=PCTA_MAGIC;
  50. pFileDataReq->Head.protocol=UPDATE_PROTOCOL_RFILE;
  51. pFileDataReq->Head.code=DOWNLOAD_FILE_DATA_REQ;
  52. pFileDataReq->Head.tid=0;
  53. pFileDataReq->Head.count=sizeof(SUT_DF_DATA_REQ)-sizeof(SUT_DF_HEAD);
  54. pFileDataReq->FileIndex=FileIndex;
  55. memcpy(&pFileDataReq->FileInfo,&g_sutFilesList.FileInfo[FileIndex],sizeof(SUT_FILE_INFO));
  56. pFileDataReq->length=length;
  57. pFileDataReq->offset=offset;
  58. return sizeof(SUT_DF_DATA_REQ);
  59. }
  60. /*****************************************************************************************
  61. DFGetFileData
  62. 请求文件数据
  63. ******************************************************************************************/
  64. void DFGetFileData(uint16_t FileIndex,uint32_t offset,uint32_t length)
  65. {
  66. int len;
  67. len=MakePctfFileDataReq((char *)TxBuffer1,FileIndex,offset,length);
  68. Uart1Send((char *)TxBuffer1,len);
  69. }
  70. /************************************************************************************
  71. *找出第一个不同的文件索引
  72. *************************************************************************************/
  73. int FindFirstDiffIndex(SUT_FILE_LIST *FileList)
  74. {
  75. int i;
  76. int j;
  77. for(i=0;i<g_sutFilesList.FileCount;i++){
  78. if(g_sutFilesList.FileInfo[i].FileLen!=FileList->FileInfo[i].FileLen)break;
  79. for(j=0;j<16;j++){
  80. if(g_sutFilesList.FileInfo[i].FileMD5[j]!=FileList->FileInfo[i].FileMD5[j])break;
  81. }
  82. if(j!=16)break;
  83. if(0!=strcmp(g_sutFilesList.FileInfo[i].FileName,FileList->FileInfo[i].FileName))break;
  84. }
  85. return i;
  86. }
  87. /************************************************************************************
  88. IapRecvMsgHandle
  89. 处理接收到的数据
  90. *************************************************************************************
  91. int DFRecvMsgHandle(unsigned char *pData, unsigned short DataLen)
  92. {
  93. int i;
  94. unsigned short crc,CRC16;
  95. unsigned short ReadBuf[4];
  96. char buf[200];
  97. uint32_t addr,len,offset;
  98. unsigned char code;
  99. unsigned short count;
  100. SUT_DF_HEAD *pHeader;
  101. SUT_DF_LIST_RSP *pListRsp;
  102. SUT_DF_DATA_RSP *pDataRsp;
  103. pHeader=(SUT_DF_HEAD *)pData;
  104. if(pHeader->magic != PCTA_MAGIC)return -1;
  105. if(pHeader->protocol != UPDATE_PROTOCOL_RFILE )return -2;
  106. code= pHeader->code;
  107. count= pHeader->count;
  108. if(code==DOWNLOAD_FILE_LIST_REQ){//PC响应文件列表
  109. if(count!=(sizeof(SUT_DF_LIST_RSP)-sizeof(SUT_DF_HEAD)))return -4;
  110. pListRsp= (SUT_DF_LIST_RSP *)pData;
  111. CRC16=pListRsp->FileListCRC;
  112. crc=crc16_calc(0,(uint8_t *)&pListRsp->FileList,sizeof(SUT_FILE_LIST));
  113. if(crc!=CRC16)return -5;
  114. if(pListRsp->FileList.FileCount==0)return 0;//文件个数为0,不用更新,直接完成
  115. #ifdef DOWNLOAD_DIFFERENT_FILE_ONLY //跳过前面相同的文件,只从第一个不相同的文件开始更新
  116. sFileIndex=FindFirstDiffIndex(&pListRsp->FileList);//即将更新文件的索引
  117. if(sFileIndex >= pListRsp->FileList.FileCount){//没有需要更新的,结束
  118. g_sutFilesList.FileCount=pListRsp->FileList.FileCount;
  119. g_sutFilesList.Mark=STORAGE_MARK;
  120. FileSysSaveIndex();//保存索引
  121. return 0;
  122. }
  123. g_sutFilesList.FileCount=pListRsp->FileList.FileCount;
  124. memcpy(&g_sutFilesList.FileInfo[sFileIndex],&pListRsp->FileList.FileInfo[sFileIndex],(pListRsp->FileList.FileCount-sFileIndex)*sizeof(SUT_FILE_INFO));
  125. #else //不判断是否文件相同都更新
  126. sFileIndex=0;
  127. memcpy(&g_sutFilesList,&pListRsp->FileList,sizeof(SUT_FILE_LIST));
  128. #endif
  129. sFileDataOffset=0;//即将更新文件数据的位置
  130. sprintf(buf,"RF Count=%lu\r\n",g_sutFilesList.FileCount);
  131. IapTrace(buf);
  132. sprintf(buf,"RF[%d]:%s len=%lu\r\n",sFileIndex,g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen);
  133. IapTrace(buf);
  134. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  135. return 1;
  136. }else if(code == DOWNLOAD_FILE_DATA_REQ){//PC响应文件数据申请
  137. pDataRsp = (SUT_DF_DATA_RSP*)pData;
  138. if(pDataRsp->FileInfo.FileLen!=g_sutFilesList.FileInfo[pDataRsp->FileIndex].FileLen \
  139. || pDataRsp->offset != sFileDataOffset || sFileIndex!=pDataRsp->FileIndex){//文件长度or 索引 or 偏移 不对?重新更新
  140. IapTrace("F-LEN-OFF err!ReDO!\r\n");
  141. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  142. return -6;
  143. }
  144. len=pDataRsp->length;
  145. len-=2;//实际数据长度应去掉2字节的CRC
  146. //CRC校验
  147. CRC16=crc16_calc(0,pDataRsp->data,len);
  148. crc=((unsigned short)pDataRsp->data[len+1]&0xff)<<8;
  149. crc+=(unsigned short)pDataRsp->data[len]&0xff;
  150. if(crc!=CRC16){
  151. //校验错误,申请重新下载
  152. IapTrace("CRC error!ReDO!\r\n");
  153. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  154. return -8;
  155. }
  156. //==CRC校验成功,更新FLASH ===
  157. sFlash_Write(pDataRsp->data,g_sutFilesList.FileInfo[sFileIndex].FileAddr+sFileDataOffset,len);
  158. if((len+sFileDataOffset)>=pDataRsp->FileInfo.FileLen){//完成当前文件下载
  159. if(sFileIndex==(g_sutFilesList.FileCount-1)){//判断所有文件是否下载完毕?
  160. //所有文件下载完毕,结束
  161. g_sutFilesList.Mark=STORAGE_MARK;
  162. FileSysSaveIndex();//保存索引
  163. return 0;
  164. }else{
  165. //校验本文件的MD5码,看是否正确,如不正确则重新下载本文件,如正确则切换下一文件
  166. if(0==FileCheckMD5(sFileIndex)){//MD5错误
  167. //重新下载
  168. sFileDataOffset=0;//即将更新文件数据的位置
  169. sprintf(buf,"RF[%d]:%s len=%lu\r\n",sFileIndex,g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen);
  170. IapTrace(buf);
  171. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  172. }else{//MD5正确
  173. //启动下一文件传输
  174. sFileIndex++;
  175. //下一个文件地址为上一个文件地址加上一个文件的长度
  176. g_sutFilesList.FileInfo[sFileIndex].FileAddr=g_sutFilesList.FileInfo[sFileIndex-1].FileAddr+g_sutFilesList.FileInfo[sFileIndex-1].FileLen;
  177. sFileDataOffset=0;//即将更新文件数据的位置
  178. sprintf(buf,"RF[%d]:%s len=%lu\r\n",sFileIndex,g_sutFilesList.FileInfo[sFileIndex].FileName,g_sutFilesList.FileInfo[sFileIndex].FileLen);
  179. IapTrace(buf);
  180. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  181. }
  182. }
  183. }else{
  184. //本文件传输未结束,启动下一包下载
  185. sFileDataOffset+=len;
  186. sprintf(buf,"offset=%d\r\n",sFileDataOffset);
  187. IapTrace(buf);
  188. DFGetFileData(sFileIndex,sFileDataOffset,4096);
  189. }
  190. return 2;
  191. }
  192. }
  193. */