#include "includes.h" unsigned char Fota_Rcv_Pri_Flag=1;//IAP串口输出标志 unsigned short g_usTid=0; //static unsigned char FileMD5[16];//={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; uint16_t ui_version; uint8_t resendPackage; //串口打印信息 const char No_Login_In[] = "Logout!\r\n"; const char Fota_Start[] = "Fota IAP start!\r\n"; const char Ver_Ok_Dat_Start[] = "Ver req ok data req start!\r\n"; const char Task_GoTo_App[] = "Task goto App!\r\n"; const char MD5_Error[] = "MD5 err!\r\n"; const char Len_Offset_Error[] = "len or offset err!\r\n"; const char CRC_Error[] = "CRC err!\r\n"; const char Resend_Package[] = "Resend last package!\r\n"; const char Wait_Package_Timeout[] = "Package wait timeout!\r\n"; const char Reboot[] = "Update done! rebooting\r\n"; const char OtherLen_error[] = "otherLen < 46\r\n"; const char Format_Not_Fit[] = "Invalid Header\r\n"; const char ReTry_Failed[] = "Re-Try 3 time failed! %d\r\n"; //语音部分 const char VO_NO_LOGIN[] = "AT+LSHTTS=0,\"2A677B76555F\"\r";//未登陆 const char APP_CHECK [] = "AT+LSHTTS=0,\"0B4E7D8F10629F52636B285721688C9A\"\r";//下载成功正在校验 const char UP_APP_VER [] = "AT+LSHTTS=0,\"636B28570B4E7D8FF78B0D7A1950\"\r";//正在下载请稍候 const char UP_PRO_VER [] = "AT+LSHTTS=0,\"636B2857B783D653B06548722C67\"\r";//正在获取新版本 const char VOIC_NO_VER[] = "AT+LSHTTS=0,\"A16C0967EF53F466B06548722C67\"\r";//没有可更新版本 const char VOIC_REBOOT[] = "AT+LSHTTS=0,\"2B52AD653575004E06529F94CD912F54\"\r";//别断电一分钟重启 //下面不改 const char App_Checking[] = " 下载成功正在校验 \r\n"; const char Ver_Invalid[] = " 没有可更新版本 \r\n"; const char Reboot_Mini[] = " 别断电一分钟重启 \r\n"; const char UP_LOADING [] = "正在下载,请稍候... "; const char UPDATE_ING [] = "正在处理,请稍候... "; const char UPDATE_OK[] = " 下载完成 "; const char VER_REQ_ING[] = "正在获取新版本... "; const char EXIT_CANCLE[] = " [EXIT]取消"; const char MESSG1 [] = "升级应用版本"; const char MESSG3 [] = "[M]升级 [EXIT]退出"; const char TRY_FAILED[] =" 下载失败 "; const char GET_FILE_ERR[] =" 获取文件失败 "; const char NET_OVERTIME_ERR[] =" 网络超时 "; const char SER_NO_FILE[] =" 服务器无文件 "; const char MD5_VRY_ERR[] =" 文件校验失败 "; static void MyIap_Init(void); static void NewTask(uint8_t); static void FotaSocketCtl(uint8_t); static void StartIAP(void); static void TickIAP(void); static void FotaSocketCtl(uint8_t); static void IapGetUpdateVersion_FOGA(void); static void IapGetUpdateData_FOGA(uint32_t offset,uint16_t len); static void ChangeDataToHex(char *, uint16_t ); static int IapCheckFileMD5_SPI_Flash(uint8_t *,uint8_t,uint8_t); static void Door_Ctrl(uint8_t ); static void SaveNewMD5(char *, char *); static char ChageAscii_To_Hex(char *); static void TryTimeCheck(uint8_t ); static void UI_Process_Update(void); static void HBD_Ui_Update(uint8_t ); static void IapAppStore(uint32_t , uint8_t *, uint16_t ); static uint8_t DownLoaded_DataProcess(void); static uint8_t CopyFileListToFlash(SUT_FILE_LIST *, uint8_t); static void ExitRightNow(void); static uint32_t SaveLengthInFormat(char *dat); static uint8_t SetMark(uint32_t ); //////////////////////////// SUT_NET_STATUS sutNetStatus; unsigned char fotaDatabuffer[DATA_DRAT_SIZE_PER_TIME+11]; unsigned short fotaLen,reqLen; unsigned char getFirstPacked; ////启动IAP初始化 void MyIap_Init(void) { FotaSocketCtl(1); memset((unsigned char *)&sutNetStatus,0,sizeof(SUT_NET_STATUS)); NewTask(TASK_GET_FILEINFO); getFirstPacked=0; } ///////UI 选择 void SetUpAppricationVerPending(void) { if(KEY_PANEL_EXIT == g_ulKeyValue){ ExitRightNow(); } if(netPPP != OPEN){//检测PPP就好了 MeSpeak(ENCODE_ASCII, "CEDECDF8C2E7");//无网络 ExitRightNow(); SlwTrace(INF, (char *)No_Login_In,0); return; } StartIAP(); TickIAP(); UI_Process_Update(); } ///////IAP状态切换 static void NewTask(uint8_t task) { sutNetStatus.TaskStatus = task; sutNetStatus.TaskStart = 1; } static void StartIAP(void) { if(sutNetStatus.FotaTCP==0) return; if(!sutNetStatus.TaskStart) return; sutNetStatus.TaskStart = 0; switch(sutNetStatus.TaskStatus) { case TASK_GET_FILEINFO: //如果版本未请求--请求版本 if(!sutNetStatus.FileReqOk) //版本请求 IapGetUpdateVersion_FOGA(); break; case TASK_GET_FILEDATA: SlwTrace(INF, (char *)Ver_Ok_Dat_Start,0); break; case TASK_FILE_CHECK: SlwTrace(INF, (char *)App_Checking,0); HBD_Ui_Update(2); break; case TASK_GOTO_APP: SlwTrace(INF, (char *)Task_GoTo_App,0); HBD_Ui_Update(3); break; } } ///////IAP处理/////////////// static void TickIAP(void) { uint32_t len,offset; unsigned short crc,CRC16; char buf[50],temp[5]; static unsigned char timeCnt; static unsigned char reTime=0; static unsigned char timeOutCnt=0; if(++sutNetStatus.Tick10ms > TICK_COUNT) { sutNetStatus.Tick10ms = 0; //process switch(sutNetStatus.TaskStatus) { case TASK_GET_FILEINFO: //请求版本过程--检测是否超时--超明重新请求 if(0 == sutNetStatus.FileReqOk) {//超时未请求成功 sutNetStatus.getFileInfoTime++; if(sutNetStatus.getFileInfoTime < GET_FILE_TIMES) {//再请求一次 NewTask(TASK_GET_FILEINFO); }else{ //重请求次数超了,退出 sutNetStatus.errType=1;//获取文件失败 NewTask(TASK_EXIT); } }else NewTask(TASK_GET_FILEINFO); break; case TASK_GET_FILEDATA: if(0 == sutNetStatus.FileReqOk) {//未请求文件,则请求文件 NewTask(TASK_GET_FILEINFO); }else { //已请求成功,即下载数据时超时了 sutNetStatus.getDataInfoTime++; if(sutNetStatus.getDataInfoTime < GET_DATA_TIMES) {//再请求一次 SlwTrace(INF, "Req Data",1); IapGetUpdateData_FOGA(sutNetStatus.FileOffset,DATA_DRAT_SIZE_PER_TIME); }else{//重请求次数超了,退出 sutNetStatus.errType=2;//网络不好,多次重请求数据超时 NewTask(TASK_EXIT); } } break; case TASK_FILE_CHECK: //MD5总校验 switch(IapCheckFileMD5_SPI_Flash(sutNetStatus.MD5,2,0)) { case 0://OK NewTask(TASK_GOTO_APP); break; case 1://confinue sutNetStatus.errType=4;//MD5校验失败 SlwTrace(INF, (char *)MD5_Error,0); NewTask(TASK_EXIT); break; } break; case TASK_GOTO_APP: SetMark(GOOD_UPDATE_STORAGE); SlwTrace(INF, (char *)Reboot,0); //rt_tsk_lock();//这样就不会切换任务,其它任务就不会喂狗 //rt_suspend(); while(1); break; case TASK_EXIT: GuiShowStr(4,40,TRY_FAILED,0x01,0); switch(sutNetStatus.errType) { case 1: GuiShowStr(4,70,GET_FILE_ERR,0x01,0); break; case 2: GuiShowStr(4,70,NET_OVERTIME_ERR,0x01,0); break; case 3: GuiShowStr(4,70,SER_NO_FILE,0x01,0); break; case 4: GuiShowStr(4,70,MD5_VRY_ERR,0x01,0); break; } //os_dly_wait(200);//后续需要增加 ExitRightNow(); break; } } ///////TCP 持续维持/////// timeCnt++; if(timeCnt++ >=254) { timeCnt=0; reTime++; if(reTime < 3) { snprintf(buf, sizeof(buf), "AT+TCPSTATUS=%d\r\n", FOTA_IAP_SOCKET); ModemSendAt(buf); }else{ reTime=0; if(sutNetStatus.FotaTCP==0) FotaSocketCtl(1); } } } static uint32_t SaveLengthInFormat(char *dat) { uint32_t temp,i; temp = 0; for(i=0;i<4;i++){ temp <<= 8; temp |= (uint32_t)ChageAscii_To_Hex(dat+6-2*i); } return temp; } //针对FOTA升级时处理此终端UDP返回的数据 void FotaIap_Handle(unsigned char *msg) { char buf[60]; uint16_t i,j; uint16_t len1,len2; SUTDS ds; SUTDL dl1; SUTDL dl2; unsigned char *dataPtr; unsigned char cmd,checksum; SUT_FILE_INFO2 *pFileInfo; uint32_t toffset; STATUE ipStatus; if(!sutNetStatus.FotaTCP) return; IWDG_ReloadCounter(); //1,数据拆包 //1.1比较命令头,socket,IP,port,udp type //+TCPRECV:2,1, //+TCPRECV:2,1035, snprintf(buf, sizeof(buf), "+TCPRECV:%d,", FOTA_IAP_SOCKET); if(0 != strncmp((char *)msg, buf, 11)) return; //+TCPRECV:0,2,31 len1=atoi((char *)&msg[11]); if(len1 < 5) return;//至少5个字节 if(len1<10) dataPtr=&msg[13]; else if(len1<100) dataPtr=&msg[14]; else if(len1<1000) dataPtr=&msg[15]; else if(len1<10000) dataPtr=&msg[16]; else return; if(getFirstPacked == 0) {//首包 if(dataPtr[0] != PACKET_HEAD) { SlwTrace(INF, "HErr1",1); return; } ds.Data.ucData.b2=dataPtr[2]; ds.Data.ucData.b1=dataPtr[3]; len2=ds.Data.usData;//packetLen if(len1 < (len2+4)) {//有分包,此处作拷贝即可 memcpy(fotaDatabuffer, dataPtr, len1); fotaLen=len1; getFirstPacked=1; reqLen=len2+4; //SlwTrace(INF, "I need next packet", 1); return; }else if(len1 == (len2+4)) {//没有分包,可以直接包处理数据 goto PACKED_READY; }else{//有问题包,不处理 return; } } else{//分包 if(fotaLen+len1 == reqLen) { if(reqLen <= sizeof(fotaDatabuffer)) { memcpy(&fotaDatabuffer[fotaLen], dataPtr, len1); dataPtr=fotaDatabuffer; len1=reqLen; goto PACKED_READY; }else{ SlwTrace(INF, "BufferOver", 1); return; } }else{ //长度不对,丢弃 SlwTrace(INF, "WLenErr",1); getFirstPacked=0; return; } } PACKED_READY: //check length if(dataPtr[0] != PACKET_HEAD) { SlwTrace(INF, "HErr2",1); return; } cmd=dataPtr[1]; //check lenght ds.Data.ucData.b2=dataPtr[2]; ds.Data.ucData.b1=dataPtr[3]; len2=ds.Data.usData; if(len1!=(len2+4)){ SlwTrace(INF,"lenErr",1); return; } //checksum checksum=0; for(i=0;i<(len2+3);i++){ checksum^=dataPtr[i]; } if(checksum!=dataPtr[len2+3]){ SlwTrace(INF,"SumErr",1); return; } switch(cmd) { case CMD_GET_FILE_INFO_ACK: sutNetStatus.Tick10ms=0; pFileInfo=(SUT_FILE_INFO2 *)&dataPtr[4]; if(0!=strcmp(pFileInfo->FileName,sutNetStatus.FullFileName)){ SlwTrace(INF,"FileName error!",1); return; } //对于unsigned long类型的 FileLength 需要转换下高地位字节。因为网络传过来的是大端模式,MCU却是小端模式 dl1.Data.ulData=pFileInfo->FileLength; //文件总长度 dl2.Data.ucData.b1=dl1.Data.ucData.b4; dl2.Data.ucData.b2=dl1.Data.ucData.b3; dl2.Data.ucData.b3=dl1.Data.ucData.b2; dl2.Data.ucData.b4=dl1.Data.ucData.b1; sutNetStatus.FileLength=dl2.Data.ulData; sutNetStatus.encrypted=pFileInfo->encrypted; sutNetStatus.key=pFileInfo->key; memcpy(sutNetStatus.MD5,pFileInfo->MD5,16); if(sutNetStatus.FileLength==0) { sutNetStatus.errType=3;//服务器无请求的数据文件 SlwTrace(INF, "No file",1); NewTask(TASK_EXIT); break; } if(sutNetStatus.FileLength%2!=0){ SlwTrace(INF,"FLen is not even!",1); } NewTask(TASK_GET_FILEDATA); //请求文件数据 sutNetStatus.FileOffset=0; sutNetStatus.FileReqOk=1; IapGetUpdateData_FOGA(sutNetStatus.FileOffset,DATA_DRAT_SIZE_PER_TIME); break; case CMD_GET_FILE_DATA_ACK: sutNetStatus.Tick10ms=0; //offset dl1.Data.ucData.b4=dataPtr[4]; dl1.Data.ucData.b3=dataPtr[5]; dl1.Data.ucData.b2=dataPtr[6]; dl1.Data.ucData.b1=dataPtr[7]; toffset=dl1.Data.ulData; //len ds.Data.ucData.b2=dataPtr[8]; ds.Data.ucData.b1=dataPtr[9]; len1=ds.Data.usData; if(len2!=(len1+1+6)){ SlwTrace(DEBUG,"Recv file data len error!",1); } //保存到FLASH里 IapAppStore(APP_FILE_DATA_ADDR+toffset, &dataPtr[10], len1); //判断是否全部下载完成 if((toffset+len1)>=sutNetStatus.FileLength){ SlwTrace(INF,"Dowload complected!",1); //下载完成,校验MD5码 // GuiClearRect(0,40,160,58); // GuiShowStr(0,40,UPDATE_OK,0x01); NewTask(TASK_FILE_CHECK); }else{//未下载完成,申请下载下一包数据 HBD_Ui_Update(1); snprintf(buf, sizeof(buf),"HBD=%d",sutNetStatus.FileOffset);//Has been downloaded SlwTrace(INF, buf,1); sutNetStatus.FileOffset=toffset+len1; IapGetUpdateData_FOGA(sutNetStatus.FileOffset,DATA_DRAT_SIZE_PER_TIME); } break; } } /******************************************************************* 封包,获取新版本文件信息 |Head|Cmd|length(2) | data... | Check| Head 包头,固定为0xAB Cmd 命令字 length 后续的数据长度,包括到Check的长度 length=1+data.len Check 从Head开始按字节异或运算 data: unsigned long PSN;//终端编号 char FileName[20];//文件名,不够的在末尾补0 总长 24+5=29 bytes *******************************************************************/ unsigned short PacketGetFileInfo(unsigned char *buf) { unsigned char checksum; unsigned short i,j,k; SUTDL dl; SUTDS ds; j=0; memset(buf,0,29); buf[j++]=PACKET_HEAD; buf[j++]=CMD_GET_FILE_INFO; buf[j++]=0; buf[j++]=24+1;//数据24字节,1字节checksum //PSN dl.Data.ulData=sutProductPara.PSN; //因为协议要求大端模式传输,所以需要转一下 buf[j++]=dl.Data.ucData.b4; buf[j++]=dl.Data.ucData.b3; buf[j++]=dl.Data.ucData.b2; buf[j++]=dl.Data.ucData.b1; //FileName memset(sutNetStatus.FullFileName, 0, sizeof(sutNetStatus.FullFileName)); snprintf(sutNetStatus.FullFileName, sizeof(sutNetStatus.FullFileName), "%s_V%d.bin", sutProductPara.ProductName,ui_version); for(i=0;i<20;i++){ buf[j++]=sutNetStatus.FullFileName[i]; } //校验 checksum=0; for(i=0;isizeof(txbuf)){ SlwTrace(INF,"txbuf over!",1); return; } tcpSocketSendData(FOTA_IAP_SOCKET,txbuf,len); } /******************************************************************* 封包,获取新版本 |Head|Cmd|length(2) | data... | Check| Head 包头,固定为0xAB Cmd 命令字 length 后续的数据长度,包括到Check的长度 length=1+data.len Check 从Head开始按字节异或运算 data: unsigned long PSN; //终端编号 unsigned char FileName[20]; //文件名 如:RT101_V102.bin unsigned long offset; //请求数据在文件中的开始位置 unsigned short len; //请求数据的长度,服务器返回的数据可能小于等于此长度 *******************************************************************/ unsigned short PacketGetFileData(unsigned char *buf,unsigned int offset,unsigned short len) { unsigned char checksum; unsigned short i,j; SUTDL dl; SUTDS ds; j=0; memset(buf,0,35); buf[j++]=PACKET_HEAD; buf[j++]=CMD_GET_FILE_DATA; buf[j++]=0; buf[j++]=30+1;//数据18字节,1字节checksum //PSN dl.Data.ulData=sutProductPara.PSN; //因为协议要求大端模式传输,所以需要转一下 buf[j++]=dl.Data.ucData.b4; buf[j++]=dl.Data.ucData.b3; buf[j++]=dl.Data.ucData.b2; buf[j++]=dl.Data.ucData.b1; //FileName for(i=0;i<20;i++){ buf[j++]=sutNetStatus.FullFileName[i]; } //offset dl.Data.ulData=offset; //因为协议要求大端模式传输,所以需要转一下 buf[j++]=dl.Data.ucData.b4; buf[j++]=dl.Data.ucData.b3; buf[j++]=dl.Data.ucData.b2; buf[j++]=dl.Data.ucData.b1; //len ds.Data.usData=len; buf[j++]=ds.Data.ucData.b2; buf[j++]=ds.Data.ucData.b1; //校验 checksum=0; for(i=0;isizeof(txbuf)){ SlwTrace(INF,"txbuf over!",1); return; } tcpSocketSendData(FOTA_IAP_SOCKET,txbuf,l); } ////////////////////相关子方法 //"3a" or "3A" to 0x3a static char ChageAscii_To_Hex(char *dat) { char temp[2]; uint8_t i; for(i=0;i<2;i++){ if(dat[i] >= '0' && dat[i] <= '9') temp[i] = dat[i] - 0x30; else if(dat[i] >= 'A' && dat[i] <= 'Z') temp[i] = dat[i] - 0x37; else if(dat[i] >= 'a' && dat[i] <= 'z') temp[i] = dat[i] - 0x57; } return ((temp[0]<<4) | temp[1]); } //保存以ASCII形式的数据为十六进制放回dat 实际数据长度减半 static void ChangeDataToHex(char *dat, uint16_t len) { uint16_t i; for(i=0;i 16 HEX static void SaveNewMD5(char *dat, char *des) { uint8_t i; for(i=0;i<16;i++) des[i] = ChageAscii_To_Hex(dat+2*i); } static void ExitRightNow(void) { FotaSocketCtl(0); UISetNextStatus(UIS_MENU_SYS_SET);//退出升级操作 } //FOTA 开关宏控制 //FOTA 打印宏控制 static void Door_Ctrl(uint8_t flag) { if(flag){ Fota_Rcv_Pri_Flag = 0; ////////////////////////// g_uiGpsStat=0; }else{ Fota_Rcv_Pri_Flag = 1; ////////////////////////// g_uiGpsStat=1; } } //SOCKET OPEN OR CLOSE static void FotaSocketCtl(uint8_t ctl) { char buf[50]; if(ctl){//open snprintf(buf, sizeof(buf), "AT+TCPOPEN=%d,%s:%d\r\n",FOTA_IAP_SOCKET,FOTA_IAP_IP, FOTA_IAP_PORT); Door_Ctrl(ctl); }else{//close snprintf(buf, sizeof(buf), "AT+TCPCLOSE=%d\r\n", FOTA_IAP_SOCKET); Door_Ctrl(ctl); } ModemSendAt(buf); SlwTrace(INF, buf,0); } static void IapAppStore(uint32_t addr, uint8_t *buf, uint16_t len) { sFlash_Write(buf,addr,len); } //return 0 校验正确 //return 1 错误 //type 1 block 1 //type 2 block 2 //spical 0 no need to change first 4 bytes to 0 after read out //spical 1 need to change first 4 bytes to 0 after read out static int IapCheckFileMD5_SPI_Flash(uint8_t *MD,uint8_t type,uint8_t spical) { //总数据大小为 IapPra.u_filesize; MD5_CTX mdContext; uint32_t Read_file_size; uint32_t read_addr,startAddr; uint8_t buf[1024],finished_flag,temp; uint16_t read_len,i; char tempbuf[5]; uint8_t firstTime; firstTime = 0; if(type == 1) startAddr = FILE_INDEX_ADDR; else if(type == 2) startAddr = APP_FILE_DATA_ADDR; else return 1; if(!spical)firstTime=1; Read_file_size = 0; read_addr = 0; finished_flag = 0; MD5Init(&mdContext); do{ if(sutNetStatus.FileLength - Read_file_size >= 1024) read_len = 1024; else{ read_len = sutNetStatus.FileLength - Read_file_size; finished_flag = 1; } sFlash_Read(buf, startAddr+read_addr, read_len); if(!firstTime){ firstTime ++; buf[0] = 0;buf[1] = 0;buf[2] = 0;buf[3] = 0; } Read_file_size += read_len; read_addr += read_len; MD5Update(&mdContext, buf, read_len); }while(!finished_flag); MD5Final(&mdContext); //check for(i=0;i<16;i++){ if(MD[i] != mdContext.digest[i]) break; } if(i<16) return 1; else return 0; } static void UI_Process_Update(void) { char buf[22]; uint8_t persent,showFlag; showFlag = 0; switch(sutNetStatus.iapUI.update) { case 1: persent = 100*sutNetStatus.iapUI.down_size/sutNetStatus.iapUI.total_size; #if(USING_LANGUAGE==USING_CHINESE) snprintf(buf, sizeof(buf), " 已下载百分之 %d \r\n", persent); #else snprintf(buf, sizeof(buf), " DownLoad %d \r\n", persent); #endif showFlag ++; break; case 2: snprintf(buf, sizeof(buf), App_Checking); showFlag ++; break; case 3: snprintf(buf, sizeof(buf), Reboot_Mini); //MeSpeak(ENCODE_ASCII,(char *)VOIC_REBOOT,0); IWDG_ReloadCounter(); DelayMs(1000); IWDG_ReloadCounter(); showFlag ++;break; } if(showFlag) GuiShowStr(0,70,buf,1,0); sutNetStatus.iapUI.update = 0; } static void HBD_Ui_Update(uint8_t type) { sutNetStatus.iapUI.down_size = sutNetStatus.FileOffset; sutNetStatus.iapUI.total_size=sutNetStatus.FileLength; sutNetStatus.iapUI.update = type; } void SetUpAppricationVerShow(int update) { char buf[30]; if(update){ ui_version = PRODUCT_VERSION+1; GuiClearAll(); ShowCaption(MESSG1,0); //升级应用版本 GuiDrawHLine(0,159,20,1); //sprintf(buf, " 是否升级到 V%d ", ui_version);//是否升级到 V%d //GuiShowStr(0,56,buf,1); snprintf(buf, sizeof(buf), " 当前版本: V%d ", PRODUCT_VERSION);//是否升级到 V%d GuiShowStr(0,44,buf,1,0);//当前版本 snprintf(buf, sizeof(buf), " 升级到:V%d ", ui_version); GuiShowStr(0,68,buf,1,0); //GuiReverseRect(96,68,24,16); GuiDrawHLine(0,159,104,1); GuiShowStr(0,110,MESSG3,0x01,0);//[OK]升级 [EXIT]退出 } } void SetUpAppricationVerResponse(void) { char buf[19],update; static char APP_Flag=0; if(KEY_PANEL_MENU==g_ulKeyValue){//因为没有UDP指令,暂时没有此功能 UISetNextStatus(UIS_UP_APP_PENDING); GuiClearArea(0, 56, 160, 24); //SpeakerEnable(); //ModemSendAt((char *)UP_PRO_VER); //正在处理请稍候 //MeSpeak(ENCODE_UNICODE, (char *)UP_PRO_VER, 0); GuiShowStr(4,40,UPDATE_ING,0x01,0);//正在处理,请稍候... GuiShowStr(4,70,VER_REQ_ING,0x01,0);// 版本请求中... GuiShowStr(0,110,EXIT_CANCLE,0x01,0); IWDG_ReloadCounter(); //os_dly_wait(200); 后续需要增加 MyIap_Init(); }else if(KEY_PANEL_EXIT==g_ulKeyValue) UISetNextStatus(UIS_MENU_SYS_SET); //else if(KEY_PANEL_MENU==g_ulKeyValue) UISetNextStatus(UIS_MENU_MAIN); else if(KEY_PANEL_UP == g_ulKeyValue || KEY_PANEL_DOWN == g_ulKeyValue) { update=0; if(KEY_PANEL_UP == g_ulKeyValue) { ui_version ++; update ++; }else if(KEY_PANEL_DOWN == g_ulKeyValue && ui_version > PRODUCT_VERSION+1) { ui_version --; update ++; } if(update) { snprintf(buf, sizeof(buf), " 升级到:V%d ", ui_version); GuiShowStr(0,68,buf,1,0); //GuiReverseRect(96,68,24,16); } } else if(KEY_OPTION==g_ulKeyValue) { // //对讲版本升级,长按P1+P3 3秒,可退出后再进入 // if(APP_Flag == 0) // { // g_ucUKC=0; // APP_Flag++; // }else // { // if(g_ucUKC>3){ // UISetNextStatus(UIS_UP_INTERCOM_VER); // APP_Flag =0; // } // } } else APP_Flag=0; } //type 1, 文件索引保存到块1 //type 2, 文件索引保存到块2 static void SaveFileIndexCtl(uint8_t *p_sutFileList, uint8_t type) { if(type == 1) sFlash_Write(p_sutFileList,FILE_INDEX_ADDR,sizeof(SUT_FILE_LIST)); else if(type == 2) sFlash_Write(p_sutFileList,APP_FILE_DATA_ADDR,sizeof(SUT_FILE_LIST)); } static uint8_t SetMark(uint32_t value) { uint8_t buf[4],i; for(i=0;i<4;i++) buf[i] = value>>(i*8); /* 改为内部FLASH 置位。 */ // sFlash_Write(buf, APP_FILE_DATA_ADDR, 4); memcpy(sutProductPara.FoTaMark,"FOTA",4);//FOTA sutProductPara.AppLen=sutNetStatus.FileLength; sutProductPara.ExAddr=APP_FILE_DATA_ADDR; memcpy(sutProductPara.MD5,sutNetStatus.MD5,16); SaveProductParaToFlash(); }