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

📄 esmetransceivercom.cpp

📁 一个短信smpp协议开发包源码
💻 CPP
字号:
// EsmeTransceiverCom.cpp : Implementation of CEsmeTransceiverCom

#include "stdafx.h"
#include "EsmeTransceiverCom.h"


// CEsmeTransceiverCom

STDMETHODIMP CEsmeTransceiverCom::bind(BSTR sysid, BSTR passwd, BSTR systype, ISmppAddressCom* iaddr, VARIANT_BOOL* pret)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// TODO: Add your implementation code here
	USES_CONVERSION;

	LPSTR sid, pwd, stype;

	sid = OLE2A(sysid);
	pwd = OLE2A(passwd);
	stype = OLE2A(systype);

	SHORT npi;
	SHORT ton;
	BSTR addr;

	iaddr->get_NPI(&npi);
	iaddr->get_TON(&ton);
	iaddr->get_Address(&addr);

	LPSTR paddr = OLE2A(addr);
	CSmppAddress srange(ton, npi, paddr);

	SysFreeString(addr);

	//setting finished, going to bind to SMSC

	EnterCriticalSection(&m_cs);				//enter m_cs

	ResetEvent(m_response_event);
	CEsmeTransceiver::bind(sid, pwd, stype, srange);

	HANDLE hwait[] = {m_response_event, m_hDisconnectEvent, m_hKillEvent};

	DWORD ret = WaitForMultipleObjects(3, hwait, FALSE, 30000);

	if (ret == WAIT_OBJECT_0)
	{
		if (m_last_error)
			*pret = VARIANT_FALSE;
		else
			*pret = VARIANT_TRUE;
	}
	else
		*pret = VARIANT_FALSE;

	ResetEvent(m_response_event);

	LeaveCriticalSection(&m_cs);				//leave m_cs

	return S_OK;
}

STDMETHODIMP CEsmeTransceiverCom::unbind(VARIANT_BOOL* pret)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// TODO: Add your implementation code here

	EnterCriticalSection(&m_cs);				//enter m_cs

	ResetEvent(m_response_event);
	CEsmeTransceiver::unbind();

	HANDLE hwait[] = {m_response_event, m_hDisconnectEvent, m_hKillEvent};

	DWORD ret = WaitForMultipleObjects(3, hwait, FALSE, 30000);

	if (ret == WAIT_OBJECT_0)
	{
		if (m_last_error)
			*pret = VARIANT_FALSE;
		else
			*pret = VARIANT_TRUE;
	}
	else
		*pret = VARIANT_FALSE;

	ResetEvent(m_response_event);

	LeaveCriticalSection(&m_cs);				//leave m_cs

	return S_OK;
}

STDMETHODIMP CEsmeTransceiverCom::enquireLink(VARIANT_BOOL* pret)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// TODO: Add your implementation code here

	EnterCriticalSection(&m_cs);				//enter m_cs

	ResetEvent(m_response_event);
	CEsmeTransceiver::enquireLink();

	HANDLE hwait[] = {m_response_event, m_hDisconnectEvent, m_hKillEvent};

	DWORD ret = WaitForMultipleObjects(3, hwait, FALSE, 30000);

	if (ret == WAIT_OBJECT_0)
	{
		if (m_last_error)
			*pret = VARIANT_FALSE;
		else
			*pret = VARIANT_TRUE;
	}
	else
		*pret = VARIANT_FALSE;

	ResetEvent(m_response_event);

	LeaveCriticalSection(&m_cs);				//leave m_cs

	return S_OK;
}

STDMETHODIMP CEsmeTransceiverCom::init(BSTR svrip, LONG port)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// TODO: Add your implementation code here

	USES_CONVERSION;

	LPSTR sip = OLE2A(svrip);

	CEsmeTransceiver::init(sip, port);

	return S_OK;
}

STDMETHODIMP CEsmeTransceiverCom::close(void)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// TODO: Add your implementation code here
	CEsmeTransceiver::close();

	return S_OK;
}

STDMETHODIMP CEsmeTransceiverCom::get_Connected(VARIANT_BOOL* pVal)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// TODO: Add your implementation code here

	if (CEsmeTransceiver::isConnected())
	{
		*pVal = VARIANT_TRUE;
	}
	else
	{
		*pVal = VARIANT_FALSE;
	}

	return S_OK;
}

STDMETHODIMP CEsmeTransceiverCom::submitMessage(ISubmitSMCom* isubmit, BSTR* pMsgid, VARIANT_BOOL* pret)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// TODO: Add your implementation code here
	CSubmitSM sm;

	USES_CONVERSION;

	BSTR svrtype;
	isubmit->get_ServiceType(&svrtype);
	LPSTR stype = OLE2A(svrtype);

	sm.setServiceType(stype);

	SHORT dc, esm, repif, priflag, proid, defmsg, regdel;
	
	isubmit->get_dataCoding(&dc);
	isubmit->get_esmClass(&esm);
	isubmit->get_replaceIfPresent(&repif);
	isubmit->get_priorityFlag(&priflag);
	isubmit->get_protocolID(&proid);
	isubmit->get_smDefaultMsgId(&defmsg);
	isubmit->get_registeredDelivery(&regdel);

	sm.setDataCoding(dc);
	sm.setEsmClass(esm);
	sm.setReplaceIfPresent(repif);
	sm.setPriorityFlag(priflag);
	sm.setProtocolId(proid);
	sm.setSmDefaultMsgId(defmsg);
	sm.setRegisteredDelivery(regdel);

	SHORT ton, npi;
	BSTR addr;

	ISmppAddressCom *iaddr;

	//getting source
	isubmit->get_Source(&iaddr);
	iaddr->get_TON(&ton);
	iaddr->get_NPI(&npi);
	iaddr->get_Address(&addr);
	iaddr->Release();

	LPSTR paddr = OLE2A(addr);
	SysFreeString(addr);

	CSmppAddress src(ton, npi, paddr);

	//getting destination
	isubmit->get_Destination(&iaddr);
	iaddr->get_TON(&ton);
	iaddr->get_NPI(&npi);
	iaddr->get_Address(&addr);
	iaddr->Release();

	paddr = OLE2A(addr);
	SysFreeString(addr);

	CSmppAddress dst(ton, npi, paddr);

	//assing source and destination
	sm.setSource(src);
	sm.setDestination(dst);

	ISmppDateCom *idate;
	BSTR strdate;

	//getting ScheduledDelivery
	isubmit->get_scheduledDelivery(&idate);
	idate->toString(&strdate);
	LPSTR sdt = OLE2A(strdate);
	idate->Release();

	CSmppDate schdel;
	schdel.setDate(sdt);

	//getting ValidityPeriod
	isubmit->get_validityPeriod(&idate);
	idate->toString(&strdate);
	sdt = OLE2A(strdate);
	idate->Release();

	CSmppDate valprd;
	valprd.setDate(sdt);

	//assign scheduledDelivery and validityPeriod to sm
	sm.setScheduledDelivery(schdel);
	sm.setValidityPeriod(valprd);

	VARIANT var;
	isubmit->getMessage(&var);
	SAFEARRAY *psa = var.parray;
	BYTE *padata;

	int nsize = psa->rgsabound->cElements;
	SafeArrayAccessData(psa, (void **) &padata);
	sm.setMessage(padata, nsize);
	SafeArrayUnaccessData(psa);


	//
	//okay, we've setting up the SubmitSM, send it
	//

	EnterCriticalSection(&m_cs);				//enter m_cs

	ResetEvent(m_response_event);
	CEsmeTransceiver::submitMessage(sm);

	HANDLE hwait[] = {m_response_event, m_hDisconnectEvent, m_hKillEvent};

	DWORD ret = WaitForMultipleObjects(3, hwait, FALSE, 30000);

	if (ret == WAIT_OBJECT_0)
	{
		if (m_last_error)
			*pret = VARIANT_FALSE;
		else
		{
			*pret = VARIANT_TRUE;
			*pMsgid = m_last_msg_id.AllocSysString();
		}
	}
	else
		*pret = VARIANT_FALSE;

	ResetEvent(m_response_event);

	LeaveCriticalSection(&m_cs);				//leave m_cs

	return S_OK;
}

//registered callback to handle SMPP packets sent from SMSC
//(must be static class method or global procedure)
void __stdcall CEsmeTransceiverCom::processPacketProc(CPacketBase *pak, LPVOID param)
{
	CEsmeTransceiverCom *pTrans = (CEsmeTransceiverCom *) param;

	//route to instance method, so it can access instance attributes
	pTrans->processPacket(pak);
}


//actuallly SMPP packets are in turns handled here 
void CEsmeTransceiverCom::processPacket(CPacketBase *pak)
{

		switch (pak->getCommandId())
		{


			case SMPP_ENQUIRE_LINK:
			{
				//SMSC requested us to send querylink response

				CEnquireLink *pPak;
				pPak = static_cast<CEnquireLink *>(pak);

				//automatic reponse for enquery link
				CEnquireLinkResp elresp(*pPak);
				sendPacket(elresp);
				
			}
			break;

			case SMPP_DELIVER_SM:
			{
				//got a deliver SM
				CDeliverSM *pPak;
				pPak = static_cast<CDeliverSM *>(pak);

				//automatic response deliversm reponse
				CDeliverSMResp dresp (*pPak);
				sendPacket(dresp);

				//notify client for the deliver SM
				NotifyClientDeliverSM(pPak);
			}
			break;

			case SMPP_BIND_TRANSCEIVER_RESP:
			{
				//bind transceiver response

				CBindTransceiverResp *pPak;
				pPak = static_cast<CBindTransceiverResp *>(pak);

				if (pPak->getCommandStatus() == 0)
				{
					m_last_error = false;
				}
				else
				{
					m_last_error = true;
				}
				SetEvent(m_response_event);
			}
			break;

			
			case SMPP_UNBIND_RESP:
			{
				//unbind response

				CUnbindResp *pPak;
				pPak = static_cast<CUnbindResp *>(pak);

				if (pPak->getCommandStatus() == 0)
				{
					m_last_error = false;
				}
				else
				{
					m_last_error = true;
				}
				SetEvent(m_response_event);
			}
			break;


			case SMPP_SUBMIT_SM_RESP:
			{
				//Submit Short Message Response

				CSubmitSMResp *pPak;
				pPak = static_cast<CSubmitSMResp *>(pak);

				if (pPak->getCommandStatus() == 0)
				{
					m_last_msg_id = pPak->getMessageId();
					m_last_error = false;
				}
				else
				{
					m_last_error = true;
				}
				SetEvent(m_response_event);
			}
			break;


			case SMPP_ENQUIRE_LINK_RESP:
			{
				//Previous EnquireLink is responsed

				CEnquireLinkResp *pPak;
				pPak = static_cast<CEnquireLinkResp *>(pak);

				if (pPak->getCommandStatus() == 0)
				{
					m_last_error = false;
					SetEvent(m_response_event);
				}
				else
				{
					m_last_error = true;
				}
				SetEvent(m_response_event);
			}
			break;


			default:
				break;
		}
}

void CEsmeTransceiverCom::NotifyClientDeliverSM(CDeliverSM *pak)
{
	IDeliverSMCom *pVal;

	//create an CDeliverSMCom instance to return
	CoCreateInstance(	CLSID_DeliverSMCom,
						NULL,
						CLSCTX_ALL,
						IID_IDeliverSMCom,
						(void **) &pVal);

	USES_CONVERSION;

	pVal->put_dataCoding(pak->getDataCoding());
	pVal->put_esmClass(pak->getEsmClass());
	pVal->put_replaceIfPresent(pak->getReplaceIfPresent());
	pVal->put_priorityFlag(pak->getPriorityFlag());
	pVal->put_protocolID(pak->getProtocolId());
	pVal->put_smDefaultMsgId(pak->getSmDefaultMsgId());
	pVal->put_registeredDelivery(pak->getRegisteredDelivery());


	//create an CSmppAddressCom for setting addresses
	ISmppAddressCom *iaddr;
	CoCreateInstance(	CLSID_SmppAddressCom,
						NULL,
						CLSCTX_ALL,
						IID_ISmppAddressCom,
						(void **) &iaddr);

	BSTR addrstr;

	//Setting source
	CSmppAddress source = pak->getSource();
	iaddr->put_TON(source.m_addr_ton);
	iaddr->put_NPI(source.m_addr_npi);
	addrstr = source.m_addr.AllocSysString();
	iaddr->put_Address(addrstr);
	SysFreeString(addrstr);

	pVal->put_Source(iaddr);

	//Setting Destination
	CSmppAddress destination = pak->getDestination();
	iaddr->put_TON(destination.m_addr_ton);
	iaddr->put_NPI(destination.m_addr_npi);
	addrstr = destination.m_addr.AllocSysString();
	iaddr->put_Address(addrstr);
	SysFreeString(addrstr);

	pVal->put_Destination(iaddr);

	iaddr->Release();


	//create an CSmppDate for setting dates
	ISmppDateCom *idate;
	CoCreateInstance(	CLSID_SmppDateCom,
						NULL,
						CLSCTX_ALL,
						IID_ISmppDateCom,
						(void **) &idate);
	
	BSTR strdate;

	//setting scheduleddelivery
	CSmppDate schdate = pak->getScheduledDelivery();
	strdate = schdate.toString().AllocSysString();
	idate->setDate(strdate);
	pVal->put_scheduledDelivery(idate);
	SysFreeString(strdate);

	//setting validityperiod
	CSmppDate vldprd = pak->getValidityPeriod();
	strdate = vldprd.toString().AllocSysString();
	idate->setDate(strdate);
	pVal->put_validityPeriod(idate);
	SysFreeString(strdate);

	idate->Release();

	//setting message
	PBYTE pdata;
	uint32 nsize;
	pak->getMessage(pdata, nsize);

	VARIANT var;

	VariantInit(&var);
	var.vt = VT_ARRAY | VT_UI1;
	SAFEARRAY *psa;
	SAFEARRAYBOUND bounds = {nsize, 0};
	psa = SafeArrayCreate(VT_UI1, 1, &bounds);
	BYTE *padata;
	SafeArrayAccessData(psa, (void **) &padata);
	memcpy(padata, pdata, nsize);
	SafeArrayUnaccessData(psa);
	var.parray = psa;

	pVal->setMessage(var);

	//fire notification event
	Fire_OnDeliverSM(pVal);

}

⌨️ 快捷键说明

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