/******************************************************************************** * File Name: HgsTcpProc.c * Function Describe:The HgsTcpProc for the system * Relate Module: * Explain: Hardware version is * Writer: wuzhao * Date: 2016.12.8 *******************************************************************************/ //-------------------------------------------------------------------------------- #include "includes.h" CONFIG_SER_DEF sutConfig; #define POC_TIME_OUT_1 180 //seconds #define POC_TIME_OUT_2 60 //TCP连接失败或发送登陆包超三次后重新按此时间计时 //负载均衡思想 //目的,后台管理会给终端分配所属交换服务器 //终端处理方法: //1、每次开机都会访问管理服务器ManaIP,如果成功则获取到非0的IP,检测是否与本地原PIP一致,如果不一致,则重置模块参数,并保存新PIP到本地,然后重启整机系统 //2、如果开机后登陆不上(判定A)交换IP,则启动登陆管理服务器获取新IP,如果与本地一致,不改变本地参数,继续登陆交换服务器,如果一致,则更新并复位整机系统 //3、如果成功登陆过后,然后掉线后再也登陆不上(判定B)交换服务器,则启动登陆管理服务器获取新IP,如果与本地一致,不改变本地参数,继续登陆交换服务器,如果一致,则更新并复位整机系统 //判定A:即未登陆状态,从配置完POC参数后开始计时(PocTimeoutCnt),如果登录成功则重置PocTimeoutCnt计数,且不再计数,如果掉线后则再次清PocTimeoutCnt且开始计时,超过3分钟(待定)则判定成功 //判定B:与判定A后半部分类似,即从掉线后开始计时 //注意,执行访问管理服务器时,我们就不处理GPS了。因为此模块查询TCP状态返回不带SOCKET,且代码模式如果更改会比较复杂 unsigned char CCID[21]; unsigned char HigosSendFlag;//发送login包的次数 unsigned char HgsConnetCnt;//发起连接次数 unsigned char HgsConnetStatus;//tcp连接状态 unsigned char HgsProcessResult;//0未知道结果或没测试 1测试不成功, 2测试通过 unsigned char PocStartCnt; unsigned short PocTimeoutCnt,newCOUNT; //load part unsigned char tcpControl; //根据不同的cmd往buffer填充相应的值 //当前支持cmd = 0x12 0x19 unsigned short SendTcpDataFill(unsigned char *buffer, unsigned char cmd,unsigned char status,unsigned char value) { unsigned char *p = buffer; unsigned short i,j; unsigned char nowCIP[4],nowPIP[4],nowGIP[4]; unsigned short nowCPort,nowPPort,nowGPort; SUTDL dl; SUTDS ds; i=0; //PSN dl.Data.ulData = sutProductPara.PSN; p[i++] = dl.Data.ucData.b4; p[i++] = dl.Data.ucData.b3; p[i++] = dl.Data.ucData.b2; p[i++] = dl.Data.ucData.b1; //PASS if(cmd == 0x12) { dl.Data.ulData = 0; p[i++] = dl.Data.ucData.b4; p[i++] = dl.Data.ucData.b3; p[i++] = dl.Data.ucData.b2; p[i++] = dl.Data.ucData.b1; } //PName for(j=0;j<8;j++) p[i++]= sutProductPara.ProductName[j]; //CurVer ds.Data.usData = sutProductPara.ProductVersion; p[i++] = ds.Data.ucData.b2; p[i++] = ds.Data.ucData.b1; //CCID for(j=0;j<20;j++) p[i++]= CCID[j]; if(cmd == 0x19) { p[i++] = status; p[i++] = value; if(status == 1) {//上报详情 memcpy(nowCIP, sutProductPara.ManagerIP, 4); nowCPort = sutProductPara.ManagerPort; if(GetStringIP2Bytes(nowPIP, sutProductPara.PIP)) SlwTrace(INF, "IP Para err1",1); nowPPort = 0xffff; if(GetStringIP2Bytes(nowGIP, sutProductPara.GIP)) SlwTrace(INF, "IP Para err2",1); nowGPort = sutProductPara.GpsPort; }else if(status == 2) {//上报结果不需要值 memset(nowCIP, 0, 4); memset(nowPIP, 0, 4); memset(nowGIP, 0, 4); nowCPort=0;nowPPort=0;nowGPort=0; }else{ } for(j=0;j<4;j++) p[i++] = nowCIP[j]; ds.Data.usData = nowCPort; p[i++] = ds.Data.ucData.b2; p[i++] = ds.Data.ucData.b1; for(j=0;j<4;j++) p[i++] = nowPIP[j]; ds.Data.usData = nowPPort; p[i++] = ds.Data.ucData.b2; p[i++] = ds.Data.ucData.b1; for(j=0;j<4;j++) p[i++] = nowGIP[j]; ds.Data.usData = nowGPort; p[i++] = ds.Data.ucData.b2; p[i++] = ds.Data.ucData.b1; } return i; } /********************************************************************************************************************** Type:1字节,决定Data的内容 length:2字节 从data到checkSum的字节数 Data[n]:根据实际数据 checkSum:1字节 从头开始按字节累加到data为止每次累加的进位去掉 ***********************************************************************************************************************/ unsigned short SendTcpSeverPack(unsigned char *Buffer,unsigned char CMD,unsigned short Datalen) { unsigned short j,i=0; unsigned char *pBuf=Buffer,sum; SUTDS ds; pBuf[0]=CMD; ds.Data.usData = Datalen+1; pBuf[1]=ds.Data.ucData.b2; pBuf[2]=ds.Data.ucData.b1; sum=0; for(j=0;j<1+2+Datalen;j++) sum += pBuf[j]; pBuf[3+Datalen]=sum; return (3+Datalen+1); } /********************************************************************************************************************** 格式:AT+ICCID +GETICCID:0x89860315402521836592 +SCID:98680036904030021872 ***********************************************************************************************************************/ int ModemGetCCID(void) { int t; int i,len,ver; char buf[80],bufTemp[3]; SUT_MODEM_AT_MSG *pMsg=&sutAtmPro; ver=0; for(i=0;i<5;i++){ t=100; ModemSendAT("AT+ICCID\r\n"); while(t--) {//^SCID: 89860316452001903429 if((pMsg->MsgLen = MsgQueueAccept(pMsg->MsgData, sizeof(pMsg->MsgData)))) { if(0==ModemStrCmp((char *)pMsg->MsgData,"^SCID:")) { memcpy(CCID, &pMsg->MsgData[7], sizeof(CCID)); CCID[20]=0; snprintf(buf, sizeof(buf), "[09]ICCID:%s[", CCID); bufTemp[0] = CCID[4]; bufTemp[1] = CCID[5]; bufTemp[2] = 0; switch(atoi(bufTemp)) { case 1: case 9:thisYunYingShang = CHINA_UNICOM; strcat(buf, "CHINA_UNICOM]"); break; case 0: case 2: case 7:thisYunYingShang = CHINA_MOBILE; strcat(buf, "CHINA_MOBILE]"); break; case 3: case 6: case 8: case 11:thisYunYingShang = CHINA_TELECOM; strcat(buf, "CHINA_TELECOM]"); break; default:strcat(buf, "UNKNOW-ICCID]"); break; } SlwTrace(INF, buf,1); return 1; } }else os_dly_wait(1); } } SlwTrace(INF, "[09]Get CCID failed",1); return 0; } /********************************************************************************************************************** 开机发送CCID (unsigned char *Buffer,unsigned long PSN,unsigned char CMD,unsigned long PASS,unsigned char *PName,unsigned short CurVer,unsigned char *CCID); ***********************************************************************************************************************/ void SendHgsData(void) { unsigned short len; unsigned char HgsBuf[60]; HigosSendFlag +=1; len=SendTcpDataFill(&HgsBuf[3],0x12,0,0);//先填充数据段,后两参数没意义 len=SendTcpSeverPack(HgsBuf,0x12,len);//再按协议格式打包 M9507CSendTcpData(GPS_DATA_SOCKET, HgsBuf, len); PrintTcpData(HgsBuf,len); } /********************************************************************************************************************** 收到服务器返回后处理 ***********************************************************************************************************************/ void HigosInit(void) { #if(USE_HIGOS_PRO==1) tcpControl = 0;//先处理ManaTCP HigosSendFlag=0; HgsConnetCnt=0; HgsProcessResult=0; HgsConnetStatus=0; #else tcpControl=1; #endif } void HigosStartCnt(unsigned char long_short) { PocStartCnt=1;//打开计时 PocTimeoutCnt=0;//从0开始计数 if(long_short == 1)//long newCOUNT=POC_TIME_OUT_1; else newCOUNT=POC_TIME_OUT_2; HgsProcessResult=0; SlwTrace(INF, "\r\nStart cnt",1); } void HigosStopCnt(void) { #if(USE_HIGOS_PRO==1) PocStartCnt=0;//禁止计时 PocTimeoutCnt=0;//从0开始计数 SlwTrace(INF, "\r\nStop cnt",1); #endif } /************************************************ 每10ms处理一次 AT+ZIPSETUP=0,higos.f3322.net,12001 +ZDNSGETIP:125.118.61.34 **************************************************/ #define TCP_RETRY_NUM 3 void HigosTick(void) { static unsigned char sucSecCt=0; static unsigned char sucSteep=0; static unsigned char sucTcpCnt=TCP_RETRY_NUM; unsigned char ret; char buf[50]; static STATUE psStatus = INVALID; #if(USE_HIGOS_PRO==0) return; #endif if(psStatus != sutGpsStatus.PPPStatus) { if(psStatus != OPEN && sutGpsStatus.PPPStatus == OPEN) {//PPP从没打开变成打开了,此时开始认为所到网络条件都具备了 if(sutPocStatus.Logined == 0) HigosStartCnt(1); } psStatus = sutGpsStatus.PPPStatus; } //===========以下控制每1.5秒执行一次============ if(++sucSecCt>99)sucSecCt=0; else return; if(sutGpsStatus.PPPStatus != OPEN) return; /////////////判定计时///////////////// if(PocStartCnt) { if(++PocTimeoutCnt >= newCOUNT) { SlwTrace(INF, "POC Login timeout",1); HigosStopCnt(); //开启管理服务器登陆 //先断开GPS吧 snprintf(buf, sizeof(buf), "AT+TCPCLOSE=%d\r\n", GPS_DATA_SOCKET); ModemSendAT(buf); //1分钟后继续尝试 if(HgsProcessResult==1) HigosStartCnt(0);//因连接TCP失败而导致未登陆管理服务器,短时间后重试 HigosInit(); } } if(tcpControl != 0) return; //---以下控制--- if(++sucSteep>3)sucSteep=0; //---- if(sucSteep==0) { if(++sucTcpCnt >= TCP_RETRY_NUM) { sucTcpCnt=0; if(HgsConnetCnt<3 && HgsConnetStatus==0) { snprintf(buf, sizeof(buf),"AT+TCPOPEN=%d,%d.%d.%d.%d:%d\r\n", GPS_DATA_SOCKET, sutProductPara.ManagerIP[0], sutProductPara.ManagerIP[1], sutProductPara.ManagerIP[2], sutProductPara.ManagerIP[3], sutProductPara.ManagerPort); ModemSendAT(buf); ++HgsConnetCnt; SlwTrace(INF, buf,0); } } }else if(1==sucSteep) { if(HgsConnetStatus)//已连接成功 SendHgsData(); }else if(2==sucSteep) { if(HigosSendFlag >=3 || //已发了三次了 HgsConnetCnt >= 3 || //三次连接失败了 HgsProcessResult == 2)//处理完成 { if(HgsProcessResult != 2) HgsProcessResult=1; snprintf(buf, sizeof(buf),"AT+TCPCLOSE=%d\r\n", GPS_DATA_SOCKET); ModemSendAT(buf); os_dly_wait(1); tcpControl=1;//ManaTCP完毕,允许执行GPS处理 sutConfig.g_ubConfigFlag=0; sutConfig.g_usOptionCnt=0; HgsConnetStatus=0; } } } void Hgs_Data_RecvHandle(char *data, unsigned short len) { unsigned short i; unsigned char sum,type,zerocnt; unsigned short thisLen; unsigned char newIP[4]; char buf[60]; char buf1[120]; char *p=data; unsigned char status; unsigned char Right,AckStatus; unsigned char newCip[4],newPip[4],newGip[4]; unsigned short newCPort,newPPort,newGPort; SUTDS ds; unsigned char zeroNum; char needSave=0; status=0; if(tcpControl != 0 && tcpControl != 2) return; //check load data type = *p++; thisLen = *p++; thisLen <<= 8; thisLen &= 0xff00; thisLen |= *p++; if((1+2+thisLen) != len) { snprintf(buf1, sizeof(buf1), "Len err"); status=1; goto EXIT; } sum = 0; for(i=0;i= 2) { SlwTrace(INF, "err_IP",1); status=5; goto EXIT; } snprintf(buf, sizeof(buf), "%d.%d.%d.%d", newIP[0],newIP[1],newIP[2],newIP[3]); if(strcmp(sutProductPara.PIP,buf) != 0) {//有新交换IP IWDG_ReloadCounter(); //1、保存起来 snprintf(sutProductPara.PIP,sizeof(sutProductPara.PIP), "%d.%d.%d.%d", newIP[0],newIP[1],newIP[2],newIP[3]); SaveProductParaToFlash("HGS_IP"); //2、写到模块去 snprintf(buf, sizeof(buf),"id=%lu;ip=%s;pwd=%s;",sutProductPara.PSN,sutProductPara.PIP,sutProductPara.HARDID); AscStrToHexStr(buf,buf1); ModemSendAT("AT+POC=010000"); ModemSendAT(buf1); ModemSendAT("\r\n"); //reset whole system SlwTrace(INF, "Reboot...",1); os_dly_wait(100); while(1); }else { snprintf(buf1, sizeof(buf1),"Same_IP"); status=0; goto EXIT; } EXIT: SlwTrace(INF, buf1,1); //成功拿到一包数据后,则认为完成一次处理 if(sutPocStatus.Logined==0) HigosStartCnt(1);//如果未登陆要接着计数 HgsProcessResult=2; }else if(type == 0x19) { #if(USE_CONFIG_FUN==1) AckStatus = *p++; sutConfig.g_ucConfigSerAckStatus=AckStatus; switch(AckStatus) { case 1://响应成功,可处理数据 memcpy(newCip, p, 4);p+=4; ds.Data.ucData.b2 = *p++; ds.Data.ucData.b1 = *p++; newCPort=ds.Data.usData; memcpy(newPip, p, 4);p+=4; ds.Data.ucData.b2 = *p++; ds.Data.ucData.b1 = *p++; newPPort=ds.Data.usData; memcpy(newGip, p, 4);p+=4; ds.Data.ucData.b2 = *p++; ds.Data.ucData.b1 = *p++; newGPort=ds.Data.usData; snprintf(buf1, sizeof(buf1), "\r\nCIP:%d.%d.%d.%d,%d PIP:%d.%d.%d.%d,%d GIP:%d.%d.%d.%d,%d", newCip[0],newCip[1],newCip[2],newCip[3],newCPort, newPip[0],newPip[1],newPip[2],newPip[3],newPPort, newGip[0],newGip[1],newGip[2],newGip[3],newGPort); SlwTrace(INF, buf1, 1); //检测CIP是否为全0 IP zeroNum=0; for(i=0;i<4;i++) if(newCip[i] == 0) zeroNum++; if(zeroNum <=1 && newCPort)//只有1个或没有0,认为IP有效 { if( 0!=memcmp(newCip, sutProductPara.ManagerIP, 4) || newCPort != sutProductPara.ManagerPort) { needSave=1; memcpy(sutProductPara.ManagerIP, newCip, 4); sutProductPara.ManagerPort = newCPort; SlwTrace(INF, "CIP Update",1); }else SlwTrace(INF, "CIP No change",1); } //检测PIP是否为全0 IP zeroNum=0; for(i=0;i<4;i++) if(newPip[i] == 0) zeroNum++; if(zeroNum <=1)//只有1个或没有0,认为IP有效 { snprintf(buf, sizeof(buf), "%d.%d.%d.%d",newPip[0],newPip[1],newPip[2],newPip[3]); if(0!=strcmp(buf, sutProductPara.PIP)) { needSave=2; strcpy(sutProductPara.PIP, buf); SlwTrace(INF, "PIP Update",1); }else SlwTrace(INF, "PIP No change",1); } //检测GIP是否为全0 IP zeroNum=0; for(i=0;i<4;i++) if(newGip[i] == 0) zeroNum++; if(zeroNum <=1 && newGPort)//只有1个或没有0,认为IP有效 { snprintf(buf, sizeof(buf), "%d.%d.%d.%d",newGip[0],newGip[1],newGip[2],newGip[3]); if(0!=strcmp(buf, sutProductPara.GIP) || newGPort != sutProductPara.GpsPort) { needSave=3; strcpy(sutProductPara.GIP, buf); sutProductPara.GpsPort = newGPort; SlwTrace(INF, "GIP Update",1); }else SlwTrace(INF, "GIP No change",1); } if(needSave !=0) SaveProductParaToFlash("NCONF"); sutConfig.g_ucConfigStatus=2;//上报更新结果 sutConfig.g_ucConfigValue=1;//完成配置 sutConfig.g_ubConfigFinished=1; break; case 2://服务器无此PSN SlwTrace(INF, "\r\nNo PSN in server",1); break; case 3://CCID不匹配 SlwTrace(INF, "\r\nCCID no fitted",1); break; case 4://新旧IP一致 SlwTrace(INF, "\r\nAll para no change",1); break; default://保留 break; } #endif } } #if(USE_CONFIG_FUN==1) void SerConfigSend(void) { unsigned short len; unsigned char HgsBuf[80]; len=SendTcpDataFill(&HgsBuf[3],0x19,sutConfig.g_ucConfigStatus,sutConfig.g_ucConfigValue);//先填充数据段,后两参数没意义 len=SendTcpSeverPack(HgsBuf,0x19,len);//再按协议格式打包 M9507CSendTcpData(CONFIG_SER_SOCKET, HgsBuf, len); PrintTcpData(HgsBuf,len); } void ConfigCtrHandle(void) { static unsigned char Cnt,thisStatus=0,timeout=0; char buf[50],needAt; if(sutConfig.g_ubConfigFlag==0) return; // if(sutConfig.g_ubConfigFinished) return; if(++Cnt < 99) return; if(timeout++ > 60) { CONFIG_EXIT: ////////////////////////////////////////// GuiClearRect(0,65,LCD_WIDTH-1,81); GuiShowBmp(30,34,"logo.bmp"); if(sutGpsStatus.PPPStatus != OPEN) { SlwTrace(INF, "PPP Failed",1); //sprintf(buf,"B2A6BAC5CAA7B0DC"); GuiShowStr(42, 55, "拨号失败!",1); }else if(sutConfig.g_ubConfigTcpStatus==0) { SlwTrace(INF, "Tcp Failed",1); //sprintf(buf,"C1ACBDD3CAA7B0DC"); GuiShowStr(42, 55, "连接失败!",1); }else if(sutConfig.g_ucTcpSendDateTime >=3) { SlwTrace(INF, "Tcp no fit data",1); //sprintf(buf,"CFECD3A6CEDED0A7"); GuiShowStr(42, 55, "响应无效!",1); }else{ SlwTrace(INF, "Access ok",1); //sprintf(buf,"B7C3CECACDEAB3C9"); GuiShowStr(42, 55, "访问完成!",1); } //strcat(buf, "2CCDCBB3F6C5E4D6C3"); GuiShowStr(42, 80, "退出配置!",1); //MeSpeak(ENCODE_GBK, buf, 1); SlwTrace(INF, "Quit config",1); ////////////////////////////////////////// if(sutConfig.g_ubConfigTcpStatus) { os_dly_wait(100); snprintf(buf, sizeof(buf), "AT+TCPCLOSE=%d\r\n", CONFIG_SER_SOCKET); ModemSendAT(buf); } memset((unsigned char *)&sutConfig, 0, sizeof(CONFIG_SER_DEF)); timeout=0; sutConfig.g_ubConfigFlag=0; return; } Cnt=0; needAt=0; if(++thisStatus > 2) thisStatus=0; switch(thisStatus) { case 0://检测ppp if(sutGpsStatus.PPPStatus == OPEN) snprintf(buf, sizeof(buf), "AT+TCPSTATUS=%d\r\n", CONFIG_SER_SOCKET); else snprintf(buf, sizeof(buf), "AT+POC_PPP\r\n"); needAt=1; break; case 1://连接TCP if(sutGpsStatus.PPPStatus != OPEN) break; if(sutConfig.g_ucTcpRetryNum++ >= CONFIG_TCP_RETRY_CNT) { sutConfig.g_ucTcpRetryNum =0; if(sutConfig.g_ubConfigTcpStatus == 0)//未连接成功 {//发起连接 if(sutConfig.g_ucTcpConnectTime < CONFIG_TCP_MAX_CONNECT) {//连接次数未超标 snprintf(buf, sizeof(buf), "AT+TCPOPEN=%d,%d.%d.%d.%d:%d\r\n", CONFIG_SER_SOCKET, sutProductPara.ConfigSerIP[0], sutProductPara.ConfigSerIP[1], sutProductPara.ConfigSerIP[2], sutProductPara.ConfigSerIP[3], sutProductPara.ConfigSerPort); needAt=1; sutConfig.g_ucTcpConnectTime++; }else goto CONFIG_EXIT; } } break; case 2://发送数据 if(sutGpsStatus.PPPStatus != OPEN) break; if(sutConfig.g_ubConfigTcpStatus==0) break; if(sutConfig.g_ucTcpSendDateTime++ < 3 || sutConfig.g_ubConfigFinished)//收到服务器应答并处理完成后,应答结果,完成交互 { SerConfigSend(); }else goto CONFIG_EXIT; break; } if(needAt) { SlwTrace(INF, buf,0); ModemSendAT(buf); } if(sutConfig.g_ubConfigFinished) goto CONFIG_EXIT; } #endif #define PRINTF_MAX_LEN 70 void PrintTcpData(unsigned char *tcpData, unsigned short len) { char buf[PRINTF_MAX_LEN*2+10]; char temp[2]; unsigned char thisLen,i; thisLen = PRINTF_MAX_LEN; if(len > thisLen) len = thisLen; snprintf(buf, sizeof(buf), "TcpS[%d]:",len); #if 0 for(i=0;i