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

📄 func.cpp

📁 本程序是实现中国移动中国联通的网关程序.代码比较完整.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
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;
	if(arg.s<1||arg.dwStopFlag)return ExitFromNetClose;
	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 error1 for: %d\n",WSAGetLastError());
#if ONESECTION1
			LeaveCriticalSection(&(arg.syc1));
#endif
			return ExitFromNetClose;
		}

		i+=j;
	}
#if ONESECTION1
	LeaveCriticalSection(&(arg.syc1));
#endif
	AddBinLog(buffer,i,0);
	return 0;
}
int SendBuffer(char* buffer)
{
	int i,j,buf_len;
	if(arg.s<1||arg.dwStopFlag)return ExitFromNetClose;
	i=j=0;
	buf_len=(int)GetNByte(buffer,4);
#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 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;
	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)
{
	int i;
	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;

	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==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();
		ts=0;
		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;//0:send mt, 1:recv ,2: other operation
		i++;
		PutNByte(buffer+i,4,ts);i+=4;//time stamp looks like:MMDDHHMMSS,1001100101
		break;
		case nCMPP_ACTIVE_TEST:
			buffer[i]=0;i++;
		break;
	}
	PutNByte(buffer,4,i);
	if(i=SendBuffer(buffer))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 nCMPP_CONNECT_RESP:
				if(GetNByte(buffer+12,4)==0)
				{
					arg.isActive=1;
					AddLog("bind to chen1 server ok\n");
					break;
				}
				else AddLog("bind to server error for: %d.\n",GetNByte(buffer+12,4));
				arg.isActive=0;
			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)break;
				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);
					if(arg.isDebug)AddLog("resp: %s\n",strSQL);
					AddResp("Resp",0,"%d,%d,%.20s\n",
						arg.iChannelNum,GetNByte(buffer+8,4),msg->szContent);
				}
				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))return i;
				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[87]==0)//是否是状态报告
				{//deliver process
					wtos(tmp,GetNByte(buffer+12,4),GetNByte(buffer+12+4,4));
					for(i=0;i<(BYTE)buffer[88];i++)//状态报告标志后面就是1字节的长度标志
						sprintf(msgbuffer+i*2,"%.2x",//长度标志后面就是信息体
						(BYTE)(buffer[89+i]));
					//if(strlen(buffer+41)>1)
					//{
						sprintf(strSQL,"exec sp_insert_mo '%s','%.32s',0x%s,%d,'%.21s',%d,'%.20s','%.10s'",
							tmp,//ismg_id
							buffer+54,//src_termid  位于msg_format之后,长度32字节
							msgbuffer,//msg
							(BYTE)buffer[53],//msg_format 位于第54字节
							buffer+20,//dst_termid 前面有20字节,长度为21字节
							arg.iChannelNum,//channel number.
							buffer+GetNByte(buffer,4)-20,//LinkID是最后20字节
							buffer+41//spserviceid前面有41字节
							);

						AddResp("MO",0,"%s,%.32s,0x%s,%d,%.21s,%d,%.20s,%.10s\n",
							tmp,//ismg_id
							buffer+54,//src_termid  位于msg_format之后,长度32字节
							msgbuffer,//msg
							(BYTE)buffer[53],//msg_format 位于第54字节
							buffer+20,//dst_termid 前面有20字节,长度为21字节
							arg.iChannelNum,//channel number.
							buffer+GetNByte(buffer,4)-20,//LinkID是最后20字节
							buffer+41//spserviceid前面有41字节
							);
					/*}else
					{
						sprintf(strSQL,"exec sp_insert_mo '%s','%.32s',0x%s,%d,'%.21s',%d",
							tmp,//ismg_id
							buffer+54,//src_termid  位于msg_format之后,长度32字节
							msgbuffer,//msg
							(BYTE)buffer[53],//msg_format 位于第54字节
							buffer+20,//dst_termid 前面有20字节,长度为21字节
							arg.iChannelNum//channel number.
							);

						AddResp("MO",0,"%s,%.32s,0x%s,%d,%.21s,%d\n",
							tmp,//ismg_id
							buffer+54,//src_termid  位于msg_format之后,长度32字节
							msgbuffer,//msg
							(BYTE)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+89,4),GetNByte(buffer+89+4,4));
					sprintf(strSQL,"EXEC SP_STATE_REPORT %d,'%s','%.32s','%.7s','%.10s'",
						arg.iChannelNum,
						tmp,//ismg_id
						buffer+89+8+7+20,//dst_termid,在状态报告+20字节之后,长度为32字节
						buffer+89+8,//state在8字节ISMGID之后,长度7字节
						buffer+12+8+21
						);
					AddResp("Status",0,"%d,%s,%.32s,%.7s,%.10s\n",
						arg.iChannelNum,
						tmp,//ismg_id
						buffer+89+8+7+20,//dst_termid,在状态报告+20字节之后,长度为32字节
						buffer+89+8,//state在8字节ISMGID之后,长度7字节
						buffer+12+8+21
						);
				}
				if(arg.isDebug)AddLog("%s\n",strSQL);
				pCnnGSM->Errors->Clear();
				pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);

				PutNByte(buffer+20,4,0);
				PutNByte(buffer,4,24);
				PutNByte(buffer+4,4,nCMPP_DELIVER_RESP);
				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==nCMPP_SUBMIT)arg.dwSequence=msg->dwSequence;
	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]=3;i++;//msg level set to 3
		sprintf(buffer+i,"%.10s",msg->szServiceID);i+=10;//svc id
		buffer[i]=msg->bFeeUserType;i++;//fee user type
		sprintf(buffer+i,"%.32s",msg->FeeUser);i+=32;
		buffer[i]=0;i++;//fee term type
		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
//#if 1
		//sprintf(buffer+i,"000002000000000R");//2 days.
		//memset(buffer+i+16,0,18);i+=34;//Valid_Time & At_Time,000002000000000R:
//#else
		//memset(buffer+i,0,34);i+=34;//Valid_Time & At_Time
//#endif
		sprintf(buffer+i,"%.21s",msg->SrcTermId);i+=21;//src termid
		buffer[i]=1;i++;//dst termid count
		sprintf(buffer+i,"%.32s",msg->DstTermId);i+=32;//dst termid
		buffer[i]=0;i++;//dst termid type
		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);
		sprintf(buffer+i,"%.20s",msg->sLinkID);
		i+=20;
		break;
	case nCMPP_CONNECT:// over
		//ts=GetTime();
		ts=0;
		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;//0:send mt, 1:recv ,2: other operation
		i++;
		PutNByte(buffer+i,4,ts);i+=4;//time stamp looks like:MMDDHHMMSS,1001100101
		break;
		case nCMPP_ACTIVE_TEST:
			buffer[i]=0;i++;
		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);

	

⌨️ 快捷键说明

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