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

📄 cmpp_client.cpp

📁 河南移动的cmpp的基础类
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "StdAfx.h"
#include "cmpp_client.h"
#include "global.h"
#include "cmpp.h"
#include "proxyserver.h"
#include ".\cmpp_client.h"

#define EACH_SMS_LEN 120

vector<FeeNode> CCMPP_Client::m_FeeList;
bool CCMPP_Client::m_bCanUsed = false;
char CCMPP_Client::m_SrcID[80];
char CCMPP_Client::m_DefaultMsgSrc[80];
CLogFile CCMPP_Client::m_LogFile;
char CCMPP_Client::m_LogFileName[256]={"log\\CMPPClient.log"};
DWORD CCMPP_Client::m_LastUserID=0;
int CCMPP_Client::m_SocketCount=0;

CCMPP_Client::CCMPP_Client(void)
{
}

CCMPP_Client::~CCMPP_Client(void)
{
}

void CCMPP_Client::CMPP_MSG_Dowith(char* pData, DWORD nLen, DWORD UserID)
{
	CMPP_ActiveTestResp * pActiveResp;
	//CMPP_CancelResp *pCancelResp;
	CMPP_ConnectResp *pConnectResp;
	CMPP_DeliverResp *pDeliverResp;
	CMPP_Deliver *pDeliver;
	CMPP_QueryResp *pQueryResp;
	CMPP_SubmitResp * pSubmitResp;
	CMPP_Terminate * pTerminate;
	CMPP_TerminateResp * pTerminateResp;

	CMPP_Head Head;
	char buffer[32768];

	if(nLen > 4096)
	{
		TRACE("too long%ld\r\n", nLen);
		return ;
	}

	//加入数据到缓冲区
	m_CMPPSocket.AppendData(UserID, (BYTE*)pData, nLen);

	for(;;)
	{
		TRACE("ok-1\r\n");
		int bytes = m_CMPPSocket.GetData(UserID, (BYTE*)&Head, sizeof(CMPP_Head));

		if(bytes == sizeof(CMPP_Head))
		{
			if( ntohl(Head.TotalLength) > 2048 || ntohl(Head.TotalLength) == 0)
			{
				m_CMPPSocket.Clear(UserID);
				break;
			}
			int RcvBytes = m_CMPPSocket.GetDataAndRemove(UserID, (BYTE*)buffer, ntohl(Head.TotalLength));
			TRACE("响应消息ID=0x%08X,length=%ld,bytes=%ld\r\n", ntohl(Head.CommandID), ntohl(Head.TotalLength),RcvBytes);

			if(RcvBytes == ntohl(Head.TotalLength))
			{
				
				switch(ntohl(Head.CommandID))
				{
				case CMPP_Msg::ACTIVE_TEST:
					
					break;
				case CMPP_Msg::ACTIVE_TEST_RESP:
					TRACE("测试连接响应消息\r\n");
					pActiveResp = (CMPP_ActiveTestResp*)buffer;
					break;
				case CMPP_Msg::CANCEL_RESP:
					TRACE("取消短信响应消息\r\n");
//					pCancelResp = (CMPP_ConnectResp*)buffer;

					break;
				case CMPP_Msg::CONNECT_RESP:
					TRACE("连接登陆响应消息\r\n");
					pConnectResp = (CMPP_ConnectResp*)buffer;
					if(pConnectResp->Status == 0)
					{
						m_ListMsg.InsertStringToQueue(0, "登陆短信网关成功。连接编号:%ld,版本:%0X", UserID, pConnectResp->Version);
						m_bCanUsed = true;
					}
					else
					{
						m_ListMsg.InsertStringToQueue(1, "登陆短信网关失败,连接编号:%ld, 状态:%d,版本:%0X", UserID, pConnectResp->Status, pConnectResp->Version);
					}
					break;
				case CMPP_Msg::DELIVER_RESP:
					TRACE("接收短信响应消息\r\n");
					pDeliverResp = (CMPP_DeliverResp*)buffer;
					break;
				case CMPP_Msg::DELIVER:
					TRACE("接收短信消息\r\n");
					pDeliver = (CMPP_Deliver*)buffer;
					//m_ListMsg.InsertStringToQueue(0, "接收到Deliver消息,TotalLength=%ld, MsgLength=%d", htonl(pDeliver->TotalLength), pDeliver->Msg_Length);
 					m_ListMsg.InsertStringToQueue( 0, "接收到Deliver消息,TotalLength=%ld, MsgLength=%d,SocketID:%d", htonl(pDeliver->TotalLength), pDeliver->Msg_Length, UserID);
					
					DeliverMsg( pDeliver, UserID );
					break;
				case CMPP_Msg::QUERY_RESP:
					TRACE("查询响应消息\r\n");
					pQueryResp = (CMPP_QueryResp*)buffer;
					break;
				case CMPP_Msg::SUBMIT_RESP:
					TRACE("提交短信响应消息\r\n");
					pSubmitResp = (CMPP_SubmitResp*)buffer;
					if(pSubmitResp->Result == 0)
					{
						m_ListMsg.InsertStringToQueue( 0, "短消息发送成功");
						//SetMsgID(ntohl(pSubmitResp->SequenceID), pSubmitResp->Msg_Id );
					}
					else
					{
						m_ListMsg.InsertStringToQueue(1, "短消息发送失败。错误值:%d", pSubmitResp->Result);
					}
					break;
				case CMPP_Msg::TERMINATE:
					TRACE("终止消息\r\n");
					pTerminate = (CMPP_Terminate*)buffer;
					m_bCanUsed = false;
					SendTerminateResp(UserID);
					break;
				case CMPP_Msg::TERMINATE_RESP:
					TRACE("终端响应消息\r\n");
					pTerminateResp = (CMPP_TerminateResp*)buffer;
		//			m_CMPPSocket.Close(UserID);
					break;
				default:
					break;
				}
			}
			else
				break;
		}
		else
			break;
	}
}

void CCMPP_Client::DowithConnect(char * strIP, short Port, DWORD UserID)
{
	m_ListMsg.InsertStringToQueue(0, "与CMPP服务器建立连接。IP=%s, Port=%d,,并发送登陆包,等待回应。", m_CMPPSocket.GetIP(UserID), m_CMPPSocket.GetPort(UserID));
	m_bCanUsed = false;
	
	//
	m_LogFile.WriteLog(m_LogFileName, "与短信网关建立连接,并发送登陆包,等待回应。");
	//建立连接,发送登陆包
	SendLogon(UserID);
}

void CCMPP_Client::DowithDisconnect(char * strIP, short Port, DWORD UserID)
{
	m_ListMsg.InsertStringToQueue(1, "与短消息网关的连接断开。");
	m_bCanUsed = false;
	m_SocketTimer.AddOnceTimer(60, UserID, 0, 0);
	this->m_CMPPSocket.Clear(UserID);
}

void CCMPP_Client::SendActive(DWORD UserID)
{
	CMPP_ActiveTest Active;
	DWORD ret = m_CMPPSocket.Send((BYTE*)&Active, sizeof(CMPP_ActiveTest), UserID);
	/*char temp[80];
	AfxMessageBox(itoa(ret, temp, 10));
	Sleep(100);*/
}

void CCMPP_Client::SendActiveResp(DWORD UserID)
{
	CMPP_ActiveTestResp Active;
	m_CMPPSocket.Send((BYTE*)&Active, sizeof(CMPP_ActiveTestResp), UserID);
}

bool CCMPP_Client::Connect(DWORD UserID)
{
	char IP[512];
	m_bCanUsed = false;
	char keyname[80];

	sprintf(keyname, "Port%d", UserID);
	int Port = GetPrivateProfileInt("CMPP", keyname, 0, CGlobal::IniFile);

	sprintf(keyname, "IP%d", UserID);
	GetPrivateProfileString("CMPP", keyname, "", IP, 256, CGlobal::IniFile);
	
	
	if(m_CMPPSocket.Connect(IP, Port, UserID) == 0)
	{
		Sleep(10);
		m_SocketTimer.RemoveTimer(UserID);
		return true;
	}
	else
	{
		m_ListMsg.InsertStringToQueue(1, "不能与CMPP服务器建立连接,请检查网络及相关参数。IP=%s, Port=%d", m_CMPPSocket.GetIP(UserID), m_CMPPSocket.GetPort(UserID));
		m_SocketTimer.AddOnceTimer(60, UserID, 0, 0);
		int t=0;
		TRACE("\r已经设置了自动重新连接!时间是%d\r",t=60);
		return false;
	}
}

void CCMPP_Client::SendLogon(DWORD UserID)
{
	BYTE Authenticator[256];
	char pwd[80], sp[80];

	GetPrivateProfileString("CMPP", "Authenticator", "", pwd, 64, IniFile);
	GetPrivateProfileString("CMPP", "user", "", sp, 64, IniFile);

	strcpy(m_DefaultMsgSrc, sp);
	GetPrivateProfileString("CMPP", "sp", "", m_SrcID, 64, IniFile);

	char temp[256];
	ZeroMemory(temp, 256);
	/*SYSTEMTIME t;
	GetLocalTime(&t);*/

	//生成登陆消息
	CMPP_Connect logon;

//	sprintf(temp, "%s000000000%s%02d%02d%02d%02d%02d", sp, pwd, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
	char time[80];
	sprintf(time, "%010d", ntohl(logon.Timestamp));
	sprintf(temp, "%s000000000%s%s", sp, pwd, time );
	memset((BYTE*)&temp[strlen(sp)], 0, 9);
	int len = CMD5Checksum::GetMD5( Authenticator, (BYTE*)temp, (int)strlen(sp) + 9 + (int)strlen(pwd) + (int)strlen(time));
	
	memcpy(logon.SourceAddr, sp, strlen(sp));
	
	memcpy(logon.Authenticator, Authenticator, len);

	if(m_CMPPSocket.Send((BYTE*)&logon, sizeof(CMPP_Connect), UserID) > 0)
	{
		m_ListMsg.InsertStringToQueue(0, "发送登陆鉴权消息成功。");
	}
	else
		m_ListMsg.InsertStringToQueue(1, "发送登陆鉴权消息失败。");

}

void CCMPP_Client::SendTerminate(DWORD UserID)
{
	CMPP_Terminate Terminate;
	m_CMPPSocket.Send((BYTE*)&Terminate, sizeof(CMPP_Terminate), UserID);
}

void CCMPP_Client::SendTerminateResp(DWORD UserID)
{
	CMPP_TerminateResp TerminateResp;
	m_CMPPSocket.Send((BYTE*)&TerminateResp, sizeof(CMPP_TerminateResp), UserID);
}

void CCMPP_Client::DeliverMsg(CMPP_Deliver* pDeliver, DWORD UserID)
{
	char  Sender[80];
	char Receiver[80];

	
	ZeroMemory(Sender, 80);
	ZeroMemory(Receiver, 80);

	CMPP_DeliverResp DeliverResp;

	memcpy(DeliverResp.Msg_Id, pDeliver->Msg_Id, 8);

	try
	{
		//消息头检验
		if( htonl(pDeliver->TotalLength) == (CMPP_DELIVER_HEAD_LENGTH + pDeliver->Msg_Length + 8)
							&& pDeliver->Msg_Length <128 )
		{
			DeliverResp.Result = 0;
			DeliverReport Report;
			if(pDeliver->Registered_Delivery == 0)//SMS
			{
				m_ListMsg.InsertStringToQueue(0, "收到短信,开始处理。");
				//TRACE("接收到短信\r\n");
				char Context[1024];
				ZeroMemory(Context, 256);

				memcpy(Sender, pDeliver->Srcterminal_id, __min(20, strlen(pDeliver->Srcterminal_id)));
				memcpy(Receiver, pDeliver->Destnation_id, __min(20, strlen(pDeliver->Destnation_id)));

				m_ListMsg.InsertStringToQueue(0, "收到短信,开始处理。len=%d", pDeliver->Msg_Length);
				int len = __min(255, pDeliver->Msg_Length);
				if(len != 0)
				{
					if( pDeliver->Msg_Fmt == 8 )
					{
						CMPP_Head::UCS2_To_ASCII( (LPCWSTR)pDeliver->Msg_Content, pDeliver->Msg_Length, Context);
						//Context[pDeliver->Msg_Length/2] = 0;
					}
					else
						memcpy( Context, pDeliver->Msg_Content,  len );
				}
				TRACE("接收到短信---3\r\n");
				m_ListMsg.InsertStringToQueue(0, "收到短信:%s, 发送方号码:%s, 接收方号码:%s", Context, Sender, Receiver);
				
				//发送给短信处理程序
				//if(pDeliver->Msg_Length > 0)
				TRACE("接收到短信---4\r\n");

				//记录日志

				//

				CProxyServer::FireRcvSM(pDeliver->Srcterminal_id, pDeliver->Destnation_id, Context, pDeliver->Msg_Length);
				TRACE("接收到短信---5\r\n");
			}
			else if(pDeliver->Registered_Delivery == 1)//REPORT
			{
				if( pDeliver->Msg_Length == sizeof(DeliverReport) )
				{
					TRACE("接收到报告\r\n");
					memcpy(&Report, pDeliver->Msg_Content, __min(pDeliver->Msg_Length, sizeof(DeliverReport)));

					char stat[80];

					ZeroMemory(stat, 80);
					memcpy(stat, Report.Stat, 7);
					memcpy(Receiver, Report.Dest_terminal_Id, __min(20, strlen(Report.Dest_terminal_Id)));
					
					m_ListMsg.InsertStringToQueue(0, "收到状态报告:%s, 接收方号码:%s", stat, Receiver);

					FeeResult( Report );

				}
				else
				{
					DeliverResp.Result = 1;
					m_ListMsg.InsertStringToQueue(1, "收到的状态报告包有错误。");
				}
			}
		}
		else
		{
			DeliverResp.Result = 4;
			m_ListMsg.InsertStringToQueue(1, "接收短信消息长度错误");
		}
	}
	catch(...)
	{
		DeliverResp.Result = 9;
		m_ListMsg.InsertStringToQueue(1, "接收短信消息的异常错误。");
	}

	TRACE("Deliver Response MSG \r\n");
	memcpy(DeliverResp.Msg_Id, pDeliver->Msg_Id, 8);
	m_CMPPSocket.Send((BYTE*)&DeliverResp, sizeof(CMPP_DeliverResp), UserID);
}

/*
char FeeUserType--一般等于0
计费用户类型字段
0:对目的终端MSISDN计费;
1:对源终端MSISDN计费;
2:对SP计费;
3:表示本字段无效,对谁计费参见Fee_terminal_Id字段。

char* FeeTerminal---被计计费的用户号码

char MsgFmt--端消息的编码格式
0:ASCII串
3:短信写卡操作
4:二进制信息
8:UCS2编码
15:含GB汉字 

char* MsgSrc -信息内容来源(SP_Id)

char * FeeType--资费类别
01:对“计费用户号码”免费
02:对“计费用户号码”按条计信息费
03:对“计费用户号码”按包月收取信息费
04:对“计费用户号码”的信息费封顶
05:对“计费用户号码”的收费是由SP实现
如果MsgSrc为空则填写m_DefaultMsgSrc的值m_DefaultMsgSrc从设置文件的[CMPP]的sp读取
char* FeeCode--付费金额

char* SrcId--源号码
SP的服务代码或前缀为服务代码的长号码, 网关将该号码完整的填到SMPP协议Submit_SM消息相应的source_addr字段,
该号码最终在用户手机上显示为短消息的主叫号码

char* DestTerminal ==接收方号码
char Registered_Delivery=是否需要报告
0:不需要
1:需要
2:产生SMC话单(该类型短信仅供网关计费使用,不发送给目的终端)

int MsgLength==消息的长度

char* MsgContext==消息的内容
*/
int CCMPP_Client::Submit(/*char * ServiceID, */
char FeeUserType, char* FeeTerminal, char MsgFmt, char* MsgSrc, 
char * FeeType, char* FeeCode, char* SrcId, char* DestTerminal, 
char Registered_Delivery, int MsgLength, char* MsgContext)
{
	BYTE buffer[1024];//定义要发送的字符序列
	CMPP_Submit Submit;//实例化短信提交类
	DWORD UserID =GetSendID();//得到系统内部的soketid
	if(UserID>=0xFFFF)//如果用户不存在
	{
		return -3;//退出
	}
	strcpy(Submit.Service_id,m_SrcID);//给类中的变量赋值,该变量表示业务类型
	strcpy(Submit.Fee_terminal_id,FeeTerminal);//给类中的变量赋值,该变量表示被计费的用户号码
	if(strlen(MsgSrc))//如果信息来源长度不是零
	{
		strcpy(Submit.Msg_src,m_DefaultMsgSrc);//信息来源表示的是sp的id,该id是给移动的短信平台来识别sp的识别码
	}
	else
	{
		strcpy(Submit.Msg_src,MsgSrc);
	}

	memcpy(Submit.FeeType,FeeType,2);//FeeType表示资费类型
	strncpy(Submit.FeeCode,FeeCode,__min(6,strlen(FeeCode)));//FeeCode表示资费代码

	if(strlen(SrcId)!=0)
	{
		strcpy(Submit.Src_terminal_id,SrcId);//Src_terminal_id是sp的号码,给用户识别的代码,在这里指短信的发送方
	}

⌨️ 快捷键说明

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