AppIap.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. #include "includes.h"
  2. struct IAP_PRA IapPra;
  3. unsigned char Fota_Rcv_Pri_Flag=1;//IAP串口输出标志
  4. unsigned short g_usTid=0;
  5. static unsigned char FileMD5[16];//={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  6. uint16_t ui_version;
  7. uint8_t resendPackage;
  8. //串口打印信息
  9. const char No_Login_In[] = "Logout!\r\n";
  10. const char Fota_Start[] = "Fota IAP start!\r\n";
  11. const char Ver_Ok_Dat_Start[] = "Ver req ok data req start!\r\n";
  12. const char Task_GoTo_App[] = "Task goto App!\r\n";
  13. const char MD5_Error[] = "MD5 err!\r\n";
  14. const char Len_Offset_Error[] = "len or offset err!\r\n";
  15. const char CRC_Error[] = "CRC err!\r\n";
  16. const char Resend_Package[] = "Resend last package!\r\n";
  17. const char Wait_Package_Timeout[] = "Package wait timeout!\r\n";
  18. const char Reboot[] = "Update done! rebooting\r\n";
  19. const char OtherLen_error[] = "otherLen < 46\r\n";
  20. const char Format_Not_Fit[] = "Invalid Header\r\n";
  21. const char ReTry_Failed[] = "Re-Try 3 time failed! %d\r\n";
  22. //语音部分
  23. const char VO_NO_LOGIN[] = "AT+ZTTS=1,\"2A677B76555F\"\r";//未登陆
  24. const char APP_CHECK [] = "AT+ZTTS=1,\"0B4E7D8F10629F52636B285721688C9A\"\r";//下载成功正在校验
  25. const char UP_APP_VER [] = "AT+ZTTS=1,\"636B28570B4E7D8FF78B0D7A1950\"\r";//正在下载请稍候
  26. const char UP_PRO_VER [] = "AT+ZTTS=1,\"636B2857B783D653B06548722C67\"\r";//正在获取新版本
  27. const char VOIC_NO_VER[] = "AT+ZTTS=1,\"A16C0967EF53F466B06548722C67\"\r";//没有可更新版本
  28. const char VOIC_REBOOT[] = "AT+ZTTS=1,\"2B52AD653575004E06529F94CD912F54\"\r";//别断电一分钟重启
  29. //下面不改
  30. const char App_Checking[] = " 下载成功正在校验 \r\n";
  31. const char Ver_Invalid[] = " 没有可更新版本 \r\n";
  32. const char Reboot_Mini[] = " 别断电一分钟重启 \r\n";
  33. const char UP_LOADING [] = "正在下载,请稍候... ";
  34. const char UPDATE_ING [] = "正在处理,请稍候... ";
  35. const char VER_REQ_ING[] = "正在获取新版本... ";
  36. const char EXIT_CANCLE[] = " [EXIT]取消";
  37. const char MESSG1 [] = "升级应用版本";
  38. const char MESSG3 [] = "[OK]升级 [EXIT]退出";
  39. static void MyIap_Init(void);
  40. static void NewTask(uint8_t);
  41. static void FotaSocketCtl(uint8_t);
  42. static void StartIAP(void);
  43. static void TickIAP(void);
  44. static void FotaSocketCtl(uint8_t);
  45. static void IapGetUpdateVersion_FOGA(void);
  46. static int MakeFoTaVersionReq(char *);
  47. static void ResetTimerCou(void);
  48. static void IapGetUpdateData_FOGA(uint32_t );
  49. int MakeFoTaDataReq(char *,int ,int );
  50. static void ChangeDataToHex(char *, uint16_t );
  51. static int IapCheckFileMD5_SPI_Flash(uint8_t *,uint8_t,uint8_t);
  52. static void Door_Ctrl(uint8_t );
  53. static void SaveNewMD5(char *, char *);
  54. static void SaveNewFileSize(char *);
  55. static char ChageAscii_To_Hex(char *);
  56. static void TryTimeCheck(uint8_t );
  57. static void UI_Process_Update(void);
  58. static void HBD_Ui_Update(uint8_t );
  59. static void IapAppStore(uint32_t , uint8_t *, uint16_t );
  60. static uint8_t DownLoaded_DataProcess(void);
  61. static uint8_t CopyFileListToFlash(SUT_FILE_LIST *, uint8_t);
  62. static void ExitRightNow(void);
  63. static uint32_t SaveLengthInFormat(char *dat);
  64. int ModemSendUdpData_User(unsigned char ,unsigned char *,unsigned short );
  65. static uint8_t SetMark(uint32_t );
  66. ////启动IAP初始化
  67. void MyIap_Init(void)
  68. {
  69. FotaSocketCtl(1);
  70. IapPra.Tick10ms=0;
  71. IapPra.TaskStart=0;
  72. IapPra.V_flag = 0;
  73. IapPra.timeTry = 0;
  74. IapPra.resetModemTime=0;
  75. resendPackage = 0;
  76. NewTask(TASK_WAIT);
  77. }
  78. ///////UI 选择
  79. void SetUpAppricationVerPending(void)
  80. {
  81. //unsigned long key;
  82. //key=ListBoxResponse(&sutListBox);
  83. if(KEY_PANEL_EXIT == g_ulKeyValue){
  84. ExitRightNow();
  85. }
  86. if(!sutPocStatus.Logined){//未登陆退出
  87. SpeakerEnable();
  88. ModemSendAT((char *)VO_NO_LOGIN); //正在下载
  89. ExitRightNow();
  90. SlwTrace(INF, (char *)No_Login_In,0);
  91. return;
  92. }
  93. StartIAP();
  94. TickIAP();
  95. UI_Process_Update();
  96. }
  97. ///////IAP状态切换
  98. static void NewTask(uint8_t task)
  99. {
  100. IapPra.TaskStatus = task;
  101. IapPra.TaskStart = 1;
  102. if(task == TASK_FILE_CHECK){
  103. IapPra.GotData_IPRECV = 3;
  104. return;
  105. }
  106. IapPra.GotData_IPRECV = 0;
  107. if(IapPra.TaskStatus == TASK_WAIT){
  108. IapPra.V_flag = 0;//如果是重新下载-重置标志
  109. SlwTrace(INF, (char *)Fota_Start,0);
  110. IapPra.u_filesize = 0;
  111. IapPra.u_req_offset = 0;
  112. IapPra.u_DownFilesize = 0;
  113. IapPra.iapUI.update = 0;
  114. }
  115. ResetTimerCou();
  116. }
  117. static void StartIAP(void)
  118. {
  119. if(!IapPra.TaskStart) return;
  120. IapPra.TaskStart = 0;
  121. switch(IapPra.TaskStatus)
  122. {
  123. case TASK_WAIT:
  124. //如果版本未请求--请求版本
  125. if(!IapPra.V_flag){ //版本请求
  126. IapGetUpdateVersion_FOGA();
  127. }else{}//do nothing
  128. break;
  129. case TASK_MODEM_UPDATE:
  130. SlwTrace(INF, (char *)Ver_Ok_Dat_Start,0);
  131. break;
  132. case TASK_FILE_CHECK:
  133. SlwTrace(INF, (char *)App_Checking,0);
  134. HBD_Ui_Update(2);
  135. break;
  136. case TASK_GOTO_APP:
  137. SlwTrace(INF, (char *)Task_GoTo_App,0);
  138. HBD_Ui_Update(4);
  139. break;
  140. case TASK_VERSION_ERROR:
  141. HBD_Ui_Update(3);
  142. ExitRightNow();
  143. break;
  144. }
  145. }
  146. ///////IAP处理///////////////
  147. static void TickIAP(void)
  148. {
  149. uint32_t len,offset;
  150. unsigned short crc,CRC16;
  151. char buf[50],temp[5];
  152. if(++IapPra.Tick10ms > TICK_COUNT)
  153. {
  154. IapPra.Tick10ms = 0;
  155. IapPra.timeOut ++;
  156. //process
  157. switch(IapPra.TaskStatus)
  158. {
  159. case TASK_WAIT:
  160. //请求版本过程--检测是否超时--超明重新请求
  161. if(0 == IapPra.V_flag)
  162. {//还未请求成功
  163. if(IapPra.timeOut >= TIME_OUT_IAP)
  164. TryTimeCheck(1);
  165. }else
  166. {
  167. if(IapPra.GotData_IPRECV == 1)
  168. {//收到请求确认--请求数据包
  169. SpeakerEnable();
  170. ModemSendAT((char *)UP_APP_VER); //正在下载
  171. GuiShowStr(0,40,UP_LOADING,1);
  172. NewTask(TASK_MODEM_UPDATE);
  173. IapGetUpdateData_FOGA(0);
  174. }
  175. }
  176. break;
  177. case TASK_MODEM_UPDATE:
  178. if(IapPra.GotData_IPRECV == 2)
  179. { //收到数据包请求数据回来,检查包数据
  180. //1检查MD5是否一致
  181. ///////////////////////////////////
  182. IapPra.resetModemTime=0;//说明数据通了,复位数清零
  183. ///////////////////////////////////
  184. if(0 != strncmp((char *)FileMD5, IapPra.MD5, 16)){
  185. SlwTrace(INF, (char *)MD5_Error,0);
  186. TryTimeCheck(2);
  187. return;
  188. }
  189. //2检查长度偏移
  190. len=IapPra.u_length;
  191. offset=IapPra.u_offset;
  192. if(len < 2 || \
  193. offset != IapPra.u_req_offset ||
  194. (len+IapPra.u_req_offset) > (IapPra.u_filesize+2))
  195. {
  196. SlwTrace(INF, (char *)Len_Offset_Error,0);
  197. TryTimeCheck(3);
  198. // {
  199. // char tbuf[60];
  200. // sprintf(tbuf, "len:%d,offset:%d,re_offset:%d,filesize:%d\r\n",len, offset, IapPra.u_req_offset, IapPra.u_filesize);
  201. // SlwTrace(INF, tbuf);
  202. // }
  203. return;
  204. }
  205. //3.检查CRC
  206. len -= 2;
  207. CRC16=crc16_calc(0,IapPra.FOGA_buf, len);
  208. crc=((unsigned short)IapPra.FOGA_buf[len+1]&0xff)<<8;
  209. crc+=(unsigned short)IapPra.FOGA_buf[len]&0xff;
  210. if(crc!=CRC16){
  211. SlwTrace(INF, (char *)CRC_Error,0);
  212. TryTimeCheck(4);
  213. return ;
  214. }
  215. //校验成功
  216. //处理一包数据
  217. IapAppStore(APP_FILE_DATA_ADDR+IapPra.u_req_offset, IapPra.FOGA_buf, len);
  218. //处理完
  219. IapPra.u_DownFilesize += len;
  220. IapPra.u_req_offset += len;
  221. HBD_Ui_Update(1);
  222. sprintf(buf,"HBD=%d",IapPra.u_req_offset);//Has been downloaded
  223. SlwTrace(INF, buf,1);
  224. if(IapPra.u_DownFilesize >= IapPra.u_filesize){//下载结束
  225. SpeakerEnable();
  226. ModemSendAT((char *)APP_CHECK);
  227. IWDG_ReloadCounter();
  228. os_dly_wait(200);
  229. NewTask(TASK_FILE_CHECK);
  230. return;
  231. }
  232. //未结束启动下一包
  233. IapGetUpdateData_FOGA(IapPra.u_req_offset);
  234. resendPackage = 0;
  235. }else if(!IapPra.GotData_IPRECV)
  236. {
  237. if(IapPra.timeOut >= TIME_OUT_IAP){
  238. SlwTrace(INF, (char *)Wait_Package_Timeout,0);//调试过程试过出现"NO CARRIER"即数据业务断开了
  239. TryTimeCheck(6);
  240. }
  241. }
  242. break;
  243. case TASK_FILE_CHECK:
  244. //MD5总校验
  245. switch(IapCheckFileMD5_SPI_Flash(FileMD5,2,0))
  246. {
  247. case 0://OK
  248. NewTask(TASK_GOTO_APP);
  249. break;
  250. case 1://confinue
  251. SlwTrace(INF, (char *)MD5_Error,0);
  252. TryTimeCheck(5);
  253. break;
  254. }
  255. break;
  256. case TASK_GOTO_APP:
  257. SetMark(GOOD_UPDATE_STORAGE);
  258. SlwTrace(INF, (char *)Reboot,0);
  259. while(1);
  260. break;
  261. case TASK_EXIT:
  262. ExitRightNow();
  263. break;
  264. }
  265. }
  266. }
  267. static uint32_t SaveLengthInFormat(char *dat)
  268. {
  269. uint32_t temp,i;
  270. temp = 0;
  271. for(i=0;i<4;i++){
  272. temp <<= 8;
  273. temp |= (uint32_t)ChageAscii_To_Hex(dat+6-2*i);
  274. }
  275. return temp;
  276. }
  277. //针对FOTA升级时处理此终端UDP返回的数据
  278. //对CDMA(如8332)格式为+ZIPRECVU:........
  279. void FotaIap_Handle(char *msg)
  280. {
  281. char buf[60],kk[60],temp[10];
  282. uint8_t i,j,dataIndex;
  283. uint16_t otherLength;
  284. uint8_t extraLen;
  285. if(!IapPra.FOTA_IS_ON) return;
  286. if(IapPra.GotData_IPRECV) return;
  287. //1,数据拆包
  288. //1.1比较命令头,socket,IP,port,udp type
  289. //+ZIPRECVU:2,
  290. sprintf(buf, "+ZIPRECVU:%d,", FOTA_IAP_SOCKET);
  291. if(0 != strncmp(msg, buf, 12)) return;
  292. //1.2 取具体数据索引第二个逗号加1
  293. j=0;
  294. for(i=0;i<20;i++){
  295. if(*(msg+i) == ','){
  296. j++;
  297. if(j >= 2) break;
  298. }
  299. }
  300. dataIndex = i+1;
  301. //1.2 get data len,最大16384五位数
  302. otherLength = StrToNum(msg+12);//这里其实最大可以是5位十进制数--我们不可能传那么大数据-一般只有一两个K
  303. //1.3 比较版本请求头格式
  304. if(otherLength < 46){
  305. SlwTrace(INF, (char *)OtherLen_error,0);
  306. return;
  307. }
  308. MakeFoTaVersionReq(buf);
  309. if(0 != strncmp(buf, msg+dataIndex, 22) && \
  310. 2 != *(msg+dataIndex+5))
  311. {
  312. SlwTrace(INF, (char *)Format_Not_Fit,0);
  313. return;
  314. }
  315. //1.4 得到协议内具体数据长度
  316. otherLength = (uint16_t)*(msg+dataIndex+25);
  317. otherLength <<= 8;
  318. otherLength |= (uint16_t)*(msg+dataIndex+24);//LSByte
  319. //1.5 区别版本或数据请求返回
  320. if(otherLength == 20)
  321. {
  322. //是否已经请求过版本数据了
  323. if(IapPra.V_flag){}//请求过了的
  324. else
  325. {
  326. //第一次请求到了
  327. IapPra.V_flag = 1;
  328. //保存文件MD5码
  329. memcpy(kk, msg+dataIndex+26, 16);
  330. j=0;
  331. for(i=0;i<16;i++){
  332. if(kk[i] == 0) j++;
  333. }
  334. if(16 == j){
  335. SlwTrace(INF, (char *)Ver_Invalid,0);
  336. NewTask(TASK_VERSION_ERROR);
  337. return;
  338. }
  339. for(i=0;i<16;i++)
  340. memcpy(FileMD5, kk, 16);
  341. //保存文件长度
  342. //IapPra.u_filesize = 0;
  343. for(i=0;i<4;i++){
  344. IapPra.u_filesize <<= 8;
  345. IapPra.u_filesize |= *(msg+dataIndex+45-i);//文件数据在msg+dataIndex+42~45
  346. }
  347. IapPra.iapUI.total_size = IapPra.u_filesize;
  348. IapPra.GotData_IPRECV = 1;//收到了版本请求返回
  349. return;
  350. }
  351. }else if(otherLength > 20)
  352. {
  353. if(IapPra.V_flag)
  354. { //已经请求过版本了
  355. //保存MD5
  356. for(i=0;i<16;i++)
  357. memcpy(IapPra.MD5, msg+dataIndex+26, 16);
  358. //保存OFFSET
  359. for(i=0;i<4;i++){
  360. IapPra.u_offset <<= 8;
  361. IapPra.u_offset |= *(msg+dataIndex+45-i);//文件数据在msg+dataIndex+42~45
  362. }
  363. //保存LENGTH
  364. for(i=0;i<4;i++){
  365. IapPra.u_length <<= 8;
  366. IapPra.u_length |= *(msg+dataIndex+49-i);//文件数据在msg+dataIndex+46~49
  367. }
  368. //保存数据
  369. memcpy(IapPra.FOGA_buf, msg+dataIndex+50, IapPra.u_length);
  370. IapPra.GotData_IPRECV = 2;
  371. }else {}
  372. }
  373. }
  374. //////////////版本请求/////////////////////////////
  375. static void IapGetUpdateVersion_FOGA(void)
  376. {
  377. int len;
  378. //重置状态
  379. IapPra.GotData_IPRECV = 0;
  380. ResetTimerCou();//开始计数
  381. len=MakeFoTaVersionReq((char *)TxBuffer3);
  382. ModemSendUdpData_User(FOTA_IAP_SOCKET,TxBuffer3,len);
  383. }
  384. /*****************************************************************************************
  385. MakeFoTaVersionReq
  386. ******************************************************************************************/
  387. static int MakeFoTaVersionReq(char *txbuf)
  388. {
  389. update_version_req_t *pUpdateVersionReq;
  390. pUpdateVersionReq=(update_version_req_t *)txbuf;
  391. memset(pUpdateVersionReq,0,sizeof(update_version_req_t));
  392. pUpdateVersionReq->hdr.magic=FOTA_MAGIC;
  393. pUpdateVersionReq->hdr.protocol=UPDATE_PROTOCOL;
  394. pUpdateVersionReq->hdr.code=UPDATE_CODE_VERSION_REQ;
  395. sprintf(pUpdateVersionReq->hdr.dev_id,"%lu",sutProductPara.PSN);
  396. pUpdateVersionReq->hdr.tid=++g_usTid;
  397. pUpdateVersionReq->hdr.count=sizeof(update_version_req_t)-sizeof(update_hdr_t);
  398. strcpy(pUpdateVersionReq->product,sutProductPara.ProductName);
  399. pUpdateVersionReq->version=--ui_version;
  400. //pUpdateVersionReq->version=PRODUCT_VERSION;
  401. return sizeof(update_version_req_t);
  402. }
  403. ////////////文件数据请求//////////////
  404. static void IapGetUpdateData_FOGA(uint32_t offset)
  405. {
  406. int len;
  407. //重置状态
  408. IapPra.GotData_IPRECV = 0;
  409. ResetTimerCou();//开始计数
  410. len=MakeFoTaDataReq((char *)TxBuffer3,offset,DATA_DRAT_SIZE_PER_TIME);
  411. ModemSendUdpData_User(FOTA_IAP_SOCKET,TxBuffer3,len);
  412. }
  413. /*****************************************************************************************
  414. MakeFoTaDataReq
  415. ******************************************************************************************/
  416. int MakeFoTaDataReq(char *txbuf,int offset,int length)
  417. {
  418. update_data_req_t *pUpdateDataReq;
  419. pUpdateDataReq=(update_data_req_t *)txbuf;
  420. memset(pUpdateDataReq,0,sizeof(update_data_req_t));
  421. pUpdateDataReq->hdr.magic=FOTA_MAGIC;
  422. pUpdateDataReq->hdr.protocol=UPDATE_PROTOCOL;
  423. pUpdateDataReq->hdr.code=UPDATE_CODE_DATA_WITH_CRC_REQ;
  424. sprintf(pUpdateDataReq->hdr.dev_id,"%lu",sutProductPara.PSN);
  425. pUpdateDataReq->hdr.tid=++g_usTid;
  426. pUpdateDataReq->hdr.count=sizeof(update_data_req_t)-sizeof(update_hdr_t);
  427. memcpy(pUpdateDataReq->version_md5,FileMD5,16);
  428. pUpdateDataReq->offset=offset;
  429. pUpdateDataReq->length=length;
  430. return sizeof(update_data_req_t);
  431. }
  432. int ModemSendUdpData_User(unsigned char socket,unsigned char *pData,unsigned short len)
  433. {
  434. int i;
  435. char buf[142];
  436. char tmp[5];
  437. tmp[0] = 0;//
  438. sprintf(buf,"AT+ZIPSENDU=%d,%d\r", socket, len);//这里的长度会不会超过两位数
  439. if(len > 99)//three digit
  440. tmp[0] = 1;
  441. memcpy(buf+17+tmp[0], pData, len);
  442. ModemSendData((uint8_t *)buf, 17+tmp[0]+len);
  443. #if ENABL_FOGA_BACK_DATA_PRINT
  444. if(Fota_Rcv_Pri_Flag) //此句与下面的SlwTrace(INF, buf)一起用调试--中间不要插入其它语句
  445. #endif
  446. SlwTrace(INF,buf,0);
  447. return 0;
  448. }
  449. ////////////////////相关子方法
  450. //"3a" or "3A" to 0x3a
  451. static char ChageAscii_To_Hex(char *dat)
  452. {
  453. char temp[2];
  454. uint8_t i;
  455. for(i=0;i<2;i++){
  456. if(dat[i] >= '0' && dat[i] <= '9')
  457. temp[i] = dat[i] - 0x30;
  458. else if(dat[i] >= 'A' && dat[i] <= 'Z')
  459. temp[i] = dat[i] - 0x37;
  460. else if(dat[i] >= 'a' && dat[i] <= 'z')
  461. temp[i] = dat[i] - 0x57;
  462. }
  463. return ((temp[0]<<4) | temp[1]);
  464. }
  465. //保存以ASCII形式的数据为十六进制放回dat 实际数据长度减半
  466. static void ChangeDataToHex(char *dat, uint16_t len)
  467. {
  468. uint16_t i;
  469. for(i=0;i<len;i++)
  470. *(dat+i) = ChageAscii_To_Hex(dat+2*i);
  471. }
  472. //32 ASCII MD5 --> 16 HEX
  473. static void SaveNewMD5(char *dat, char *des)
  474. {
  475. uint8_t i;
  476. for(i=0;i<16;i++)
  477. des[i] = ChageAscii_To_Hex(dat+2*i);
  478. }
  479. //保存版本请求回来的文件大小
  480. static void SaveNewFileSize(char *dat)
  481. {
  482. char temp[4];
  483. uint8_t i;
  484. for(i=0;i<4;i++)
  485. temp[i] = ChageAscii_To_Hex(dat+2*i);
  486. IapPra.u_filesize = (uint32_t)temp[3]<<24;
  487. IapPra.u_filesize |= (uint32_t)temp[2]<<16;
  488. IapPra.u_filesize |= (uint32_t)temp[1]<<8;
  489. IapPra.u_filesize |= (uint32_t)temp[0];
  490. IapPra.iapUI.total_size = IapPra.u_filesize;
  491. }
  492. static void ExitRightNow(void)
  493. {
  494. FotaSocketCtl(0);
  495. UISetNextStatus(UIS_MENU_SYS_SET);//退出升级操作
  496. }
  497. //重置计数器
  498. static void ResetTimerCou(void){IapPra.timeOut = 0;}
  499. //IAP 重试检测
  500. static void TryTimeCheck(uint8_t note)
  501. {
  502. char buf[25];
  503. ResetTimerCou();
  504. switch(note)
  505. {
  506. case 2:
  507. case 3:
  508. case 4:
  509. SlwTrace(INF, (char *)Resend_Package,0);
  510. IapGetUpdateData_FOGA(IapPra.u_req_offset);
  511. return;
  512. case 6:
  513. if(resendPackage <=3)
  514. {
  515. resendPackage ++;
  516. SlwTrace(INF, (char *)Resend_Package,0);//调试过程试过出现"NO CARRIER"即数据业务断开了
  517. IapGetUpdateData_FOGA(IapPra.u_req_offset);
  518. return;
  519. }else//对于等不到数据并重发超过3次,就重新下载
  520. {}
  521. break;
  522. }
  523. resendPackage = 0;
  524. if(++IapPra.timeTry > RETRY_TIME)
  525. {//重试3次失败退出
  526. ExitRightNow();
  527. sprintf(buf, ReTry_Failed, note);
  528. SlwTrace(INF, buf,0);
  529. }else NewTask(TASK_WAIT); //再次请求
  530. }
  531. //FOTA 开关宏控制
  532. //FOTA 打印宏控制
  533. static void Door_Ctrl(uint8_t flag)
  534. {
  535. if(flag){
  536. IapPra.FOTA_IS_ON = 1;
  537. Fota_Rcv_Pri_Flag = 0;
  538. //////////////////////////
  539. g_uiGpsStat=0;
  540. }else{
  541. IapPra.FOTA_IS_ON = 0;
  542. Fota_Rcv_Pri_Flag = 1;
  543. //////////////////////////
  544. g_uiGpsStat=1;
  545. }
  546. }
  547. //SOCKET OPEN OR CLOSE
  548. static void FotaSocketCtl(uint8_t ctl)
  549. {
  550. char buf[50];
  551. if(ctl){//open
  552. sprintf(buf, "AT+ZIPSETUPU=%d,%s,%d\r\n",FOTA_IAP_SOCKET,FOTA_IAP_SERVER_IP,FOTA_IAP_SERVER_PORT);
  553. Door_Ctrl(ctl);
  554. }else{//close
  555. sprintf(buf, "AT+ZIPCLOSE=%d\r\n", FOTA_IAP_SOCKET);
  556. Door_Ctrl(ctl);
  557. }
  558. ModemSendAT(buf);
  559. SlwTrace(INF, buf,0);
  560. }
  561. static void IapAppStore(uint32_t addr, uint8_t *buf, uint16_t len)
  562. {
  563. sFlash_Write(buf,addr,len);
  564. }
  565. //return 0 校验正确
  566. //return 1 错误
  567. //type 1 block 1
  568. //type 2 block 2
  569. //spical 0 no need to change first 4 bytes to 0 after read out
  570. //spical 1 need to change first 4 bytes to 0 after read out
  571. static int IapCheckFileMD5_SPI_Flash(uint8_t *MD,uint8_t type,uint8_t spical)
  572. {
  573. //总数据大小为 IapPra.u_filesize;
  574. MD5_CTX mdContext;
  575. uint32_t Read_file_size;
  576. uint32_t read_addr,startAddr;
  577. uint8_t buf[1024],finished_flag,temp;
  578. uint16_t read_len,i;
  579. char tempbuf[5];
  580. uint8_t firstTime;
  581. firstTime = 0;
  582. if(type == 1)
  583. startAddr = FILE_INDEX_ADDR;
  584. else if(type == 2)
  585. startAddr = APP_FILE_DATA_ADDR;
  586. else return 1;
  587. Read_file_size = 0;
  588. read_addr = 0;
  589. finished_flag = 0;
  590. MD5Init(&mdContext);
  591. do{
  592. if(IapPra.u_filesize - Read_file_size >= 1024)
  593. read_len = 1024;
  594. else{
  595. read_len = IapPra.u_filesize - Read_file_size;
  596. finished_flag = 1;
  597. }
  598. sFlash_Read(buf, startAddr+read_addr, read_len);
  599. if(!firstTime){
  600. firstTime ++;
  601. buf[0] = 0;buf[1] = 0;buf[2] = 0;buf[3] = 0;
  602. }
  603. Read_file_size += read_len;
  604. read_addr += read_len;
  605. MD5Update(&mdContext, buf, read_len);
  606. }while(!finished_flag);
  607. MD5Final(&mdContext);
  608. //check
  609. for(i=0;i<16;i++){
  610. if(MD[i] != mdContext.digest[i]) break;
  611. }
  612. if(i<16) return 1;
  613. else return 0;
  614. }
  615. static void UI_Process_Update(void)
  616. {
  617. char buf[22];
  618. uint8_t persent,showFlag;
  619. showFlag = 0;
  620. switch(IapPra.iapUI.update)
  621. {
  622. case 1: persent = 100*IapPra.iapUI.down_size/IapPra.iapUI.total_size;
  623. sprintf(buf, " 已下载百分之 %d \r\n", persent);
  624. showFlag ++; break;
  625. case 2: sprintf(buf, App_Checking);
  626. showFlag ++; break;
  627. case 3: sprintf(buf, Ver_Invalid);
  628. ModemSendAT((char *)VOIC_NO_VER);
  629. // SlwTrace(INF, "***B");
  630. showFlag ++;break;
  631. case 4: sprintf(buf, Reboot_Mini);
  632. ModemSendAT((char *)VOIC_REBOOT);
  633. IWDG_ReloadCounter();
  634. DelayMs(1000);
  635. IWDG_ReloadCounter();
  636. showFlag ++;break;
  637. }
  638. if(showFlag) GuiShowStr(0,70,buf,1);
  639. IapPra.iapUI.update = 0;
  640. }
  641. static void HBD_Ui_Update(uint8_t type)
  642. {
  643. IapPra.iapUI.down_size = IapPra.u_DownFilesize;
  644. IapPra.iapUI.update = type;
  645. }
  646. void SetUpAppricationVerShow(int update)
  647. {
  648. char buf[19];
  649. if(update){
  650. ui_version = PRODUCT_VERSION+1;
  651. GuiClearAll();
  652. ShowCaption(MESSG1,0); //升级应用版本
  653. GuiDrawHLine(0,159,20,1);
  654. //sprintf(buf, " 是否升级到 V%d ", ui_version);//是否升级到 V%d
  655. //GuiShowStr(0,56,buf,1);
  656. sprintf(buf, " 当前版本: V%d ", PRODUCT_VERSION);//是否升级到 V%d
  657. GuiShowStr(0,44,buf,1);//当前版本
  658. sprintf(buf, " 升级到:V%d ", ui_version);
  659. GuiShowStr(0,68,buf,1);
  660. //GuiReverseRect(96,68,24,16);
  661. GuiDrawHLine(0,159,104,1);
  662. GuiShowStr(0,110,MESSG3,0x01);//[OK]升级 [EXIT]退出
  663. }
  664. }
  665. void SetUpAppricationVerResponse(void)
  666. {
  667. char buf[19],update;
  668. static char APP_Flag=0;
  669. if(KEY_PANEL_OK==g_ulKeyValue){//因为没有UDP指令,暂时没有此功能
  670. // UISetNextStatus(UIS_UP_APP_PENDING);
  671. // GuiClearArea(0, 56, 160, 24);
  672. // SpeakerEnable();
  673. // ModemSendAT((char *)UP_PRO_VER); //正在处理请稍候
  674. // GuiShowStr(4,40,UPDATE_ING,0x01);//正在处理,请稍候...
  675. // GuiShowStr(4,70,VER_REQ_ING,0x01);// 版本请求中...
  676. // GuiShowStr(0,110,EXIT_CANCLE,0x01);
  677. // IWDG_ReloadCounter();
  678. // os_dly_wait(200);
  679. // MyIap_Init();
  680. }else if(KEY_PANEL_EXIT==g_ulKeyValue) UISetNextStatus(UIS_MENU_SYS_SET);
  681. else if(KEY_PANEL_MENU==g_ulKeyValue) UISetNextStatus(UIS_MENU_MAIN);
  682. else if(KEY_PANEL_UP == g_ulKeyValue ||
  683. KEY_PANEL_DOWN == g_ulKeyValue)
  684. {
  685. update=0;
  686. if(KEY_PANEL_UP == g_ulKeyValue)
  687. {
  688. ui_version ++;
  689. update ++;
  690. }else if(KEY_PANEL_DOWN == g_ulKeyValue && ui_version > PRODUCT_VERSION+1)
  691. {
  692. ui_version --;
  693. update ++;
  694. }
  695. if(update)
  696. {
  697. sprintf(buf, " 升级到:V%d ", ui_version);
  698. GuiShowStr(0,68,buf,1);
  699. //GuiReverseRect(96,68,24,16);
  700. }
  701. }
  702. else if(KEY_P1_P3_UPDATE==g_ulKeyValue)
  703. {
  704. //对讲版本升级,长按P1+P3 3秒,可退出后再进入
  705. if(APP_Flag == 0)
  706. {
  707. g_ucUKC=0;
  708. APP_Flag++;
  709. }else
  710. {
  711. if(g_ucUKC>3){
  712. UISetNextStatus(UIS_UP_INTERCOM_VER);
  713. APP_Flag =0;
  714. }
  715. }
  716. }
  717. else APP_Flag=0;
  718. }
  719. //type 1, 文件索引保存到块1
  720. //type 2, 文件索引保存到块2
  721. static void SaveFileIndexCtl(uint8_t *p_sutFileList, uint8_t type)
  722. {
  723. if(type == 1)
  724. sFlash_Write(p_sutFileList,FILE_INDEX_ADDR,sizeof(SUT_FILE_LIST));
  725. else if(type == 2)
  726. sFlash_Write(p_sutFileList,APP_FILE_DATA_ADDR,sizeof(SUT_FILE_LIST));
  727. }
  728. static uint8_t SetMark(uint32_t value)
  729. {
  730. uint8_t buf[4],i;
  731. for(i=0;i<4;i++)
  732. buf[i] = value>>(i*8);
  733. sFlash_Write(buf, APP_FILE_DATA_ADDR, 4);
  734. }