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

📄 smpprotocol.cpp

📁 模拟手机源程序,做短信系统(源码)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// SMPProtocol.cpp : implementation file
//

#include "StdAfx.h"
#include "SMPProtocol.h"
#include "SMSCSocket.h"
#include "SMPPAgentDlg.h"

/////////////////////////////////////////////////////////////////////////////
// CSMPProtocol
extern int g_n112DelayTime;

CSMPProtocol::CSMPProtocol(int nDestSMSC,char* szServiceNum,int nHaveRcvLink,int nHaveTrnLink)
{

	m_pcDlg = (CSMPPAgentDlg*) AfxGetMainWnd();

	m_nDestSMSC = nDestSMSC;

	strcpy(m_szServiceNum,szServiceNum);
	m_nHaveRcvLink = nHaveRcvLink;
	m_nHaveTrnLink = nHaveTrnLink;

	m_dwStatusRCV = NO_LOGIN;
	m_dwStatusTRN = NO_LOGIN;
	
	m_dwCommandStatus = COMMAND_STATUS_INIT;
	m_dwSequenceNO = 0;

	m_listSubmitRep.RemoveAll();
	m_listStatReport.RemoveAll();
	m_listDeliver.RemoveAll();

	m_nMTCount = 0;
	m_nMOCount = 0;
	m_nSubmitRespCount = 0;
	m_nStatReportCount = 0;

	m_hEventDeliver = CreateEvent(NULL,FALSE,TRUE,"EVENT_DELIVER");
	m_hEventSubmitRep = CreateEvent(NULL,FALSE,TRUE,"EVENT_SUBMITREP");
	m_hEventStatReport = CreateEvent(NULL,FALSE,TRUE,"EVENT_STATREPORT");
//	m_hEventShowStat = CreateEvent(NULL,FALSE,TRUE,"EVENT_SHOWSTAT");

	if((!m_nHaveRcvLink)&&(!m_nHaveTrnLink))
	{
		AfxMessageBox("配置文件错,请检查链路设置是否正确!");
		return;
	}

	if(m_nHaveRcvLink)
		m_cSMSCSocketRCV=new CSMSCSocket(APP_SMPPROTOCOL,this);

	if(m_nHaveTrnLink)
		m_cSMSCSocketTRN=new CSMSCSocket(APP_SMPPROTOCOL,this);
	
	if(!m_nHaveRcvLink)
		m_cSMSCSocketRCV = m_cSMSCSocketTRN;

	if(!m_nHaveTrnLink)
		m_cSMSCSocketTRN = m_cSMSCSocketRCV;

	time(&m_nTimeLink_RCV);
	time(&m_nTimeLink_TRN);

	m_nSendLinkCount = 0;
	m_nRecvLinkCount = 0;
}


CSMPProtocol::~CSMPProtocol()
{
	delete m_cSMSCSocketRCV;
	delete m_cSMSCSocketTRN;

	CloseHandle(m_hEventDeliver);
	CloseHandle(m_hEventSubmitRep);
	CloseHandle(m_hEventStatReport);
}


int CSMPProtocol::SMPPLogIn(char* szDestIP,int nDestPort,CSMPProtocol::struSMPPLOGIN struSmppLogIn)
{
	if(m_nHaveTrnLink)
		SMPPLogInTRN(szDestIP,nDestPort,struSmppLogIn);

	if(m_nHaveRcvLink)
		SMPPLogInRCV(szDestIP,nDestPort,struSmppLogIn);

	return 0;
}


int CSMPProtocol::SMPPLogInRCV(char* szDestIP,int nDestPort,CSMPProtocol::struSMPPLOGIN struSmppLogIn)
{
	strcpy(m_szSMPPIP,szDestIP);
	m_nSMPPort = nDestPort;
	m_struSMPPLogIn = struSmppLogIn;

	Print(" ");
	Print("=========================================");
	Print("[LOGIN.][RCV]系统正在注册短信中心,请稍后...");

	ShowStatus(APP_SMPPROTOCOL + STAT_SMSC_LINK,0,NULL);

	if(!m_cSMSCSocketRCV->SMSConnect(szDestIP,nDestPort))
	{
		Print("[LOGIN.][ERROR][RCV]系统注册短信中心失败!");
		return 1;
	}

	int		nBodyLen;
	char	szBodyBuff[MAX_MSGBODY_LEN];
	struSMPPACKAGE struSMPPackage;
	nBodyLen = CompresStruct(struSmppLogIn,szBodyBuff);	

	MakePackage(ESME_BNDRCV,-1,szBodyBuff,nBodyLen,&struSMPPackage);

	if(!m_cSMSCSocketRCV->SMSCSendMsg((char*)&struSMPPackage,16 + nBodyLen))
	{
		Print("[LOGIN.][ERROR][RCV]系统注册短信中心失败!");
		return 1;
	}

	long lTimeStart,lTimeNow;
	time(&lTimeStart);	time(&lTimeNow);
	m_dwCommandStatus = COMMAND_STATUS_INIT;
	while(((lTimeNow-lTimeStart) <= LOG_TIMEOUT_SEC)&&(m_dwCommandStatus == COMMAND_STATUS_INIT))
	{
		MSG Msg;
		while(PeekMessage(&Msg,NULL,NULL,NULL,PM_REMOVE)) //单线程能够处理其他消息
		{
			TranslateMessage(&Msg);
			DispatchMessage(&Msg);
		}
		Sleep(10);

		time(&lTimeNow);
	}

	if(m_dwCommandStatus == E_SUCCESS)
	{
		Print("[LOGIN.][RCV]系统注册短信中心成功!");
		m_dwStatusRCV = HAVE_LOGIN;
		ShowStatus(APP_SMPPROTOCOL + STAT_SMSC_LINK,1,NULL);

		SendSubmitBuff();

		m_nSendLinkCount =0;
		m_nRecvLinkCount =0;
	}
	else
		Print("[LOGIN.][ERROR][RCV]系统注册短信中心失败!");
	
	return m_dwCommandStatus;
}


int CSMPProtocol::SMPPLogInTRN(char* szDestIP,int nDestPort,CSMPProtocol::struSMPPLOGIN struSmppLogIn)
{
	strcpy(m_szSMPPIP,szDestIP);
	m_nSMPPort = nDestPort;
	m_struSMPPLogIn = struSmppLogIn;

	Print("[LOGIN.][TRN]系统正在注册短信中心,请稍后...");

	if(!m_cSMSCSocketTRN->SMSConnect(szDestIP,nDestPort))
	{
		Print("[LOGIN.][ERROR][TRN]系统注册短信中心失败!");
		return 1;
	}

	int		nBodyLen;
	char	szBodyBuff[MAX_MSGBODY_LEN];
	struSMPPACKAGE struSMPPackage;
	nBodyLen = CompresStruct(struSmppLogIn,szBodyBuff);	

	MakePackage(ESME_BNDTRN,-1,szBodyBuff,nBodyLen,&struSMPPackage);

	if(!m_cSMSCSocketTRN->SMSCSendMsg((char*)&struSMPPackage,16 + nBodyLen))
	{
		Print("[LOGIN.][ERROR][TRN]系统注册短信中心失败!");
		return 1;
	}

	long lTimeStart,lTimeNow;
	time(&lTimeStart);	time(&lTimeNow);
	m_dwCommandStatus = COMMAND_STATUS_INIT;
	while(((lTimeNow-lTimeStart) <= LOG_TIMEOUT_SEC)&&(m_dwCommandStatus == COMMAND_STATUS_INIT))
	{
		MSG Msg;
		while(PeekMessage(&Msg,NULL,NULL,NULL,PM_REMOVE)) //单线程能够处理其他消息
		{
			TranslateMessage(&Msg);
			DispatchMessage(&Msg);
		}
		Sleep(10);

		time(&lTimeNow);
	}

	strcpy(m_szSMPPIP,szDestIP);
	m_nSMPPort = nDestPort;
	m_struSMPPLogIn = struSmppLogIn;

	if(m_dwCommandStatus == E_SUCCESS)
	{
		Print("[LOGIN.][TRN]系统注册短信中心成功!");
		m_dwStatusTRN = HAVE_LOGIN;
		SendSubmitBuff();
	}
	else
		Print("[LOGIN.][ERROR][TRN]系统注册短信中心失败!");
	
	return m_dwCommandStatus;
}

int CSMPProtocol::SMPPLogOut()
{
	if(m_nHaveRcvLink)
		SMPPLogOutRCV();

	if(m_nHaveTrnLink)
		SMPPLogOutTRN();

	return 0;
}


int CSMPProtocol::SMPPLogOutRCV()
{
	/*
	struSMPPACKAGE struSMPPackage;	

	MakePackage(ESME_UBD,-1,NULL,0,&struSMPPackage);

	if(!m_cSMSCSocketRCV->SMSCSendMsg((char*)&struSMPPackage,16))
		return 1;
	*/

	m_cSMSCSocketRCV->SMSCDisConnect();
	return 0;
}

int CSMPProtocol::SMPPLogOutTRN()
{
	/*
	struSMPPACKAGE struSMPPackage;	

	MakePackage(ESME_UBD,-1,NULL,0,&struSMPPackage);

	if(!m_cSMSCSocketRCV->SMSCSendMsg((char*)&struSMPPackage,16))
		return 1;
	*/

	m_cSMSCSocketTRN->SMSCDisConnect();
	return 0;
}


DWORD CSMPProtocol::SMPPSubmit(CSMPProtocol::struSMPPSUBMIT struSmppSubmit)
{
	if(!m_nHaveTrnLink)
		m_dwStatusTRN = m_dwStatusRCV;	

	//strcpy(struSmppSubmit.szSourceAddress,m_szServiceNum);

	int		nBodyLen;
	char	szBodyBuff[MAX_MSGBODY_LEN];
	struSMPPACKAGE struSMPPackage;
	nBodyLen = CompresStruct(struSmppSubmit,szBodyBuff);

	MakePackage(ESME_SUB_SM,-1,szBodyBuff,nBodyLen,&struSMPPackage);

//	if((m_dwStatusTRN == LOGIN_BREAKED)||(m_dwStatusTRN == NO_LOGIN)||
//	   (!m_cSMSCSocketTRN->SMSCSendMsg((char*)&struSMPPackage,16 + nBodyLen)))
	if((m_dwStatusTRN != HAVE_LOGIN)||
	   (!m_cSMSCSocketTRN->SMSCSendMsg((char*)&struSMPPackage,16 + nBodyLen)))
	{	
		m_dwStatusTRN = LOGIN_BREAKED;

		if(!m_nHaveTrnLink)
			m_dwStatusRCV = m_dwStatusTRN;

		m_listSubmitBuff.AddTail(struSMPPackage);	
	
		m_nMTCount++;
		ShowStatus(APP_SMPPROTOCOL+STAT_MT_COUNT,m_nMTCount,NULL);
		return -m_dwSequenceNO;
	}	

	m_nMTCount++;

	Sleep(g_n112DelayTime);

	ShowStatus(APP_SMPPROTOCOL+STAT_MT_COUNT,m_nMTCount,NULL);
	return m_dwSequenceNO;
}


int CSMPProtocol::SMPPGetDeliver(CSMPProtocol::struSMPPSUBMIT* struSmppSubmit)
{
	WaitForSingleObject(m_hEventDeliver,INFINITE);
	if(m_listDeliver.IsEmpty())
	{
		SetEvent(m_hEventDeliver);
		return 1;
	}
	
	*struSmppSubmit = m_listDeliver.RemoveHead();
	SetEvent(m_hEventDeliver);

	return 0;
}


int CSMPProtocol::SMPPGetSubmitRep(DWORD* dwSubmitID,DWORD* dwMessageID,DWORD* dwStatus)
{
	WaitForSingleObject(m_hEventSubmitRep,INFINITE);
	if(m_listSubmitRep.IsEmpty())
	{
		SetEvent(m_hEventSubmitRep);
		return 1;
	}

	struSMPPACKAGE struSmppPackage;
	struSmppPackage = m_listSubmitRep.RemoveHead();
	SetEvent(m_hEventSubmitRep);

	*dwSubmitID = struSmppPackage.struHead.dwSequenceNO;
//	*dwMessageID = atol(struSmppPackage.szBody);
	*dwStatus = struSmppPackage.struHead.dwCommandStatus;
	if(*dwStatus ==0)
		*dwMessageID = HexToDec(struSmppPackage.szBody);

	return 0;
}


int CSMPProtocol::SMPPGetStatReport(DWORD* pdwMessageID,DWORD* pdwStatus)
{
	WaitForSingleObject(m_hEventStatReport,INFINITE);
	if(m_listStatReport.IsEmpty())
	{
		SetEvent(m_hEventStatReport);
		return 1;
	}
	
	struSMPPSUBMIT struSmppSubmit;
	struSmppSubmit = m_listStatReport.RemoveHead();
	SetEvent(m_hEventStatReport);

	DealStatReport(struSmppSubmit,pdwMessageID,pdwStatus);

	return 0;
}

int CSMPProtocol::SMPPTestLink()
{
	if(m_nHaveTrnLink)
		SMPPTestLinkTRN();
	if(m_nHaveRcvLink)
		SMPPTestLinkRCV();
	return 0;
}

int CSMPProtocol::SMPPTestLinkRCV()
{
	char szDisMsg[200];

	//ShowStatus(APP_SMPPROTOCOL+STAT_MO_COUNT,m_nMOCount,NULL);
	//ShowStatus(APP_SMPPROTOCOL+STAT_MT_COUNT,m_nMTCount,NULL);
	//ShowStatus(APP_SMPPROTOCOL+STAT_REPORT_COUNT,m_nStatReportCount,NULL);
	
	/*
	sprintf(szDisMsg,"[STATUS]当前序列号是:%d",m_dwSequenceNO);
	Print(szDisMsg);

	sprintf(szDisMsg,"[STATUS]MO总数目:%d || MT总数目:%d",m_nMOCount,m_nMTCount);
	Print(szDisMsg);

	sprintf(szDisMsg,"[STATUS]MT应答总数目:%d",m_nSubmitRespCount);
	Print(szDisMsg);	

	sprintf(szDisMsg,"[STATUS]状态报告总数目:%d",m_nStatReportCount);
	Print(szDisMsg);	

	sprintf(szDisMsg,"[STATUS]MT发送失败缓存队列长度是:%d",m_listSubmitBuff.GetCount());
	Print(szDisMsg);

	WaitForSingleObject(m_hEventDeliver,INFINITE);
	sprintf(szDisMsg,"[STATUS]MO缓存队列长度是:%d",m_listDeliver.GetCount());
	SetEvent(m_hEventDeliver);
	Print(szDisMsg);

	WaitForSingleObject(m_hEventSubmitRep,INFINITE);
	sprintf(szDisMsg,"[STATUS]MT应答缓存队列长度是:%d",m_listSubmitRep.GetCount());
	SetEvent(m_hEventSubmitRep);

	Print(szDisMsg);

	WaitForSingleObject(m_hEventStatReport,INFINITE);
	sprintf(szDisMsg,"[STATUS]状态报告缓存队列长度是:%d",m_listStatReport.GetCount());
	SetEvent(m_hEventStatReport);
	Print(szDisMsg);
	*/

	char szMsg[200];

	sprintf(szMsg,"已发送检测包:%d  已收到检测包:%d",m_nSendLinkCount,m_nRecvLinkCount);
	
	Print(szMsg);

	Print("[TSTLNK][RCV]检测到短信中心的链路...");		

	if(m_dwStatusRCV == NO_LOGIN)
	{
		Print("[TSTLNK][ERROR][RCV]未注册到短信中心!");
		SMPPLogInRCV(m_szSMPPIP,m_nSMPPort,m_struSMPPLogIn);

		return 0;
	}

	long lTimeNow;
	CTimeSpan timespan;

	time(&lTimeNow);
	timespan=lTimeNow - m_nTimeLink_RCV;

	if(timespan.GetTotalSeconds()>(3*m_pcDlg->m_nTestConnInterval/1000))
		m_dwStatusRCV = LOGIN_BREAKED;

	if(m_dwStatusRCV == LOGIN_BREAKED)
	{
		Print("[ERROR][RCV]链路检测超时...重新注册");
		//SMPPLogOut();
		//SMPPLogIn();
		SMPPLogInRCV(m_szSMPPIP,m_nSMPPort,m_struSMPPLogIn);
		return 0;
	}

	Print("[TSTLNK][RCV]链路正常!");
	ShowStatus(APP_SMPPROTOCOL + STAT_SMSC_LINK,1,NULL);

	struSMPPACKAGE struSMPPackage;	

	MakePackage(ESME_QRYLINK,-1,NULL,0,&struSMPPackage);

	m_dwCommandStatus = COMMAND_STATUS_INIT;
	
	if(!m_cSMSCSocketRCV->SMSCSendMsg((char*)&struSMPPackage,16))
	{
		Print("[ERROR][RCV]发送检测链路数据包出错,链路已被对方中断!");
		m_dwStatusRCV = LOGIN_BREAKED;
		return 0;
	}

	m_nSendLinkCount++;

	/*long lTimeStart,lTimeNow;
	time(&lTimeStart);	time(&lTimeNow);

	while(((lTimeNow-lTimeStart) <= TESTLINK_TIMEOUT_SEC)&&(m_dwCommandStatus == COMMAND_STATUS_INIT))
	{
		MSG Msg;
		while(PeekMessage(&Msg,NULL,NULL,NULL,PM_REMOVE)) //单线程能够处理其他消息
		{
			TranslateMessage(&Msg);
			DispatchMessage(&Msg);
		}

		time(&lTimeNow);
	}

	if((m_dwCommandStatus == COMMAND_STATUS_INIT)||(m_dwCommandStatus == 1))
	{
		SMPPLogOutRCV();

		m_dwStatusRCV = LOGIN_BREAKED;
		//ShowStatus(APP_SMPPROTOCOL + STAT_SMSC_LINK,0,NULL);

		Print("[TSTLNK][RCV]链路被中断...重新注册");
		SMPPLogInRCV(m_szSMPPIP,m_nSMPPort,m_struSMPPLogIn);
	}
	else
	{
		Print("[TSTLNK][RCV]链路正常!");
		ShowStatus(APP_SMPPROTOCOL + STAT_SMSC_LINK,1,NULL);
	}*/

	return 0;
}


int CSMPProtocol::SMPPTestLinkTRN()
{
	Print("[TSTLNK][TRN]检测到短信中心的链路...");

	if(m_dwStatusTRN == NO_LOGIN)
	{
		Print("[TSTLNK][ERROR][TRN]未注册到短信中心!");
		SMPPLogInTRN(m_szSMPPIP,m_nSMPPort,m_struSMPPLogIn);
		return -1;
	}

	long lTimeNow;
	CTimeSpan timespan;

	time(&lTimeNow);
	timespan=lTimeNow - m_nTimeLink_TRN;
	
	if(timespan.GetTotalSeconds()>(3*m_pcDlg->m_nTestConnInterval/1000))
		m_dwStatusTRN = LOGIN_BREAKED;

	if(m_dwStatusTRN == LOGIN_BREAKED)
	{
		Print("[ERROR][TRN]链路检测超时...重新注册");
		//SMPPLogOut();
		//SMPPLogIn();
		SMPPLogInTRN(m_szSMPPIP,m_nSMPPort,m_struSMPPLogIn);
		return 0;
	}

	struSMPPACKAGE struSMPPackage;	

	MakePackage(ESME_QRYLINK,-1,NULL,0,&struSMPPackage);

	m_dwCommandStatus = COMMAND_STATUS_INIT;
	
	if(!m_cSMSCSocketTRN->SMSCSendMsg((char*)&struSMPPackage,16))
	{	
		Print("[ERROR][TRN]发送检测链路数据包出错,链路已被对方中断!");
		m_dwStatusTRN = LOGIN_BREAKED;
		return 0;
	}

	Print("[TSTLNK][TRN]链路正常!");
	m_nSendLinkCount++;
	/*
	long lTimeStart,lTimeNow;
	time(&lTimeStart);	time(&lTimeNow);

	while(((lTimeNow-lTimeStart) <= TESTLINK_TIMEOUT_SEC)&&(m_dwCommandStatus == COMMAND_STATUS_INIT))
	{
		MSG Msg;
		while(PeekMessage(&Msg,NULL,NULL,NULL,PM_REMOVE)) //单线程能够处理其他消息

⌨️ 快捷键说明

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