www.pudn.com > smpplib.zip > EsmeTransceiverCom.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(®del); 
 
	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(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(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(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(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(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(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); 
 
}