AppIap.c 23 KB

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