AppIap.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. #include "includes.h"
  2. unsigned char Fota_Rcv_Pri_Flag=1;//IAP串口输出标志
  3. unsigned short g_usTid=0;
  4. //static unsigned char FileMD5[16];//={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  5. uint16_t ui_version;
  6. uint8_t resendPackage;
  7. //串口打印信息
  8. const char No_Login_In[] = "Logout!\r\n";
  9. const char Fota_Start[] = "Fota IAP start!\r\n";
  10. const char Ver_Ok_Dat_Start[] = "Ver req ok data req start!\r\n";
  11. const char Task_GoTo_App[] = "Task goto App!\r\n";
  12. const char MD5_Error[] = "MD5 err!\r\n";
  13. const char Len_Offset_Error[] = "len or offset err!\r\n";
  14. const char CRC_Error[] = "CRC err!\r\n";
  15. const char Resend_Package[] = "Resend last package!\r\n";
  16. const char Wait_Package_Timeout[] = "Package wait timeout!\r\n";
  17. const char Reboot[] = "Update done! rebooting\r\n";
  18. const char OtherLen_error[] = "otherLen < 46\r\n";
  19. const char Format_Not_Fit[] = "Invalid Header\r\n";
  20. const char ReTry_Failed[] = "Re-Try 3 time failed! %d\r\n";
  21. //语音部分
  22. const char VO_NO_LOGIN[] = "AT+LSHTTS=0,\"2A677B76555F\"\r";//未登陆
  23. const char APP_CHECK [] = "AT+LSHTTS=0,\"0B4E7D8F10629F52636B285721688C9A\"\r";//下载成功正在校验
  24. const char UP_APP_VER [] = "AT+LSHTTS=0,\"636B28570B4E7D8FF78B0D7A1950\"\r";//正在下载请稍候
  25. const char UP_PRO_VER [] = "AT+LSHTTS=0,\"636B2857B783D653B06548722C67\"\r";//正在获取新版本
  26. const char VOIC_NO_VER[] = "AT+LSHTTS=0,\"A16C0967EF53F466B06548722C67\"\r";//没有可更新版本
  27. const char VOIC_REBOOT[] = "AT+LSHTTS=0,\"2B52AD653575004E06529F94CD912F54\"\r";//别断电一分钟重启
  28. //下面不改
  29. const char App_Checking[] = " 下载成功正在校验 \r\n";
  30. const char Ver_Invalid[] = " 没有可更新版本 \r\n";
  31. const char Reboot_Mini[] = " 别断电一分钟重启 \r\n";
  32. const char UP_LOADING [] = "正在下载,请稍候... ";
  33. const char UPDATE_ING [] = "正在处理,请稍候... ";
  34. const char UPDATE_OK[] = " 下载完成 ";
  35. const char VER_REQ_ING[] = "正在获取新版本... ";
  36. const char EXIT_CANCLE[] = " [EXIT]取消";
  37. const char MESSG1 [] = "升级应用版本";
  38. const char MESSG3 [] = "[M]升级 [EXIT]退出";
  39. const char TRY_FAILED[] =" 下载失败 ";
  40. const char GET_FILE_ERR[] =" 获取文件失败 ";
  41. const char NET_OVERTIME_ERR[] =" 网络超时 ";
  42. const char SER_NO_FILE[] =" 服务器无文件 ";
  43. const char MD5_VRY_ERR[] =" 文件校验失败 ";
  44. static void MyIap_Init(void);
  45. static void NewTask(uint8_t);
  46. static void FotaSocketCtl(uint8_t);
  47. static void StartIAP(void);
  48. static void TickIAP(void);
  49. static void FotaSocketCtl(uint8_t);
  50. static void IapGetUpdateVersion_FOGA(void);
  51. static void IapGetUpdateData_FOGA(uint32_t offset,uint16_t len);
  52. static void ChangeDataToHex(char *, uint16_t );
  53. static int IapCheckFileMD5_SPI_Flash(uint8_t *,uint8_t,uint8_t);
  54. static void Door_Ctrl(uint8_t );
  55. static void SaveNewMD5(char *, char *);
  56. static char ChageAscii_To_Hex(char *);
  57. static void TryTimeCheck(uint8_t );
  58. static void UI_Process_Update(void);
  59. static void HBD_Ui_Update(uint8_t );
  60. static void IapAppStore(uint32_t , uint8_t *, uint16_t );
  61. static uint8_t DownLoaded_DataProcess(void);
  62. static uint8_t CopyFileListToFlash(SUT_FILE_LIST *, uint8_t);
  63. static void ExitRightNow(void);
  64. static uint32_t SaveLengthInFormat(char *dat);
  65. static uint8_t SetMark(uint32_t );
  66. ////////////////////////////
  67. SUT_NET_STATUS sutNetStatus;
  68. unsigned char fotaDatabuffer[DATA_DRAT_SIZE_PER_TIME+11];
  69. unsigned short fotaLen,reqLen;
  70. unsigned char getFirstPacked;
  71. ////启动IAP初始化
  72. void MyIap_Init(void)
  73. {
  74. FotaSocketCtl(1);
  75. memset((unsigned char *)&sutNetStatus,0,sizeof(SUT_NET_STATUS));
  76. NewTask(TASK_GET_FILEINFO);
  77. getFirstPacked=0;
  78. }
  79. ///////UI 选择
  80. void SetUpAppricationVerPending(void)
  81. {
  82. if(KEY_PANEL_EXIT == g_ulKeyValue){
  83. ExitRightNow();
  84. }
  85. if(netPPP != OPEN){//检测PPP就好了
  86. MeSpeak(ENCODE_ASCII, "CEDECDF8C2E7");//无网络
  87. ExitRightNow();
  88. SlwTrace(INF, (char *)No_Login_In,0);
  89. return;
  90. }
  91. StartIAP();
  92. TickIAP();
  93. UI_Process_Update();
  94. }
  95. ///////IAP状态切换
  96. static void NewTask(uint8_t task)
  97. {
  98. sutNetStatus.TaskStatus = task;
  99. sutNetStatus.TaskStart = 1;
  100. }
  101. static void StartIAP(void)
  102. {
  103. if(sutNetStatus.FotaTCP==0) return;
  104. if(!sutNetStatus.TaskStart) return;
  105. sutNetStatus.TaskStart = 0;
  106. switch(sutNetStatus.TaskStatus)
  107. {
  108. case TASK_GET_FILEINFO:
  109. //如果版本未请求--请求版本
  110. if(!sutNetStatus.FileReqOk) //版本请求
  111. IapGetUpdateVersion_FOGA();
  112. break;
  113. case TASK_GET_FILEDATA:
  114. SlwTrace(INF, (char *)Ver_Ok_Dat_Start,0);
  115. break;
  116. case TASK_FILE_CHECK:
  117. SlwTrace(INF, (char *)App_Checking,0);
  118. HBD_Ui_Update(2);
  119. break;
  120. case TASK_GOTO_APP:
  121. SlwTrace(INF, (char *)Task_GoTo_App,0);
  122. HBD_Ui_Update(3);
  123. break;
  124. }
  125. }
  126. ///////IAP处理///////////////
  127. static void TickIAP(void)
  128. {
  129. uint32_t len,offset;
  130. unsigned short crc,CRC16;
  131. char buf[50],temp[5];
  132. static unsigned char timeCnt;
  133. static unsigned char reTime=0;
  134. static unsigned char timeOutCnt=0;
  135. if(++sutNetStatus.Tick10ms > TICK_COUNT)
  136. {
  137. sutNetStatus.Tick10ms = 0;
  138. //process
  139. switch(sutNetStatus.TaskStatus)
  140. {
  141. case TASK_GET_FILEINFO:
  142. //请求版本过程--检测是否超时--超明重新请求
  143. if(0 == sutNetStatus.FileReqOk)
  144. {//超时未请求成功
  145. sutNetStatus.getFileInfoTime++;
  146. if(sutNetStatus.getFileInfoTime < GET_FILE_TIMES)
  147. {//再请求一次
  148. NewTask(TASK_GET_FILEINFO);
  149. }else{
  150. //重请求次数超了,退出
  151. sutNetStatus.errType=1;//获取文件失败
  152. NewTask(TASK_EXIT);
  153. }
  154. }else NewTask(TASK_GET_FILEINFO);
  155. break;
  156. case TASK_GET_FILEDATA:
  157. if(0 == sutNetStatus.FileReqOk)
  158. {//未请求文件,则请求文件
  159. NewTask(TASK_GET_FILEINFO);
  160. }else
  161. {
  162. //已请求成功,即下载数据时超时了
  163. sutNetStatus.getDataInfoTime++;
  164. if(sutNetStatus.getDataInfoTime < GET_DATA_TIMES)
  165. {//再请求一次
  166. SlwTrace(INF, "Req Data",1);
  167. IapGetUpdateData_FOGA(sutNetStatus.FileOffset,DATA_DRAT_SIZE_PER_TIME);
  168. }else{//重请求次数超了,退出
  169. sutNetStatus.errType=2;//网络不好,多次重请求数据超时
  170. NewTask(TASK_EXIT);
  171. }
  172. }
  173. break;
  174. case TASK_FILE_CHECK:
  175. //MD5总校验
  176. switch(IapCheckFileMD5_SPI_Flash(sutNetStatus.MD5,2,0))
  177. {
  178. case 0://OK
  179. NewTask(TASK_GOTO_APP);
  180. break;
  181. case 1://confinue
  182. sutNetStatus.errType=4;//MD5校验失败
  183. SlwTrace(INF, (char *)MD5_Error,0);
  184. NewTask(TASK_EXIT);
  185. break;
  186. }
  187. break;
  188. case TASK_GOTO_APP:
  189. SetMark(GOOD_UPDATE_STORAGE);
  190. SlwTrace(INF, (char *)Reboot,0);
  191. //rt_tsk_lock();//这样就不会切换任务,其它任务就不会喂狗
  192. //rt_suspend();
  193. while(1);
  194. break;
  195. case TASK_EXIT:
  196. GuiShowStr(4,40,TRY_FAILED,0x01,0);
  197. switch(sutNetStatus.errType)
  198. {
  199. case 1:
  200. GuiShowStr(4,70,GET_FILE_ERR,0x01,0);
  201. break;
  202. case 2:
  203. GuiShowStr(4,70,NET_OVERTIME_ERR,0x01,0);
  204. break;
  205. case 3:
  206. GuiShowStr(4,70,SER_NO_FILE,0x01,0);
  207. break;
  208. case 4:
  209. GuiShowStr(4,70,MD5_VRY_ERR,0x01,0);
  210. break;
  211. }
  212. //os_dly_wait(200);//后续需要增加
  213. ExitRightNow();
  214. break;
  215. }
  216. }
  217. ///////TCP 持续维持///////
  218. timeCnt++;
  219. if(timeCnt++ >=254)
  220. {
  221. timeCnt=0;
  222. reTime++;
  223. if(reTime < 3)
  224. {
  225. snprintf(buf, sizeof(buf), "AT+TCPSTATUS=%d\r\n", FOTA_IAP_SOCKET);
  226. ModemSendAt(buf);
  227. }else{
  228. reTime=0;
  229. if(sutNetStatus.FotaTCP==0) FotaSocketCtl(1);
  230. }
  231. }
  232. }
  233. static uint32_t SaveLengthInFormat(char *dat)
  234. {
  235. uint32_t temp,i;
  236. temp = 0;
  237. for(i=0;i<4;i++){
  238. temp <<= 8;
  239. temp |= (uint32_t)ChageAscii_To_Hex(dat+6-2*i);
  240. }
  241. return temp;
  242. }
  243. //针对FOTA升级时处理此终端UDP返回的数据
  244. void FotaIap_Handle(unsigned char *msg)
  245. {
  246. char buf[60];
  247. uint16_t i,j;
  248. uint16_t len1,len2;
  249. SUTDS ds;
  250. SUTDL dl1;
  251. SUTDL dl2;
  252. unsigned char *dataPtr;
  253. unsigned char cmd,checksum;
  254. SUT_FILE_INFO2 *pFileInfo;
  255. uint32_t toffset;
  256. STATUE ipStatus;
  257. if(!sutNetStatus.FotaTCP) return;
  258. IWDG_ReloadCounter();
  259. //1,数据拆包
  260. //1.1比较命令头,socket,IP,port,udp type
  261. //+TCPRECV:2,1,
  262. //+TCPRECV:2,1035,
  263. snprintf(buf, sizeof(buf), "+TCPRECV:%d,", FOTA_IAP_SOCKET);
  264. if(0 != strncmp((char *)msg, buf, 11)) return;
  265. //+TCPRECV:0,2,31
  266. len1=atoi((char *)&msg[11]);
  267. if(len1 < 5) return;//至少5个字节
  268. if(len1<10) dataPtr=&msg[13];
  269. else if(len1<100) dataPtr=&msg[14];
  270. else if(len1<1000) dataPtr=&msg[15];
  271. else if(len1<10000) dataPtr=&msg[16];
  272. else return;
  273. if(getFirstPacked == 0)
  274. {//首包
  275. if(dataPtr[0] != PACKET_HEAD)
  276. {
  277. SlwTrace(INF, "HErr1",1);
  278. return;
  279. }
  280. ds.Data.ucData.b2=dataPtr[2];
  281. ds.Data.ucData.b1=dataPtr[3];
  282. len2=ds.Data.usData;//packetLen
  283. if(len1 < (len2+4))
  284. {//有分包,此处作拷贝即可
  285. memcpy(fotaDatabuffer, dataPtr, len1);
  286. fotaLen=len1;
  287. getFirstPacked=1;
  288. reqLen=len2+4;
  289. //SlwTrace(INF, "I need next packet", 1);
  290. return;
  291. }else if(len1 == (len2+4))
  292. {//没有分包,可以直接包处理数据
  293. goto PACKED_READY;
  294. }else{//有问题包,不处理
  295. return;
  296. }
  297. }
  298. else{//分包
  299. if(fotaLen+len1 == reqLen)
  300. {
  301. if(reqLen <= sizeof(fotaDatabuffer))
  302. {
  303. memcpy(&fotaDatabuffer[fotaLen], dataPtr, len1);
  304. dataPtr=fotaDatabuffer;
  305. len1=reqLen;
  306. goto PACKED_READY;
  307. }else{
  308. SlwTrace(INF, "BufferOver", 1);
  309. return;
  310. }
  311. }else{
  312. //长度不对,丢弃
  313. SlwTrace(INF, "WLenErr",1);
  314. getFirstPacked=0;
  315. return;
  316. }
  317. }
  318. PACKED_READY:
  319. //check length
  320. if(dataPtr[0] != PACKET_HEAD)
  321. {
  322. SlwTrace(INF, "HErr2",1);
  323. return;
  324. }
  325. cmd=dataPtr[1];
  326. //check lenght
  327. ds.Data.ucData.b2=dataPtr[2];
  328. ds.Data.ucData.b1=dataPtr[3];
  329. len2=ds.Data.usData;
  330. if(len1!=(len2+4)){
  331. SlwTrace(INF,"lenErr",1);
  332. return;
  333. }
  334. //checksum
  335. checksum=0;
  336. for(i=0;i<(len2+3);i++){
  337. checksum^=dataPtr[i];
  338. }
  339. if(checksum!=dataPtr[len2+3]){
  340. SlwTrace(INF,"SumErr",1);
  341. return;
  342. }
  343. switch(cmd)
  344. {
  345. case CMD_GET_FILE_INFO_ACK:
  346. sutNetStatus.Tick10ms=0;
  347. pFileInfo=(SUT_FILE_INFO2 *)&dataPtr[4];
  348. if(0!=strcmp(pFileInfo->FileName,sutNetStatus.FullFileName)){
  349. SlwTrace(INF,"FileName error!",1);
  350. return;
  351. }
  352. //对于unsigned long类型的 FileLength 需要转换下高地位字节。因为网络传过来的是大端模式,MCU却是小端模式
  353. dl1.Data.ulData=pFileInfo->FileLength; //文件总长度
  354. dl2.Data.ucData.b1=dl1.Data.ucData.b4;
  355. dl2.Data.ucData.b2=dl1.Data.ucData.b3;
  356. dl2.Data.ucData.b3=dl1.Data.ucData.b2;
  357. dl2.Data.ucData.b4=dl1.Data.ucData.b1;
  358. sutNetStatus.FileLength=dl2.Data.ulData;
  359. sutNetStatus.encrypted=pFileInfo->encrypted;
  360. sutNetStatus.key=pFileInfo->key;
  361. memcpy(sutNetStatus.MD5,pFileInfo->MD5,16);
  362. if(sutNetStatus.FileLength==0)
  363. {
  364. sutNetStatus.errType=3;//服务器无请求的数据文件
  365. SlwTrace(INF, "No file",1);
  366. NewTask(TASK_EXIT);
  367. break;
  368. }
  369. if(sutNetStatus.FileLength%2!=0){
  370. SlwTrace(INF,"FLen is not even!",1);
  371. }
  372. NewTask(TASK_GET_FILEDATA);
  373. //请求文件数据
  374. sutNetStatus.FileOffset=0;
  375. sutNetStatus.FileReqOk=1;
  376. IapGetUpdateData_FOGA(sutNetStatus.FileOffset,DATA_DRAT_SIZE_PER_TIME);
  377. break;
  378. case CMD_GET_FILE_DATA_ACK:
  379. sutNetStatus.Tick10ms=0;
  380. //offset
  381. dl1.Data.ucData.b4=dataPtr[4];
  382. dl1.Data.ucData.b3=dataPtr[5];
  383. dl1.Data.ucData.b2=dataPtr[6];
  384. dl1.Data.ucData.b1=dataPtr[7];
  385. toffset=dl1.Data.ulData;
  386. //len
  387. ds.Data.ucData.b2=dataPtr[8];
  388. ds.Data.ucData.b1=dataPtr[9];
  389. len1=ds.Data.usData;
  390. if(len2!=(len1+1+6)){
  391. SlwTrace(DEBUG,"Recv file data len error!",1);
  392. }
  393. //保存到FLASH里
  394. IapAppStore(APP_FILE_DATA_ADDR+toffset, &dataPtr[10], len1);
  395. //判断是否全部下载完成
  396. if((toffset+len1)>=sutNetStatus.FileLength){
  397. SlwTrace(INF,"Dowload complected!",1);
  398. //下载完成,校验MD5码
  399. // GuiClearRect(0,40,160,58);
  400. // GuiShowStr(0,40,UPDATE_OK,0x01);
  401. NewTask(TASK_FILE_CHECK);
  402. }else{//未下载完成,申请下载下一包数据
  403. HBD_Ui_Update(1);
  404. snprintf(buf, sizeof(buf),"HBD=%d",sutNetStatus.FileOffset);//Has been downloaded
  405. SlwTrace(INF, buf,1);
  406. sutNetStatus.FileOffset=toffset+len1;
  407. IapGetUpdateData_FOGA(sutNetStatus.FileOffset,DATA_DRAT_SIZE_PER_TIME);
  408. }
  409. break;
  410. }
  411. }
  412. /*******************************************************************
  413. 封包,获取新版本文件信息
  414. |Head|Cmd|length(2) | data... | Check|
  415. Head 包头,固定为0xAB
  416. Cmd 命令字
  417. length 后续的数据长度,包括到Check的长度 length=1+data.len
  418. Check 从Head开始按字节异或运算
  419. data:
  420. unsigned long PSN;//终端编号
  421. char FileName[20];//文件名,不够的在末尾补0
  422. 总长 24+5=29 bytes
  423. *******************************************************************/
  424. unsigned short PacketGetFileInfo(unsigned char *buf)
  425. {
  426. unsigned char checksum;
  427. unsigned short i,j,k;
  428. SUTDL dl;
  429. SUTDS ds;
  430. j=0;
  431. memset(buf,0,29);
  432. buf[j++]=PACKET_HEAD;
  433. buf[j++]=CMD_GET_FILE_INFO;
  434. buf[j++]=0;
  435. buf[j++]=24+1;//数据24字节,1字节checksum
  436. //PSN
  437. dl.Data.ulData=sutProductPara.PSN; //因为协议要求大端模式传输,所以需要转一下
  438. buf[j++]=dl.Data.ucData.b4;
  439. buf[j++]=dl.Data.ucData.b3;
  440. buf[j++]=dl.Data.ucData.b2;
  441. buf[j++]=dl.Data.ucData.b1;
  442. //FileName
  443. memset(sutNetStatus.FullFileName, 0, sizeof(sutNetStatus.FullFileName));
  444. snprintf(sutNetStatus.FullFileName, sizeof(sutNetStatus.FullFileName), "%s_V%d.bin", sutProductPara.ProductName,ui_version);
  445. for(i=0;i<20;i++){
  446. buf[j++]=sutNetStatus.FullFileName[i];
  447. }
  448. //校验
  449. checksum=0;
  450. for(i=0;i<j;i++){
  451. checksum=checksum^buf[i];
  452. }
  453. buf[j++]=checksum;
  454. return j;
  455. }
  456. static void IapGetUpdateVersion_FOGA(void)
  457. {
  458. int len;
  459. unsigned char txbuf[29];
  460. getFirstPacked=0;
  461. len=PacketGetFileInfo(txbuf);
  462. if(len>sizeof(txbuf)){
  463. SlwTrace(INF,"txbuf over!",1);
  464. return;
  465. }
  466. tcpSocketSendData(FOTA_IAP_SOCKET,txbuf,len);
  467. }
  468. /*******************************************************************
  469. 封包,获取新版本
  470. |Head|Cmd|length(2) | data... | Check|
  471. Head 包头,固定为0xAB
  472. Cmd 命令字
  473. length 后续的数据长度,包括到Check的长度 length=1+data.len
  474. Check 从Head开始按字节异或运算
  475. data:
  476. unsigned long PSN; //终端编号
  477. unsigned char FileName[20]; //文件名 如:RT101_V102.bin
  478. unsigned long offset; //请求数据在文件中的开始位置
  479. unsigned short len; //请求数据的长度,服务器返回的数据可能小于等于此长度
  480. *******************************************************************/
  481. unsigned short PacketGetFileData(unsigned char *buf,unsigned int offset,unsigned short len)
  482. {
  483. unsigned char checksum;
  484. unsigned short i,j;
  485. SUTDL dl;
  486. SUTDS ds;
  487. j=0;
  488. memset(buf,0,35);
  489. buf[j++]=PACKET_HEAD;
  490. buf[j++]=CMD_GET_FILE_DATA;
  491. buf[j++]=0;
  492. buf[j++]=30+1;//数据18字节,1字节checksum
  493. //PSN
  494. dl.Data.ulData=sutProductPara.PSN; //因为协议要求大端模式传输,所以需要转一下
  495. buf[j++]=dl.Data.ucData.b4;
  496. buf[j++]=dl.Data.ucData.b3;
  497. buf[j++]=dl.Data.ucData.b2;
  498. buf[j++]=dl.Data.ucData.b1;
  499. //FileName
  500. for(i=0;i<20;i++){
  501. buf[j++]=sutNetStatus.FullFileName[i];
  502. }
  503. //offset
  504. dl.Data.ulData=offset; //因为协议要求大端模式传输,所以需要转一下
  505. buf[j++]=dl.Data.ucData.b4;
  506. buf[j++]=dl.Data.ucData.b3;
  507. buf[j++]=dl.Data.ucData.b2;
  508. buf[j++]=dl.Data.ucData.b1;
  509. //len
  510. ds.Data.usData=len;
  511. buf[j++]=ds.Data.ucData.b2;
  512. buf[j++]=ds.Data.ucData.b1;
  513. //校验
  514. checksum=0;
  515. for(i=0;i<j;i++){
  516. checksum=checksum^buf[i];
  517. }
  518. buf[j++]=checksum;
  519. return j;
  520. }
  521. ////////////文件数据请求//////////////
  522. static void IapGetUpdateData_FOGA(uint32_t offset,uint16_t len)
  523. {
  524. unsigned short l;
  525. unsigned char txbuf[35];
  526. getFirstPacked=0;
  527. l=PacketGetFileData(txbuf,offset,len);
  528. if(l>sizeof(txbuf)){
  529. SlwTrace(INF,"txbuf over!",1);
  530. return;
  531. }
  532. tcpSocketSendData(FOTA_IAP_SOCKET,txbuf,l);
  533. }
  534. ////////////////////相关子方法
  535. //"3a" or "3A" to 0x3a
  536. static char ChageAscii_To_Hex(char *dat)
  537. {
  538. char temp[2];
  539. uint8_t i;
  540. for(i=0;i<2;i++){
  541. if(dat[i] >= '0' && dat[i] <= '9')
  542. temp[i] = dat[i] - 0x30;
  543. else if(dat[i] >= 'A' && dat[i] <= 'Z')
  544. temp[i] = dat[i] - 0x37;
  545. else if(dat[i] >= 'a' && dat[i] <= 'z')
  546. temp[i] = dat[i] - 0x57;
  547. }
  548. return ((temp[0]<<4) | temp[1]);
  549. }
  550. //保存以ASCII形式的数据为十六进制放回dat 实际数据长度减半
  551. static void ChangeDataToHex(char *dat, uint16_t len)
  552. {
  553. uint16_t i;
  554. for(i=0;i<len;i++)
  555. *(dat+i) = ChageAscii_To_Hex(dat+2*i);
  556. }
  557. //32 ASCII MD5 --> 16 HEX
  558. static void SaveNewMD5(char *dat, char *des)
  559. {
  560. uint8_t i;
  561. for(i=0;i<16;i++)
  562. des[i] = ChageAscii_To_Hex(dat+2*i);
  563. }
  564. static void ExitRightNow(void)
  565. {
  566. FotaSocketCtl(0);
  567. UISetNextStatus(UIS_MENU_SYS_SET);//退出升级操作
  568. }
  569. //FOTA 开关宏控制
  570. //FOTA 打印宏控制
  571. static void Door_Ctrl(uint8_t flag)
  572. {
  573. if(flag){
  574. Fota_Rcv_Pri_Flag = 0;
  575. //////////////////////////
  576. g_uiGpsStat=0;
  577. }else{
  578. Fota_Rcv_Pri_Flag = 1;
  579. //////////////////////////
  580. g_uiGpsStat=1;
  581. }
  582. }
  583. //SOCKET OPEN OR CLOSE
  584. static void FotaSocketCtl(uint8_t ctl)
  585. {
  586. char buf[50];
  587. if(ctl){//open
  588. snprintf(buf, sizeof(buf), "AT+TCPOPEN=%d,%s:%d\r\n",FOTA_IAP_SOCKET,FOTA_IAP_IP,
  589. FOTA_IAP_PORT);
  590. Door_Ctrl(ctl);
  591. }else{//close
  592. snprintf(buf, sizeof(buf), "AT+TCPCLOSE=%d\r\n", FOTA_IAP_SOCKET);
  593. Door_Ctrl(ctl);
  594. }
  595. ModemSendAt(buf);
  596. SlwTrace(INF, buf,0);
  597. }
  598. static void IapAppStore(uint32_t addr, uint8_t *buf, uint16_t len)
  599. {
  600. sFlash_Write(buf,addr,len);
  601. }
  602. //return 0 校验正确
  603. //return 1 错误
  604. //type 1 block 1
  605. //type 2 block 2
  606. //spical 0 no need to change first 4 bytes to 0 after read out
  607. //spical 1 need to change first 4 bytes to 0 after read out
  608. static int IapCheckFileMD5_SPI_Flash(uint8_t *MD,uint8_t type,uint8_t spical)
  609. {
  610. //总数据大小为 IapPra.u_filesize;
  611. MD5_CTX mdContext;
  612. uint32_t Read_file_size;
  613. uint32_t read_addr,startAddr;
  614. uint8_t buf[1024],finished_flag,temp;
  615. uint16_t read_len,i;
  616. char tempbuf[5];
  617. uint8_t firstTime;
  618. firstTime = 0;
  619. if(type == 1)
  620. startAddr = FILE_INDEX_ADDR;
  621. else if(type == 2)
  622. startAddr = APP_FILE_DATA_ADDR;
  623. else return 1;
  624. if(!spical)firstTime=1;
  625. Read_file_size = 0;
  626. read_addr = 0;
  627. finished_flag = 0;
  628. MD5Init(&mdContext);
  629. do{
  630. if(sutNetStatus.FileLength - Read_file_size >= 1024)
  631. read_len = 1024;
  632. else{
  633. read_len = sutNetStatus.FileLength - Read_file_size;
  634. finished_flag = 1;
  635. }
  636. sFlash_Read(buf, startAddr+read_addr, read_len);
  637. if(!firstTime){
  638. firstTime ++;
  639. buf[0] = 0;buf[1] = 0;buf[2] = 0;buf[3] = 0;
  640. }
  641. Read_file_size += read_len;
  642. read_addr += read_len;
  643. MD5Update(&mdContext, buf, read_len);
  644. }while(!finished_flag);
  645. MD5Final(&mdContext);
  646. //check
  647. for(i=0;i<16;i++){
  648. if(MD[i] != mdContext.digest[i]) break;
  649. }
  650. if(i<16) return 1;
  651. else return 0;
  652. }
  653. static void UI_Process_Update(void)
  654. {
  655. char buf[22];
  656. uint8_t persent,showFlag;
  657. showFlag = 0;
  658. switch(sutNetStatus.iapUI.update)
  659. {
  660. case 1: persent = 100*sutNetStatus.iapUI.down_size/sutNetStatus.iapUI.total_size;
  661. #if(USING_LANGUAGE==USING_CHINESE)
  662. snprintf(buf, sizeof(buf), " 已下载百分之 %d \r\n", persent);
  663. #else
  664. snprintf(buf, sizeof(buf), " DownLoad %d \r\n", persent);
  665. #endif
  666. showFlag ++; break;
  667. case 2: snprintf(buf, sizeof(buf), App_Checking);
  668. showFlag ++; break;
  669. case 3: snprintf(buf, sizeof(buf), Reboot_Mini);
  670. //MeSpeak(ENCODE_ASCII,(char *)VOIC_REBOOT,0);
  671. IWDG_ReloadCounter();
  672. DelayMs(1000);
  673. IWDG_ReloadCounter();
  674. showFlag ++;break;
  675. }
  676. if(showFlag) GuiShowStr(0,70,buf,1,0);
  677. sutNetStatus.iapUI.update = 0;
  678. }
  679. static void HBD_Ui_Update(uint8_t type)
  680. {
  681. sutNetStatus.iapUI.down_size = sutNetStatus.FileOffset;
  682. sutNetStatus.iapUI.total_size=sutNetStatus.FileLength;
  683. sutNetStatus.iapUI.update = type;
  684. }
  685. void SetUpAppricationVerShow(int update)
  686. {
  687. char buf[30];
  688. if(update){
  689. ui_version = PRODUCT_VERSION+1;
  690. GuiClearAll();
  691. ShowCaption(MESSG1,0); //升级应用版本
  692. GuiDrawHLine(0,159,20,1);
  693. //sprintf(buf, " 是否升级到 V%d ", ui_version);//是否升级到 V%d
  694. //GuiShowStr(0,56,buf,1);
  695. snprintf(buf, sizeof(buf), " 当前版本: V%d ", PRODUCT_VERSION);//是否升级到 V%d
  696. GuiShowStr(0,44,buf,1,0);//当前版本
  697. snprintf(buf, sizeof(buf), " 升级到:V%d ", ui_version);
  698. GuiShowStr(0,68,buf,1,0);
  699. //GuiReverseRect(96,68,24,16);
  700. GuiDrawHLine(0,159,104,1);
  701. GuiShowStr(0,110,MESSG3,0x01,0);//[OK]升级 [EXIT]退出
  702. }
  703. }
  704. void SetUpAppricationVerResponse(void)
  705. {
  706. char buf[19],update;
  707. static char APP_Flag=0;
  708. if(KEY_PANEL_MENU==g_ulKeyValue){//因为没有UDP指令,暂时没有此功能
  709. UISetNextStatus(UIS_UP_APP_PENDING);
  710. GuiClearArea(0, 56, 160, 24);
  711. //SpeakerEnable();
  712. //ModemSendAt((char *)UP_PRO_VER); //正在处理请稍候
  713. //MeSpeak(ENCODE_UNICODE, (char *)UP_PRO_VER, 0);
  714. GuiShowStr(4,40,UPDATE_ING,0x01,0);//正在处理,请稍候...
  715. GuiShowStr(4,70,VER_REQ_ING,0x01,0);// 版本请求中...
  716. GuiShowStr(0,110,EXIT_CANCLE,0x01,0);
  717. IWDG_ReloadCounter();
  718. //os_dly_wait(200); 后续需要增加
  719. MyIap_Init();
  720. }else if(KEY_PANEL_EXIT==g_ulKeyValue) UISetNextStatus(UIS_MENU_SYS_SET);
  721. //else if(KEY_PANEL_MENU==g_ulKeyValue) UISetNextStatus(UIS_MENU_MAIN);
  722. else if(KEY_PANEL_UP == g_ulKeyValue ||
  723. KEY_PANEL_DOWN == g_ulKeyValue)
  724. {
  725. update=0;
  726. if(KEY_PANEL_UP == g_ulKeyValue)
  727. {
  728. ui_version ++;
  729. update ++;
  730. }else if(KEY_PANEL_DOWN == g_ulKeyValue && ui_version > PRODUCT_VERSION+1)
  731. {
  732. ui_version --;
  733. update ++;
  734. }
  735. if(update)
  736. {
  737. snprintf(buf, sizeof(buf), " 升级到:V%d ", ui_version);
  738. GuiShowStr(0,68,buf,1,0);
  739. //GuiReverseRect(96,68,24,16);
  740. }
  741. }
  742. else if(KEY_OPTION==g_ulKeyValue)
  743. {
  744. // //对讲版本升级,长按P1+P3 3秒,可退出后再进入
  745. // if(APP_Flag == 0)
  746. // {
  747. // g_ucUKC=0;
  748. // APP_Flag++;
  749. // }else
  750. // {
  751. // if(g_ucUKC>3){
  752. // UISetNextStatus(UIS_UP_INTERCOM_VER);
  753. // APP_Flag =0;
  754. // }
  755. // }
  756. }
  757. else APP_Flag=0;
  758. }
  759. //type 1, 文件索引保存到块1
  760. //type 2, 文件索引保存到块2
  761. static void SaveFileIndexCtl(uint8_t *p_sutFileList, uint8_t type)
  762. {
  763. if(type == 1)
  764. sFlash_Write(p_sutFileList,FILE_INDEX_ADDR,sizeof(SUT_FILE_LIST));
  765. else if(type == 2)
  766. sFlash_Write(p_sutFileList,APP_FILE_DATA_ADDR,sizeof(SUT_FILE_LIST));
  767. }
  768. static uint8_t SetMark(uint32_t value)
  769. {
  770. uint8_t buf[4],i;
  771. for(i=0;i<4;i++)
  772. buf[i] = value>>(i*8);
  773. /*
  774. 改为内部FLASH 置位。
  775. */
  776. // sFlash_Write(buf, APP_FILE_DATA_ADDR, 4);
  777. memcpy(sutProductPara.FoTaMark,"FOTA",4);//FOTA
  778. sutProductPara.AppLen=sutNetStatus.FileLength;
  779. sutProductPara.ExAddr=APP_FILE_DATA_ADDR;
  780. memcpy(sutProductPara.MD5,sutNetStatus.MD5,16);
  781. SaveProductParaToFlash();
  782. }