📄 func.cpp
字号:
#include "stdafx.h"
#include <windows.h>
#include <process.h>
#include <time.h>
#include <sys/timeb.h>
#include <stdio.h>
#include <winsock2.h>
#include <direct.h>
#include <stdarg.h>
#include <wchar.h>
#include <STDLIB.H>
#include "gw.h"
#include "md5.h"
#include "func.h"
#include "sock.h"
CArg arg;
DWORD WINAPI MOThread(LPVOID pp)
{
char buffer[SMPPMAXLENGTH];
char strSQL[512];
fd_set rfds,afds;
timeval tv;
DWORD dwRet=0;
char tmp[50];
char msgbuffer[323];
CMSG msg;
tv.tv_sec=0;
tv.tv_usec=5;
while(arg.isActive==0)SleepEx(50,1);
AddLog("begin to get mo.\n");
FD_ZERO(&afds);
FD_SET(arg.s,&afds);
while(1)
{
if(arg.dwStopFlag)return 0;
memcpy(&rfds,&afds,sizeof(afds));
dwRet=select(FD_SETSIZE,&rfds,(fd_set*)0,(fd_set*)0,
(struct timeval*)&tv);
if(dwRet==SOCKET_ERROR)//network error
{
AddLog("select error for %d\n",GetLastError());
SleepEx(20*1000,1);
return ExitFromNetClose;
}
else if(dwRet==0)
{
if(arg.dwStopFlag)return 0;
arg.dwRecv++;
continue;//time expired
}
int i;
if(i=ioctlsocket(arg.s,FIONREAD ,&dwRet))
{
AddLog("error for %d\n",i);
return ExitFromNetClose;
}else if(dwRet==0)
{
AddLog("socket closed by server gracefully\n");
return ExitFromNetClose;
}
ZeroMemory(buffer,SMPPMAXLENGTH);
if(i=RecvBuffer(buffer))return i;
arg.dwRecv++;
//now , the package should be processed.
ZeroMemory(&msg,sizeof(CMSG));
msg.dwCommand=(GetNByte(buffer+4,4)+0x80000000);
msg.dwSequence=GetNByte(buffer+8,4);
msg.dwResult=0;
try
{
switch(GetNByte(buffer+4,4))
{
case nCMPP_CONNECT_RESP:
if(buffer[12])
{
if(arg.isDebug)
AddLog("bind to server error for: %d.\n",
(BYTE)buffer[12]);
arg.isActive=0;
return ExitFromNetClose;
}
else
{
if(arg.isDebug)AddLog("bind to server ok.\n");
arg.isActive=1;
}
break;
case nCMPP_TERMINATE_RESP:
closesocket(arg.s);
arg.isActive=0;
return 0;
break;
case nCMPP_SUBMIT_RESP:
dwRet=(BYTE)buffer[20];
SetWindow(-1);
wtos(msg.szContent,GetNByte(buffer+12,4),GetNByte(buffer+12+4,4));
if(dwRet)
{
sprintf(strSQL,"exec sp_send_mt_error %d,%d,%d",
arg.iChannelNum,GetNByte(buffer+8,4),dwRet);
if(arg.isDebug)AddLog("error: %s\n",strSQL);
arg.pCnnGSM->Errors->Clear();
arg.pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
}else
{
AddResp("Resp",0,"%d,%d,%.20s\n",
arg.iChannelNum,GetNByte(buffer+8,4),msg.szContent);
sprintf(strSQL,"exec sp_send_mt_resp %d,%d,'%.20s'",
arg.iChannelNum,GetNByte(buffer+8,4),msg.szContent);
if(arg.isDebug)AddLog("resp: %s\n",strSQL);
arg.pCnnGSM->Errors->Clear();
arg.pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
}
break;
case nCMPP_QUERY_RESP:
break;
case nCMPP_CANCEL_RESP:
break;
case nCMPP_ACTIVE_TEST:
AddLog("get active test here\n");
//set command
PutNByte(buffer+4,4,nCMPP_ACTIVE_TEST_RESP);
buffer[12]=0;
PutNByte(buffer,4,12+1);
if(i=SendBuffer(buffer,13))
return i;
arg.isActive=1;
break;
case nCMPP_ACTIVE_TEST_RESP:
if(arg.isDebug)AddLog("get cmpp active test resp.\n");
arg.isActive=1;
break;
case nCMPP_DELIVER:
if(buffer[75]==0)//是否是状态报告
{//deliver process
wtos(tmp,GetNByte(buffer+12,4),GetNByte(buffer+12+4,4));
for(i=0;i<(BYTE)buffer[76];i++)//状态报告标志后面就是1字节的长度标志
sprintf(msgbuffer+i*2,"%.2x",//长度标志后面就是信息体
(BYTE)(buffer[77+i]));
sprintf(strSQL,"exec sp_insert_mo '%s','%.21s',0x%s,%d,'%.21s',%d",
tmp,//ismg_id
buffer+54,//src_termid 位于msg_format之后,长度21字节
msgbuffer,//msg
buffer[53],//msg_format 位于第54字节
buffer+20,//dst_termid 前面有20字节,长度为21字节
arg.iChannelNum//channel number.
);
AddResp("MO",0,"%s,%.21s,0x%s,%d,%.21s,%d\n",
tmp,//ismg_id
buffer+54,//src_termid 位于msg_format之后,长度32字节
msgbuffer,//msg
buffer[53],//msg_format 位于第54字节
buffer+20,//dst_termid 前面有20字节,长度为21字节
arg.iChannelNum//channel number.
);
}
else
{//state report process
//应该取之前SUBMIT是回执里的ISMGID,这时在信息体开始的8字节内
wtos(tmp,GetNByte(buffer+77,4),GetNByte(buffer+77+4,4));
sprintf(strSQL,"EXEC SP_STATE_REPORT %d,'%s','%.21s','%.7s','%.10s'",
arg.iChannelNum,
tmp,//ismg_id
buffer+77+8+7+20,//dst_termid,在状态报告+20字节之后,长度为32字节
buffer+77+8,//state在8字节ISMGID之后,长度7字节
buffer+12+8+21//service id
);
AddResp("Status",0,"%d,%s,%.21s,%.7s,%.10s\n",
arg.iChannelNum,
tmp,//ismg_id
buffer+77+8+7+20,//dst_termid,在状态报告+20字节之后,长度为32字节
buffer+77+8,//state在8字节ISMGID之后,长度7字节
buffer+12+8+21//service id
);
}
if(arg.isDebug)AddLog("%s\n",strSQL);
arg.pCnnGSM->Errors->Clear();
arg.pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
PutNByte(buffer+4,4,0x80000000+nCMPP_DELIVER);
buffer[20]=0;
PutNByte(buffer,4,21);
if(i=SendBuffer(buffer,21))return i;
break;
}//end of swtich
//end of processing a package.
}//try
catch (_com_error &e)
{
AddLog("Process msg error.\n<%s>\n",strSQL);
AddLog("Description = '%s'\n", (char*) e.Description());
return 0;
}
//end of to process the msg package.
}//end of while 1
return 0;
}
GW_API DWORD BeginGW(LPVOID pp)
{
WSAData wsaData;
DWORD dwRet;
HANDLE h[3];
DWORD dwRecv,dwSend;
char szService[10];
CMSG tm;
int index;
WSAStartup(0x202,&wsaData);
tm.dwCommand=nCMPP_ACTIVE_TEST;
if(!GetArg(&arg))
{
SleepEx(1000*10,1);
return 1;
}
if(arg.isDebug)AddLog("GW.dll is beginning.\n\n");
sprintf(szService,"%d",arg.SMSCPORT);
index=0;
while(1)
{
arg.s=connectTCP(arg.SMSCIP,szService);
if(arg.s==INVALID_SOCKET)
{
SleepEx(arg.iSelectInterval,1);
index++;
if(index<arg.nMaxReconnect)continue;
return ExitFromNetClose;
}
tm.dwCommand=nCMPP_CONNECT;
tm.dwSequence=0;
if(dwRet=SendData(&tm,arg.pCnnGSM))
{
if(dwRet==ExitFromNetClose)return ExitFromNetClose;
tm.dwCommand=nCMPP_TERMINATE;
dwRet=SendData(&tm,arg.pCnnGSM);
if(dwRet==ExitFromNetClose)return ExitFromNetClose;
tm.dwCommand=nCMPP_CONNECT;
dwRet=SendData(&tm,arg.pCnnGSM);
SleepEx(arg.iSelectInterval,1);
if(dwRet)return ExitFromNetClose;
}else break;
}
try
{
::CoInitialize(NULL);
TESTHR(arg.pCnnGSM.CreateInstance(__uuidof(Connection)));
arg.pCnnGSM->ConnectionTimeout = 120;
arg.pCnnGSM->CommandTimeout=300;
TESTHR(arg.pCnnGSM->Open(arg.strCnn,"","",adConnectUnspecified));
arg.pCnnGSM->Errors->Clear();
}//try
catch (_com_error &e)
{
AddLog("db connection open error.\n");
AddLog("Description = '%s'\n", (char*) e.Description());
if(arg.pCnnGSM->GetState())arg.pCnnGSM->Close();
::CoUninitialize();
SleepEx(arg.iSelectInterval,1);
return 0;
}
dwRet=0;
ResetEvent(arg.hGW);
h[0]=(HANDLE)_beginthreadex(NULL,0,(unsigned int(__stdcall*)(void*))MTThread,0,0,0);
h[1]=(HANDLE)_beginthreadex(NULL,0,(unsigned int(__stdcall*)(void*))MOThread,0,0,0);
h[2]=arg.hGW;
dwRecv=dwSend=0;
tm.dwCommand=nCMPP_ACTIVE_TEST;
while(1)
{
dwRet=WaitForMultipleObjects(3,h,FALSE,20*1000);
switch(dwRet)
{
case WAIT_FAILED: //error:
AddLog("WSAWaitFor Error\n");
ExitProcess(-1);
break;
case WAIT_TIMEOUT:
#if 1
if(SendOnlyData(&tm))
{
TerminateThread(h[0],0);
TerminateThread(h[1],0);
goto RET_002;
}
#endif
if(arg.isMO==1)
{
if(dwRecv/3>arg.dwRecv+1)
{
AddLog("mo no data, thread will rerun.\n");
dwRecv=arg.dwRecv;
dwSend=arg.dwSend;
TerminateThread(h[0],0);
TerminateThread(h[1],0);
goto RET_002;
}
}
else if((dwRecv/3>arg.dwRecv+1)||dwSend>arg.dwSend+50)
{
if(arg.isDebug>1)
AddLog("No data, thread will rerun.\n");
dwRecv=arg.dwRecv;
dwSend=arg.dwSend;
//TerminateThread(h[0],0);
//TerminateThread(h[1],0);
goto RET_002;
}
dwRecv++;dwSend++;
if(dwRecv<arg.dwRecv)dwRecv=arg.dwRecv;
if(dwSend<arg.dwSend)dwSend=arg.dwSend;
break;
case WAIT_OBJECT_0: //mt_thread exit here
GetExitCodeThread(h[0],&dwRet);
if(arg.isDebug)AddLog("MTThread exit for %d.\n",dwRet);
if(dwRet==ExitFromNetClose||dwRet==0)
{
//TerminateThread(h[1],0);
goto RET_002;
}
CloseHandle(h[0]);
h[0]=(HANDLE)_beginthreadex(NULL,0,
(unsigned int(__stdcall*)(void*))MTThread,0,0,0);
if(h[0]==NULL)
{
//TerminateThread(h[1],0);
goto RET_002;
}
break;
case WAIT_OBJECT_0 +1://mo thread exit here.
GetExitCodeThread(h[1],&dwRet);
if(arg.isDebug)AddLog("MOThread exit for %d.\n",dwRet);
if(dwRet==ExitFromNetClose||dwRet==0)
{
TerminateThread(h[0],0);
return 0;
goto RET_002;
}
CloseHandle(h[1]);
h[1]=(HANDLE)_beginthreadex(NULL,0,
(unsigned int(__stdcall*)(void*))MOThread,
0,0,0);
if(h[1]==NULL)
{
//TerminateThread(h[0],0);
goto RET_002;
}
break;
case WAIT_OBJECT_0+2: //EventForExit
AddLog("Get msg to stop GW.\n");
//TerminateThread(h[0],0);
//TerminateThread(h[1],0);
goto RET_002;
break;
}//switch(dwRet)
}//end fo while (1)
RET_002:
AddLog("clean up\n");
arg.dwStopFlag=0x7e;
SleepEx(1000,1);
WSACleanup();
if(arg.pCnnGSM->GetState())arg.pCnnGSM->Close();
#if ONESECTION1
DeleteCriticalSection(&(arg.syc1));
#endif
#if ONESECTION2
DeleteCriticalSection(&(arg.syc2));
#endif
#if ONESECTION3
DeleteCriticalSection(&(arg.syc3));
#endif
::CoUninitialize();
AddLog("exit BeginGW\n");
return 0;
}
void PutByteString(char* dest,
char* source,
int length)
{
int i=0;
if(source==NULL)return;
for(i=0;i<length;i++)
dest[i]=source[i];
}
void PutNByte(char* buffer,BYTE b,DWORD in)
{
int i;
if(b>4)b=4;
for(i=0;i<b;i++)
{
*(buffer+b-1-i)=char(in&0xFF);
in>>=8;
}
}
DWORD GetTime()
{
int ret=0;
time_t tt;
struct tm *now;
char buf[20];
time( &tt);
now = localtime( &tt);
sprintf( buf, "%02d%02d%02d%02d%02d",
now->tm_mon + 1,
now->tm_mday,
now->tm_hour,
now->tm_min,
now->tm_sec);
ret=atoi(buf);
return ret;
}
DWORD GetTimeMillSec()
{
int ret=0;
struct _timeb timebuffer;
_ftime(&timebuffer);
ret=timebuffer.millitm+timebuffer.time%3600*1000;
return ret;
}
void GetTime(char* buffer,int period)
{
char date[20],time[20];
int d,h,m;
int year,month;
_strdate(date);
_strtime(time);
m=atoi(time+3)+period;
h=m/60+atoi(time);m%=60;
d=h/24+atoi(date+3);h%=24;
month=atoi(date);
year=atoi(date+6);
switch(month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if(d>31){month+=d/31;d%=31;}
break;
case 4:
case 6:
case 9:
case 11:
if(d>30){month+=d/30;d%=30;}
break;
case 2:
if((year%4==0&&year%100>0)||year%400==0){
if(d>29){month+=d/29;d%=29;}
}else
{
if(d>28){month+=d/28;d%=28;}
}
}
if(month>12){year+=month/12;month%=12;}
sprintf(buffer,"%.2d%.2d%.2d%.2d%.2d%.2d",
year,month,d,h,m,atoi(time+6));
strcpy(buffer+12,"032+");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -