123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577 |
- /*
- authFota.c
- 应用授权和FOTA升级功能
- 应用授权:请求服务器授权情况,授权则应用功能正常,否则应用不启动对讲功能
- FOTA升级:请求服务器是否有新对讲版本可以更新,如果有且用户确认升级,则执行升级(需要module支持/或者通过tcp自定义协议完成)
- */
- #include "includes.h"
- #include "http.h"
- #define BUF_SIZE 100
- #define AUTH_FOTA_PORT 9138
- #ifdef ENABLE_OPENHPOC
- #define FOTA_AUTH_VERSION OHPOC_VERSION
- #define FOTA_AUTH_MODLE OHPOC_MODLE
- #define FOTA_AUTH_CT OHPOC_CUST
- #else
- #define FOTA_AUTH_VERSION HPOC_VERSION
- #define FOTA_AUTH_MODLE HPOC_MODULE_TYPE
- #define FOTA_AUTH_CT CUST_STR
- #endif
- typedef enum{
- AF_IDLE,
- AF_WAIT_READY,
- AF_READY,
- AF_TCP,
- AF_TCP_WAIT,
- AF_SEND_WAIT_ACK,
- AF_WAIT_USER_CONFIRM,
- AF_ACK_UPDATE_POC,
- AF_STOP,
- AF_END
- }AF_ENUM;
- T_INT16 serverAck=0;
- T_INT8 rightFlag=0;//0,unknow result, 1, have right, else no right
- T_INT8 wgetPath[64];
- T_INT32 targetVersion;
- static AF_ENUM fotaStatus=AF_IDLE;
- static TUPSEND_DEF tupsendPara;
- static void saveAuth(T_INT8 *imei,T_INT8 flag);
- static void infoPacketAndSend(T_UINT32 psn,T_INT8 *imei, T_UINT32 version,T_INT8 *modemType,T_UINT8 udpvalue2_3,T_UINT8 udpvalue4);
- static T_INT8 RecvDataHandle(T_UINT8 *src, T_UINT16 length);
- static void tellHgsPocUpdateUdpByQue(T_UINT8 udptime2_3,T_UINT8 udptime4);
- void fillTargetVersion(char *filePath, int *targetversion){
- //120.77.66.129/higos/fotaFiles/N58_POC_ZT_2000.bin
- //-->120.77.66.129/higos/fotaFiles/N58_POC_ZT_2000.bin
- int i;
- char findDot=0;
- char info[30];
- for(i=strlen(filePath)-1;i>=0;i--){
- if(findDot==0){
- if(filePath[i]=='.') findDot=1;
- }else if(filePath[i]=='_'){
- *targetversion=atoi(filePath+i+1);
- //if(targetversion>HPOC_VERSION){
- // filePath[i+1]=0;
- // snprintf(info, sizeof(info), "%d%d.pack",HPOC_VERSION,*targetversion);
- // strcat(filePath,info);
- //}
- return;
- }
- }
- }
- T_UINT8 tudptime2_3,tudptime4;
- /*
- authFotaRecv_cb
- PLATFORM_MS5700平台udp接收回调操作入口
- */
- void authFotaRecv_cb(void *param){
- unsigned char *pdata;
- int len_ret;
- //T_UINT8 buffer[BUF_SIZE];
- nwy_osiEvent_t *pEvent = (nwy_osiEvent_t *)param;
- TUPSEND_DEF *para=(TUPSEND_DEF *)pEvent->param3;
- T_BOOL needExitThread=FALSE;
- static T_UINT8 handleDataOk=FALSE;
- showTupEventInfo("authFota",pEvent->id,para,0);
- switch(pEvent->id){
- case TUP_EVENT_SOCK_LINK_OK:
- if(AF_TCP_WAIT==fotaStatus) fotaStatus=AF_SEND_WAIT_ACK;
- break;
- // case LSAPI_SOCK_TCPIP_SOCKET_SEND_RSP:break;
- // case LSAPI_SOCK_TCPIP_SOCKET_CLOSE_RSP:
- // wlog_warn("authfota client close");
- // serverAck=-1;
- // needExitThread=TRUE;
- // break;
- case TUP_EVENT_SOCK_LINK_RECV:
- pdata=(unsigned char *)pEvent->param1;
- len_ret=pEvent->param2;
- if(FALSE==handleDataOk){
- len_ret=RecvDataHandle(pdata, len_ret);
- wlog_info("RecvDataHandle return %d", len_ret);
- if(len_ret==0) handleDataOk=TRUE;//成功处理一包后不再处理了
- }
- break;
- case TUP_EVENT_SOCK_LINK_SERVER_SHUT:break;
- default: break;
- }
- // LSAPI_OSI_Free(pEvent);
- // if(TRUE==needExitThread) threadPostEvent(nwy_get_current_thread(),USER_EVENT_EXIT);
- }
- void isAutoFotaIdle(void){
- if(fotaStatus==AF_END || fotaStatus==AF_WAIT_USER_CONFIRM) ticketVote(TICKET_PT_AUTH);
- else ticketDeVote(TICKET_PT_AUTH);
- }
- /*
- ptAuthFotaTask
- 负责授权、FOTA升级任务操作
- */
- PT_THREAD (ptAuthFotaTask(pt_timer_t *ptPool, struct pt *pt)){
- static pt_timer_t ptTimer;
- static T_UINT8 index,i;
- static T_INT16 timeout;
- static T_INT8 ipAddr[20];
- T_UINT8 ret;
- static T_INT8 *fAddr;
- PT_BEGIN(pt);
- while(1){
- //if(TCP_LOGIN_SUCC==talking.tcpLoginStatus)
- //goto PTHREAD_END;
- if(AF_IDLE==fotaStatus){
- fAddr=paras.fotaServer;
- if(talking.netWork.pdp==0 || fAddr==NULL || talking.getImeiFlag==FALSE){
- wlog_warn("pdp:%d,imei:%d,fAddr:%s, wait", talking.netWork.pdp,talking.getImeiFlag,fAddr);
- fotaStatus=AF_WAIT_READY;
- }else fotaStatus=AF_READY;
- }else if(AF_WAIT_READY==fotaStatus){
- if(talking.netWork.pdp==1 && fAddr != NULL && talking.getImeiFlag==TRUE){
- fotaStatus=AF_READY;
- wlog_info("authFota:ready");
- }
- }else if(AF_READY==fotaStatus){
- if(FALSE==setDomainForIp(fAddr, &index)){
- wlog_warn("authFota domain fun busy, retry later");
- PTTimerStart(ptPool, &ptTimer,300);//3 seconds later retry
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
- }else{
- i=0;
- while(1){
- ret=getDomainForIp(index, ipAddr, sizeof(ipAddr));
- if(ret==DOMAIN_ERR){
- wlog_error("authFota domain fail , quit");
- fotaStatus=AF_END;break;
- }else if(DOMAIN_OK==ret){
- wlog_info("authFota domain done:%s", ipAddr);
- tupParaSet(&tupsendPara, AUTH_FOTA_PORT, authFotaRecv_cb,AUTH_UDP_THREAD_STACK);
-
- fotaStatus=AF_TCP;
- break;
- }else{
- PTTimerStart(ptPool, &ptTimer,50);//wait 0.5 per time
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
- if(++i>=20){//当AUTH与POC同时处理时,有可能AUTH会比较迟才处理域名结果
- wlog_error("authFota domain timeout, quit");
- fotaStatus=AF_END;break;
- }
- }
- }
- }
- }else if(AF_TCP==fotaStatus){
- //do tcp connect
- if(1==talking.netWork.pdp){
- switch(tryConnectTup(ipAddr,TUP_UDP,&tupsendPara)){
- case TUP_STATUS_TRUE:
- wlog_info("authFota connect server ok");
- fotaStatus=AF_SEND_WAIT_ACK;
- break;
- case TUP_STATUS_FALSE:
- wlog_warn("authFota connect server failed, retry after 3 seconds");
- PTTimerStart(ptPool, &ptTimer,300);//3 seconds later retry
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
- break;
- case TUP_STATUS_WAIT:
- fotaStatus=AF_TCP_WAIT;
- break;
- }
- }
- }else if(AF_SEND_WAIT_ACK==fotaStatus){
- //send request and wait ack
- timeout=5;
- do{
- if(1==talking.netWork.pdp){
- infoPacketAndSend(paras.psn,talking.imei,FOTA_AUTH_VERSION,FOTA_AUTH_MODLE,paras.udpHeartTick_none_4G,paras.udpHeartTick_4G);
- timeout--;
- }else wlog_warn("pdp of , wait");
- PTTimerStart(ptPool, &ptTimer,200);//2 seconds later retry
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
- }while(timeout && serverAck==0);
- saveAuth(talking.imei,rightFlag);
- userCloseSocket(&tupsendPara.fd);
- if(timeout==0 || serverAck==-1 ||serverAck==0){
- msgToOutter("+CSERVER:DENY\r\n");
- wlog_warn("udp server no ack, exit");
- fotaStatus=AF_END;
- goto PTHREAD_END;
- }
- if(1==serverAck){
- wlog_info("get server ack");
- tellHgsPocUpdateUdpByQue(tudptime2_3,tudptime4);
- }else if(2==serverAck){
- wlog_info("no extend info, exit");
- fotaStatus=AF_END;
- goto PTHREAD_END;
- }else{
- wlog_info("ack data not fit, exit");
- fotaStatus=AF_END;
- goto PTHREAD_END;
- }
- if(FOTA_AUTH_VERSION>=targetVersion){
- wlog_info("No new version, exit");
- fotaStatus=AF_END;
- goto PTHREAD_END;
- }
- talking.fota_version=targetVersion;
- wlog_info("fota is available:%d,%d",FOTA_AUTH_VERSION,targetVersion);
- fotaStatus=AF_WAIT_USER_CONFIRM;
- }else if(AF_WAIT_USER_CONFIRM==fotaStatus){
- if(talking.userFotaConfirm==TRUE){
- fotaStatus=AF_ACK_UPDATE_POC;
- talking.userFotaConfirm=FALSE;
- msgToOutter("+FOTA:1\r\n");
- wlog_info("start to update poc");
- }
- }else if(AF_ACK_UPDATE_POC==fotaStatus){
- //try to update poc
- tryUpdateLte(wgetPath);
- do{
- ret=getLteUpdateStatus();
- if(ret==LTE_UPDATE_FAILED) fotaStatus=AF_WAIT_USER_CONFIRM;
- else if(ret==LTE_UPDATE_DONE) fotaStatus=AF_END;
- PTTimerStart(ptPool, &ptTimer,10);//should be fast
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
- }while(LTE_UPDATE_BUSY==ret);
- }else if(AF_TCP_WAIT==fotaStatus){
- if(tupsendPara.tupStatus==CNNT_TOUT) fotaStatus=AF_END;
- }
- PTHREAD_END:
- isAutoFotaIdle();
- PTTimerStart(ptPool, &ptTimer,100);//should be fast
- PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
- }
- PT_END(pt);
- }
- /*
- translateBeforeSend
- 部标协议数据发送前转义接口
- */
- static T_UINT16 translateBeforeSend(T_UINT8 *src, T_UINT16 length){
- //0x7E-->0X7D,0X02
- //0X7D-->0X7D,0X01
- T_UINT8 temp[BUF_SIZE*2];
- T_UINT16 i,retlen;
- retlen=0;
- for(i=0;i<length;i++){
- if(src[i]==0x7E){
- temp[retlen++]=0x7D;
- temp[retlen++]=0x02;
- }else if(src[i]==0x7D){
- temp[retlen++]=0x7D;
- temp[retlen++]=0x01;
- }else{
- temp[retlen++]=src[i];
- }
- }
- memcpy(src, temp, retlen);
- return retlen;
- }
- /*
- infoPacketAndSend
- 部标协议打包数据并发送
- */
- static void infoPacketAndSend(
- T_UINT32 psn,
- T_INT8 *imei,
- T_UINT32 version,
- T_INT8 *modemType,
- T_UINT8 udpvalue2_3,
- T_UINT8 udpvalue4){
- T_UINT8 sendbuf[BUF_SIZE];
- T_UINT8 *ptr=sendbuf;
- T_UINT8 *startPtr=sendbuf+1;
- T_UINT8 sum=0,*imeiPtr,th,tl;
- T_UINT16 i,len;
- T_INT8 temp[20];
- T_INT32 ret;
- static T_UINT16 liushui=0;
- len=0;
- //make login info
- //start indicator
- ptr[len++]=0x7E;
- //header
- //sms type 2bytes
- ptr[len++]=0x09;
- ptr[len++]=0x29;
- //sms property 2bytes
- i=59;//only low 10bits are define as sms length
- ptr[len++]=i>>8;//no sub packets,no encrypt
- ptr[len++]=i;//sms length
- //device SN 6bytes
- snprintf(temp, sizeof(temp),"%012d",psn);
- for(i=0;i<6;i++){
- th=temp[2*i];
- tl=temp[2*i+1];
- th <<= 4;th &= 0xF0;
- tl &= 0x0F;
- ptr[len++]=th | tl;
- }
- //serial nuber 2bytes
- ptr[len++]=(liushui>>8)&0xFF;
- ptr[len++]=liushui&0xFF;
- liushui++;
- //sms info
- //poc modle:EC20TGA_POC 16bytes
- memset(&ptr[len], 0, 16);
- snprintf(temp, sizeof(temp), "%s_%s",FOTA_AUTH_MODLE,FOTA_AUTH_CT);
- memcpy(&ptr[len],temp,16);
- len += 16;
- //poc version 4bytes
- ptr[len++]=version>>24;
- ptr[len++]=version>>16;
- ptr[len++]=version>>8;
- ptr[len++]=version;
- //mcu modle 16bytes
- memset(&ptr[len], 0, 16);
- len += 16;
- //mcu version 4bytes
- memset(&ptr[len], 0, 4);
- len += 4;
- //NET CODE:IMEI 16:fill 15bytes
- memset(&ptr[len], 0, 16);
- memcpy(&ptr[len], imei, 15);
- len += 16;
- //current udp2_3 heart time 1byte
- ptr[len++]=udpvalue2_3;
- //current udp4 heart time 1byte
- ptr[len++]=udpvalue4;
- //current gps upload time 1byte
- ptr[len++]=0;
- //verify code
- for(i=1;i<len;i++) sum ^= sendbuf[i];
- ptr[len++]=sum;
- //translate
- len=translateBeforeSend(sendbuf+1,len-1)+1;
- sendbuf[len++]=0x7E;
- //printf("Len:%d\r\n",len);
- //for(i=0;i<len;i++) printf("%02x",sendbuf[i]);
- //printf("\r\n");
- //send now
- //wlog_info("udp send data len %d\n", len)
- trySendTup(sendbuf,len,TUP_UDP,&tupsendPara);
- }
- /*
- translateAfterRecv
- 部标协议数据接受后转义接口
- */
- static T_UINT16 translateAfterRecv(T_UINT8 *src, T_UINT8 *in_src,T_UINT16 length){
- T_UINT16 i,retlen=0;
- T_UINT8 lastByte=0xff;
- T_UINT8 *savePtr=src;
-
- for(i=1;i<length-2;i++){
- if(lastByte==0x7D){
- if(in_src[i]==0x01){
- *savePtr++=0x7D;
- retlen++;
- }else if(in_src[i]==0x02){
- *savePtr++=0x7E;
- retlen++;
- }else{
- *savePtr++=in_src[i];
- retlen++;
- }
- }else{
- *savePtr++=in_src[i];
- retlen++;
- }
- lastByte=in_src[i];
- }
- return retlen;
- }
- /*
- findTargetVersion
- 从字符串口获取应用的最新版本号
- */
- static T_INT32 findTargetVersion(T_INT8 *src){
- int i,ver=0;;
- char findDot=0;
- //M5700_POC_ZT_2006.pack
- //M5700_POC_SFE_2006.pack
- //M5700_POC_COM_2006.pack
- for(i=strlen(src)-1;i>=0;i--){
- if(findDot==0){
- if(src[i]=='.') findDot=1;
- }else if(src[i]=='_'){
- return atoi(src+i+1);
- }
- }
- return 0;
- }
- /*
- updateLocalTime
- 更新系统时间接口
- */
- static void updateLocalTime(char *bcdtime){
- //19-06-12 11:57:12
- MY_CLOCK clock;
- clock.year=bcdToDec(bcdtime[0])+2000;
- clock.month=bcdToDec(bcdtime[1]);
- clock.day=bcdToDec(bcdtime[2]);
- clock.hour=bcdToDec(bcdtime[3]);
- clock.min=bcdToDec(bcdtime[4]);
- clock.sec=bcdToDec(bcdtime[5]);
- setMyClock(clock);
- wlog_info("UpdateDate:%d-%02d-%02d %02d:%02d:%02d",clock.year,clock.month,clock.day,clock.hour,clock.min,clock.sec);
- }
- /*
- tellHgsPocUpdateUdpByQue
- 授权时从服务器发下的应用udp心跳维持时间的更新
- */
- static void tellHgsPocUpdateUdpByQue(T_UINT8 udptime2_3,T_UINT8 udptime4){
- T_INT8 info[30];
- snprintf(info, sizeof(info), "+UDP=%d,%d\r\n",udptime2_3,udptime4);
- msgFromInner(info, strlen(info));
- wlog_warn("Tell info:%s", info);
- }
- void showtestinfo(char type){
- wlog_info("showtest info:%d",type);
- nwy_sleep(10);
- }
- /*
- RecvDataHandle
- 解析授权响应数据
- */
- static T_INT8 RecvDataHandle(T_UINT8 *src, T_UINT16 length){
- T_UINT16 i,j;
- T_INT32 k;
- T_UINT8 num_7E=0,sum=0,reallen;
- T_UINT16 takenotelen=0,temp;
- T_UINT8 temBuf[BUF_SIZE*2];
- T_UINT8 *realPtr;
- T_UINT8 filePath[80];
- T_UINT8 gpsTime;
- for(i=0;i<length;i++){
- takenotelen++;
- if(src[i]==0x7E){
- if(++num_7E>=2){
- break;
- }
- }
- }
- memcpy(temBuf, src,takenotelen);
- if(num_7E != 2 || takenotelen<=2) return 1;
- j=translateAfterRecv(temBuf,src,takenotelen);
- if(j<12) return 2;//header len err
- if(temBuf[0] != 0x89 || temBuf[1] != 0x29) return 3;//ID not fit
- temp = temBuf[2];temp <<= 8;temp &= 0xFF00;
- temp |= temBuf[3];
- if(((temp >> 10)&0xF) != 0) return 4;//no support sub packet or encrypt
- temp &= 0x3FF;//sms length
- if((12+temp) != j) return 5;//packet length err
- for(i=0;i<j-0;i++) sum ^= temBuf[i];
- if(sum != temBuf[j+1]) return 6;//sum err
- realPtr = temBuf + 12+6;
- //handle ack info
- if(realPtr[0]==1){
- rightFlag=1;//have right
- updateLocalTime(realPtr-6);
- }
- else rightFlag=0;//no right
- //这里调用tellHgsPocUpdateUdpByQue(realPtr[1],realPtr[2]);好像是不够堆栈,放在外层处理吧
- tudptime2_3=realPtr[1];
- tudptime4=realPtr[2];
- gpsTime=realPtr[3];
- realPtr += 4;//point to extend info
- temp -= 9;//extend info length
- k=temp;
- while(k>0){
- if(realPtr[0]==1){
- //take type 1 info, for poc update
- i=realPtr[1];//take length
- //decrypt
- realPtr += 2;
- for(j=0;j<i;j++){
- if(j % 2 !=0) filePath[j]=realPtr[j] ^ 0xB8;
- else filePath[j]=realPtr[j] ^ 0x56;
- }
- filePath[j]=0;
- wlog_info("Get file path:%s",filePath);
- //backup file path
- strcpy(wgetPath,filePath);
- fillTargetVersion(wgetPath,&targetVersion);
- wlog_info("target:%d,%s",targetVersion,wgetPath);
- serverAck=1;
- return 0;
- }else k -= (1+1+realPtr[1]);
- }
- serverAck=2;
- return 7;
- }
- /*
- DecodeImeiBytes
- 授权码加密
- */
- void DecodeImeiBytes(T_INT8 *imei){
- T_UINT8 i,j,seeds='w';
- j='j';
- for(i=0;i<IMEI_SIZE;i++){
- imei[i] ^= seeds;
- seeds += j;
- j += 'l';
- }
- }
- /*
- saveAuth
- 保存授权码
- */
- static void saveAuth(T_INT8 *imei,T_INT8 flag){
- T_UINT8 writebuf[64],tmp[10];
- T_UINT16 length,i;
- T_INT8 tempImei[IMEI_SIZE];
- memcpy(tempImei, imei,IMEI_SIZE );
- switch(flag){
- case 0:wlog_warn("auth no save authfile"); return;
- case 1:wlog_warn("auth have right");
- DecodeImeiBytes(tempImei);break;
- case 2:wlog_warn("auth have no right");
- default:memset(tempImei,0x55,IMEI_SIZE);
- break;
- }
-
- length=0;
- for(i=0;i<IMEI_SIZE;i++){
- snprintf(tmp,sizeof(tmp),"%02x",tempImei[i]);
- writebuf[length++]=tmp[0];
- writebuf[length++]=tmp[1];
- }
- //save code bellow
- saveAuthEncode(writebuf,length);
- }
|