⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 func.cpp

📁 本程序是实现中国移动中国联通的网关程序.代码比较完整.
💻 CPP
📖 第 1 页 / 共 3 页
字号:

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 + -