AppIap.c 22 KB

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