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

📄 func.cpp

📁 本程序是实现中国移动中国联通的网关程序.代码比较完整.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			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;
	if(arg.s<1)return ExitFromNetClose;
	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;
	if(arg.s<1)return ExitFromNetClose;
	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)
{
	fd_set rfds,afds;
	char strSQL[512];
	char buffer[SMPPMAXLENGTH];
	timeval tv;
	DWORD dwRet;
	char tmp[50];
	char msgbuffer[323];
	BYTE isDeliver;
	MD5 ctx;
	char authsrc[50], *pos;
	DWORD ts;
	BYTE bCanFunReturn=0;
	int i,j;
	BYTE msg_fmt;

	arg.dwSequence2++;
	memset(buffer,0,sizeof(buffer));
	i=0;
	i+=4;//keep space for package length.
	PutNByte(buffer+i,4,msg->dwCommand);
	i+=4;
	
	if(msg->dwCommand==nSMGP_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 nSMGP_CONNECT:// over
		strncpy(buffer+i,arg.clientID,8);i+=8;//clientid=SaiBe

		//ts=GetTime();
		ts=0;
		//	计算单向HASH函数的值
		memset(authsrc,0,sizeof(authsrc));
		strcpy(authsrc,arg.clientID);
		pos = authsrc + strlen(arg.clientID) + 7;//add 7 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;//login mode,0:send mt, 1:recv ,2: send & recv
		i++;
		PutNByte(buffer+i,4,ts);i+=4;//time stamp looks like:MMDDHHMMSS,1001100101
		buffer[i]=nSMGP_VERSION;i++;//version
		break;
		case nSMGP_ACTIVE_TEST:
		break;
	}
	PutNByte(buffer,4,i);
	i=SendBuffer(buffer);
	if(i)return i;
	SleepEx(20,1);
	tv.tv_sec=5;
	tv.tv_usec=0;
	FD_ZERO(&afds);
	FD_SET(arg.s,&afds);
	isDeliver=0;
	bCanFunReturn=0;
	while(1)//不断读取数据,直到取到希望的数据为止
	{
#if 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 ExitFromNetClose;//time expired
		}
#endif
		ZeroMemory(buffer,SMPPMAXLENGTH);
		dwRet=0;
		if(i=RecvBuffer(buffer))return i;
		arg.dwRecv++;
		
		switch(GetNByte(buffer+4,4))
		{
			case nSMGP_CONNECT_RESP:
				if(GetNByte(buffer+8,4))
				{
					AddLog("bind to server error for: %d.\n",GetNByte(buffer+8,4));
					arg.isActive=0;
					return ExitFromNetClose;
				}
				else
				{
					AddLog("bind to server ok.\n");
					arg.isActive=1;
				}
			break;
			case nSMGP_TERMINATE_RESP:
				closesocket(arg.s);
				arg.isActive=0;
				return 0;
			break;
			case nSMGP_SUBMIT_RESP:
				SetWindow(-1);
				sprintf(msgbuffer,"%.6x%.8x%.6x",GetNByte(buffer+12,3),GetNByte(buffer+15,4),GetNByte(buffer+19,3));
				dwRet=GetNByte(buffer+22,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
				{
					sprintf(strSQL,"exec sp_send_mt_resp %d,%d,'%.20s'",
						arg.iChannelNum,GetNByte(buffer+8,4),msgbuffer);
					if(arg.isDebug)AddLog("resp: %s\n",strSQL);
					AddResp("Resp",0,"%d,%d,%.20s\n",
						arg.iChannelNum,GetNByte(buffer+8,4),msgbuffer);
				}
				arg.pCnnGSM->Errors->Clear();
				arg.pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
				break;
			case nSMGP_ACTIVE_TEST:
				PutNByte(buffer+4,4,nSMGP_ACTIVE_TEST_RESP);
				if(i=SendBuffer(buffer))return i;
				arg.isActive=1;
			break;
			case nSMGP_ACTIVE_TEST_RESP:
				if(arg.isDebug)AddLog("active test ok.\n");
				arg.isActive=1;
			break;
			case nSMGP_DELIVER:
			if(buffer[26]==0)//是否是状态报告
			{//deliver process
				sprintf(tmp,"%.6x%.8x%.6x",
					GetNByte(buffer+16,3),GetNByte(buffer+16+3,4),GetNByte(buffer+16+3+4,3));
				msg_fmt=(BYTE)buffer[27];
				if(msg_fmt==0||msg_fmt==3||msg_fmt==4||msg_fmt==15)
				for(i=0;i<(BYTE)buffer[84];i++)//状态报告标志后面就是1字节的长度标志
					sprintf(msgbuffer+i*2,"%.2x",//长度标志后面就是信息体
					(BYTE)(buffer[85+i]));
				else
				{
					if(j=UCS2toGB(buffer+85,strSQL,(BYTE)buffer[84]))
					for(i=0;i<j;i++)
						sprintf(msgbuffer+i*2,"%.2x",(BYTE)(strSQL[i]));
					else msgbuffer[0]=0;
					msg_fmt=15;
				}
				sprintf(strSQL,"exec sp_insert_mo '%s','%.32s',0x%s,%d,'%.21s',%d",
					tmp,//ismg_id
					buffer+42,//src_termid  位于msg_format之后,长度32字节
					msgbuffer,//msg
					msg_fmt,//msg_format 位于状态报告标志后
					buffer+63,//dst_termid 前面有20字节,长度为21字节
					arg.iChannelNum//channel number.
					);

				AddResp("MO",0,"%d,%s,%.32s,0x%s,%d,%.21s\n",
					arg.iChannelNum,//channel number.
					tmp,//ismg_id
					buffer+42,//src_termid  位于msg_format之后,长度32字节
					msgbuffer,//msg
					msg_fmt,//msg_format 位于状态报告标志后
					buffer+63//dst_termid 前面有20字节,长度为21字节
					);
			}
			else
			{//state report process
				//应该取之前SUBMIT是回执里的ISMGID,这时在信息体开始的8字节内
				sprintf(tmp,"%.6x%.8x%.6x",GetNByte(buffer+84,3),GetNByte(buffer+87,4),GetNByte(buffer+91,3));
				sprintf(strSQL,"EXEC SP_STATE_REPORT %d,'%s','%.21s','%.7s','%.3s'",
					arg.iChannelNum,
					tmp,//ismg_id
					buffer+38,//dst_termid,长度为21字节
					buffer+162,//state
					buffer+174);//err code
				AddResp("Status",0,"%d,%s,%.21s,%.7s,%.3s,%.21s\n",
					arg.iChannelNum,
					tmp,//ismg_id
					buffer+38,//dst_termid,长度为21字节
					buffer+162,//state
					buffer+174,//error code
					buffer+59);//src_termid
			}
			if(arg.isDebug>1)AddLog("%s\n",strSQL);
			arg.pCnnGSM->Errors->Clear();
			arg.pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
			PutNByte(buffer+26,4,0x04280001);i+=4;
			buffer[i]=0;i++;
			PutNByte(buffer+4,4,nSMGP_DELIVER_RESP);
			PutNByte(buffer,4,31);
			PutNByte(buffer+8,4,0);
			if(i=SendBuffer(buffer))return i;
			break;		
		}//end of swtich
		//end of processing a package.
		//只有对应流水号、对应指令完全匹配的包回来以后才能够退出,否则继续由本函数收包
		if((DWORD)arg.dwSequence==GetNByte(buffer+8,4))bCanFunReturn=1;else isDeliver=1;
		if(isDeliver==1&&bCanFunReturn==1)return ExitFromNetClose+1;
		if(bCanFunReturn)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;
	arg.dwSequence++;
	memset(buffer,0,sizeof(buffer));
	i=0;
	i+=4;//keep space for package length.

	PutNByte(buffer+i,4,msg->dwCommand);
	i+=4;
	if(msg->dwCommand==nSMGP_SUBMIT)arg.dwSequence=msg->dwSequence;
	PutNByte(buffer+i,4,arg.dwSequence);
	i+=4;//head length=12 bytes.
	switch(msg->dwCommand)
	{
	case nSMGP_SUBMIT:// 3
		/////////////////////////////////
		buffer[i]=msg->bReason;i++;//sub_type
		buffer[i]=msg->isReply;i++;//is_reply
		buffer[i]=arg.nMsgLevel;i++;//msg level set to 3
		sprintf(buffer+i,"%.10s",msg->szServiceID);i+=10;//svc id
		sprintf(buffer+i,"%s",msg->FeeType);i+=2;//fee type
		if(atoi(msg->FeeType)==4)
		{
			sprintf(buffer+i,"%d",0);i+=6;//feecode=0
			sprintf(buffer+i,"%d",atoi(msg->FeeCode));i+=6;//fixedfee
		}
		else
		{
			sprintf(buffer+i,"%d",atoi(msg->FeeCode));i+=6;//fee code
			sprintf(buffer+i,"%d",0);i+=6;//fixedfee
		}		
		buffer[i]=msg->msg_format;i++;//msg format
		memset(buffer+i,0,34);i+=34;//Valid_Time & At_Time
		sprintf(buffer+i,"%.21s",msg->SrcTermId);i+=21;//src termid
		sprintf(buffer+i,"%.21s",msg->FeeUser);i+=21;
		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;
		}
		memset(buffer+i,0,8);i+=8;
		break;
	case nSMGP_CONNECT:// over
		strncpy(buffer+i,arg.clientID,8);i+=8;//clientid=SaiBe

		//ts=GetTime();
		ts=0;
		//	计算单向HASH函数的值
		memset(authsrc,0,sizeof(authsrc));
		strcpy(authsrc,arg.clientID);
		pos = authsrc + strlen(arg.clientID) + 7;//add 7 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;//login mode,0:send mt, 1:recv ,2: send & recv
		i++;
		PutNByte(buffer+i,4,ts);i+=4;//time stamp looks like:MMDDHHMMSS,1001100101
		buffer[i]=nSMGP_VERSION;i++;//version
		break;
		case nSMGP_ACTIVE_TEST:
		break;
	}
	PutNByte(buffer,4,i);
	i=SendBuffer(buffer);
	return i;
}
bool GetArg(CArg* arg)
{
	FILE* pf=NULL;
	char tchar[_MAX_PATH];
	int tp;
	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);
	
	fgets(tchar,_MAX_PATH,pf);
	sscanf(strchr(tchar,'=')+1,"%s",arg->clientID);

	fgets(tchar,_MAX_PATH,pf);
	sscanf(strchr(tchar,'=')+1,"%s",arg->Password);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -