// EsmeTransmitterCom.cpp : Implementation of CEsmeTransmitterCom
#include "stdafx.h"
#include "EsmeTransmitterCom.h"
// CEsmeTransmitterCom
STDMETHODIMP CEsmeTransmitterCom::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);
CEsmeTransmitter::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 CEsmeTransmitterCom::unbind(VARIANT_BOOL* pret)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: Add your implementation code here
EnterCriticalSection(&m_cs); //enter m_cs
ResetEvent(m_response_event);
CEsmeTransmitter::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 CEsmeTransmitterCom::enquireLink(VARIANT_BOOL* pret)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: Add your implementation code here
EnterCriticalSection(&m_cs); //enter m_cs
ResetEvent(m_response_event);
CEsmeTransmitter::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 CEsmeTransmitterCom::init(BSTR svrip, LONG port)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: Add your implementation code here
USES_CONVERSION;
LPSTR sip = OLE2A(svrip);
CEsmeTransmitter::init(sip, port);
return S_OK;
}
STDMETHODIMP CEsmeTransmitterCom::close(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: Add your implementation code here
CEsmeTransmitter::close();
return S_OK;
}
STDMETHODIMP CEsmeTransmitterCom::get_Connected(VARIANT_BOOL* pVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: Add your implementation code here
if (CEsmeTransmitter::isConnected())
{
*pVal = VARIANT_TRUE;
}
else
{
*pVal = VARIANT_FALSE;
}
return S_OK;
}
STDMETHODIMP CEsmeTransmitterCom::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);
CEsmeTransmitter::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 CEsmeTransmitterCom::processPacketProc(CPacketBase *pak, LPVOID param)
{
CEsmeTransmitterCom *pTrans = (CEsmeTransmitterCom *) param;
//route to instance method, so it can access instance attributes
pTrans->processPacket(pak);
}
//actuallly SMPP packets are in turns handled here
void CEsmeTransmitterCom::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_BIND_TRANSMITTER_RESP:
{
//bind transmitter response
CBindTransmitterResp *pPak;
pPak = static_cast<CBindTransmitterResp *>(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;
}
}