📄 func.cpp
字号:
DWORD GetNByte(char* buffer,BYTE b)
{
int i;
DWORD rt=0;
if(b>4)b=4;
for(i=0;i<b;i++)
rt=rt*256+*(unsigned char*)(buffer+i);
return rt;
}
long Jstrncpy(char* dest,
const char* source,
long size)
{
UINT i=0;
ZeroMemory(dest,size);
if(source==NULL)return 0;
if((long)strlen(source)>=size)
strncpy(dest,source,size);
else
strcpy(dest,source);
return (long)strlen(dest);
}
int SendBuffer(char* buffer,int buf_len)
{
int i,j;
i=j=0;
#if ONESECTION1
EnterCriticalSection(&(arg.syc1));
#endif
while(i<buf_len)
{
j=send(arg.s,buffer+i,buf_len-i,0);
if(j<1)
{
AddLog("send socket error for: %d\n",WSAGetLastError());
if(i>0)AddBinLog(buffer,i,1);
#if ONESECTION1
LeaveCriticalSection(&(arg.syc1));
#endif
return ExitFromNetClose;
}
i+=j;
}
#if ONESECTION1
LeaveCriticalSection(&(arg.syc1));
#endif
AddBinLog(buffer,i,0);
return 0;
}
int RecvBuffer(char* buffer,int len)
{
int i,j;
i=j=0;
#if ONESECTION2
EnterCriticalSection(&(arg.syc2));
#endif
while(i<len)
{
j=recv(arg.s,buffer+i,len-i,0);
if(j<1)
{
AddLog("recv socket error3 for: %d-%d\n",j,WSAGetLastError());
if(i>0)AddBinLog(buffer,i,1);
#if ONESECTION2
LeaveCriticalSection(&(arg.syc2));
#endif
return ExitFromNetClose;
}
i+=j;
}
#if ONESECTION2
LeaveCriticalSection(&(arg.syc2));
#endif
return 0;
}
int RecvBuffer(char* buffer)
{
int i,j;
i=j=0;
#if ONESECTION2
EnterCriticalSection(&(arg.syc2));
#endif
while(i<4)
{
j=recv(arg.s,buffer+i,4-i,0);
if(j<1)
{
AddLog("recv socket error1 for: %d-%d\n",j,WSAGetLastError());
if(i>0)AddBinLog(buffer,i,1);
#if ONESECTION2
LeaveCriticalSection(&(arg.syc2));
#endif
return ExitFromNetClose;
}
i+=j;
}
while(i<(int)GetNByte(buffer,4))
{
j=recv(arg.s,buffer+i,GetNByte(buffer,4)-i,0);
if(j<1)
{
AddLog("recv socket error2 for: %d-%d\n",j,WSAGetLastError());
if(i>0)AddBinLog(buffer,i,1);
#if ONESECTION2
LeaveCriticalSection(&(arg.syc2));
#endif
return ExitFromNetClose;
}
i+=j;
}
buffer[i]=0;
AddBinLog(buffer,i,1);
#if ONESECTION2
LeaveCriticalSection(&(arg.syc2));
#endif
return 0;
}
DWORD SendData(CMSG *msg,_ConnectionPtr pCnnGSM)
{
int i;
fd_set rfds,afds;
char strSQL[512];
char buffer[SMPPMAXLENGTH];
timeval tv;
DWORD dwRet;
char tmp[50];
char msgbuffer[323];
MD5 ctx;
char authsrc[50], *pos;
DWORD ts;
arg.dwSequence2++;
memset(buffer,0,SMPPMAXLENGTH);
i=0;
i+=4;//keep space for package length.
PutNByte(buffer+i,4,msg->dwCommand);
i+=4;
if(msg->dwCommand==nCMPP_SUBMIT)arg.dwSequence=msg->dwSequence;
else arg.dwSequence=arg.dwSequence2;
PutNByte(buffer+i,4,arg.dwSequence);
i+=4;//head length=12 bytes.
switch(msg->dwCommand)
{
case nCMPP_CONNECT:// over
ts=GetTime();//通过截取数据包发现,AIAPI里面取值为0,华为网关取值为GETTIME()
memcpy(buffer+i,arg.SPID,6);i+=6;//spid looks like 901001
// 计算单向HASH函数的值
memset(authsrc,0,sizeof( authsrc));
strcpy(authsrc,arg.SPID);
pos = authsrc + 6 + 9;//9 bytes 0
strcpy((char *)pos, arg.Password);
pos += strlen(arg.Password);
sprintf(pos, "%.10d",ts);
pos+=10;
ctx.update( (unsigned char *)authsrc, (int)(pos - authsrc) );
ctx.finalize();
ctx.raw_digest((unsigned char*)buffer+i);i+=16;//16 digist
buffer[i]=arg.isMO;//send mt & recv mo
i++;
PutNByte(buffer+i,4,ts);i+=4;//time stamp looks like:MMDDHHMMSS,1001100101
break;
case nCMPP_ACTIVE_TEST:
break;
}
PutNByte(buffer,4,i);
if(SendBuffer(buffer,i))return ExitFromNetClose;
tv.tv_sec=5;
tv.tv_usec=0;
FD_ZERO(&afds);
FD_SET(arg.s,&afds);
while(1)
{
memcpy(&rfds,&afds,sizeof(afds));
i=select(FD_SETSIZE,&rfds,(fd_set*)0,(fd_set*)0,
(struct timeval*)&tv);
if(i==SOCKET_ERROR)//network error
{
AddLog("select in senddata error for %d\n",GetLastError());
return ExitFromNetClose;
}
else if(i==0)
{
return -1;//time expired
}
ZeroMemory(buffer,SMPPMAXLENGTH);
if(RecvBuffer(buffer))return ExitFromNetClose;
arg.dwRecv++;
switch(dwRet=GetNByte(buffer+4,4))
{
case nCMPP_CONNECT_RESP:
if(buffer[12]==0)
{
arg.isActive=1;
AddLog("bind to server ok\n");
return 0;
}
else AddLog("bind to server error for: %d.\n",(BYTE)buffer[12]);
arg.isActive=0;
return (BYTE)buffer[12];
break;
case nCMPP_TERMINATE_RESP:
closesocket(arg.s);
arg.isActive=0;
return 0;
break;
case nCMPP_SUBMIT_RESP:
wtos(msg->szContent,GetNByte(buffer+12,4),GetNByte(buffer+12+4,4));
dwRet=GetNByte(buffer+20,4);
if(GetNByte(buffer+8,4)==(DWORD)arg.dwSequence)return dwRet;
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);
pCnnGSM->Errors->Clear();
pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
}else
{
sprintf(strSQL,"exec sp_send_mt_resp %d,%d,'%.20s'",
arg.iChannelNum,GetNByte(buffer+8,4),msg->szContent);
AddResp("Resp",0,"%d,%d,%.20s\n",
arg.iChannelNum,GetNByte(buffer+8,4),msg->szContent);
if(arg.isDebug)AddLog("resp: %s\n",strSQL);
pCnnGSM->Errors->Clear();
pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
}
break;
case nCMPP_QUERY_RESP:
break;
case nCMPP_CANCEL_RESP:
break;
case nCMPP_ACTIVE_TEST:
PutNByte(buffer+4,4,nCMPP_ACTIVE_TEST_RESP);
PutNByte(buffer,4,12+1);
buffer[12]=0;
if(i=SendBuffer(buffer,13))return i;
arg.dwRecv++;
arg.isActive=1;
break;
case nCMPP_ACTIVE_TEST_RESP:
//if(arg.isDebug)AddLog("cmpp active test ok.\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",
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);
PutNByte(buffer+4,4,0x80000000+GetNByte(buffer+4,4));
buffer[20]=0;
PutNByte(buffer,4,21);
if(i=SendBuffer(buffer,21))return i;
pCnnGSM->Errors->Clear();
pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
break;
}//end of swtich
//end of processing a package.
//只有对应流水号、对应指令完全匹配的包回来以后才能够退出,否则继续由本函数收包
if((DWORD)arg.dwSequence==GetNByte(buffer+8,4))return 0;
}//end of while 1
return 0;
}
DWORD SendOnlyData(CMSG *msg)
{
int i,j,k;
char buffer[SMPPMAXLENGTH];
char tmp[50];
BYTE b;
MD5 ctx;
char authsrc[50], *pos;
DWORD ts;
i=0;
i+=4;//keep space for package length.
memset(buffer,0,SMPPMAXLENGTH);
arg.dwSequence2++;
arg.dwSequence++;
PutNByte(buffer+i,4,msg->dwCommand);
i+=4;
if(msg->dwCommand==nCMPP_SUBMIT)arg.dwSequence=msg->dwSequence;
else arg.dwSequence=arg.dwSequence2;
PutNByte(buffer+i,4,arg.dwSequence);
i+=4;//head length=12 bytes.
switch(msg->dwCommand)
{
case nCMPP_SUBMIT:// 3
/////////////////////////////////
memset(buffer+i,0,8);//reserved for ismg_id
i+=8;
buffer[i]=msg->bPK_TOTAL;i++;//pk_total
buffer[i]=msg->bPK_NUM;i++;//pk_number
buffer[i]=msg->isReply;i++;//is_reply
buffer[i]=0;i++;//msg level
sprintf(buffer+i,"%.10s",msg->szServiceID);i+=10;//svc id
buffer[i]=msg->bFeeUserType;i++;//fee user type
sprintf(buffer+i,"%.21s",msg->FeeUser);i+=21;
buffer[i]=msg->bPID;i++;//pid
buffer[i]=msg->bUDHI;i++;//udhi
buffer[i]=msg->msg_format;i++;//msg format
sprintf(buffer+i,"%.6s",arg.SPID);i+=6;//msg_src
sprintf(buffer+i,"%s",msg->FeeType);i+=2;//fee type
sprintf(buffer+i,"%.6d",atoi(msg->FeeCode));i+=6;//fee code
memset(buffer+i,0,34);i+=34;//ValId_Time & At_Time
sprintf(buffer+i,"%.21s",msg->SrcTermId);i+=21;//src termid
buffer[i]=1;i++;//dst termid count
sprintf(buffer+i,"%.21s",msg->DstTermId);i+=21;//dst termid
if(msg->msg_format==0||msg->msg_format==15)
{
if(msg->msg_format==0)
{
if(strlen(msg->szContent)<160)
buffer[i]=strlen(msg->szContent);
else buffer[i]=(char)159;
}else
{
if(strlen(msg->szContent)<=140)
buffer[i]=strlen(msg->szContent);
else buffer[i]=(char)140;
}
i++;//msg lenth should in [0,160)
strncpy(buffer+i,msg->szContent,(BYTE)buffer[i-1]);
i+=(BYTE)buffer[i-1];
}
else
{
j=strlen(msg->szContent);
if(j>280)j=140;else j/=2;
buffer[i]=j;
i++;
for(k=0;k<j;k++)
{
sprintf(tmp,"0x%.2s\0",msg->szContent+k*2);
sscanf(tmp,"%x",&b);
buffer[i+k]=b;
}
i+=j;
}
sprintf(buffer+i,"%.8s\0",msg->sLinkID);
i+=8;
break;
case nCMPP_CONNECT:// over
ts=GetTime();//通过截取数据包发现,AIAPI里面取值为0,华为网关取值为GETTIME()
memcpy(buffer+i,arg.SPID,6);i+=6;//spid looks like 901001
// 计算单向HASH函数的值
memset(authsrc,0,sizeof( authsrc));
strcpy(authsrc,arg.SPID);
pos = authsrc + 6 + 9;//9 bytes 0
strcpy((char *)pos, arg.Password);
pos += strlen(arg.Password);
sprintf(pos, "%.10d",ts);
pos+=10;
ctx.update( (unsigned char *)authsrc, (int)(pos - authsrc) );
ctx.finalize();
ctx.raw_digest((unsigned char*)buffer+i);i+=16;//16 digist
buffer[i]=arg.isMO;//send mt & recv mo
i++;
PutNByte(buffer+i,4,ts);i+=4;//time stamp looks like:MMDDHHMMSS,1001100101
break;
case nCMPP_ACTIVE_TEST:
break;
}
PutNByte(buffer,4,i);
i=SendBuffer(buffer,i);
return i;
}
bool GetArg(CArg* arg)
{
FILE* pf=NULL;
char tchar[_MAX_PATH];
int tp;
arg->nLost=0;
arg->nLost=0;
GetModuleFileName(NULL,tchar,MAX_PATH);
sprintf(strrchr(tchar,'\\')+1,"gw.ini\0");
pf=fopen(tchar,"r");
if(pf==NULL)
{
AddLog("Load file %s Failed .\n",tchar);
return 0;
}
memset(arg,0,sizeof(CArg));
fgets(tchar,_MAX_PATH,pf);
arg->strCnn=_bstr_t("Provider=sqloledb;Data Source=")+_bstr_t(strchr(tchar,'=')+1);
fgets(tchar,_MAX_PATH,pf);
arg->strCnn+=_bstr_t(";Initial Catalog=")+_bstr_t(strchr(tchar,'=')+1);
fgets(tchar,_MAX_PATH,pf);
arg->strCnn+=_bstr_t(";User Id=")+_bstr_t(strchr(tchar,'=')+1);
fgets(tchar,_MAX_PATH,pf);
arg->strCnn+=_bstr_t(";Password=")+_bstr_t(strchr(tchar,'=')+1);
fgets(tchar,_MAX_PATH,pf);
sscanf(strchr(tchar,'=')+1,"%s",arg->SPID);
arg->SPID[6]=0;
fgets(tchar,_MAX_PATH,pf);
sscanf(strchr(tchar,'=')+1,"%s",arg->Password);
fgets(tchar,_MAX_PATH,pf);
sscanf(strchr(tchar,'=')+1,"%s",arg->SMSCIP);
fgets(tchar,_MAX_PATH,pf);
sscanf(strchr(tchar,'=')+1,"%d",&tp);
arg->SMSCPORT=tp;
fgets(tchar,_MAX_PATH,pf);
sscanf(strchr(tchar,'=')+1,"%d",&tp);
arg->nMaxReconnect=tp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -