EsmeTransceiverCom.cpp
上传用户:hkcoast
上传日期:2007-01-12
资源大小:979k
文件大小:11k
源码类别:

手机短信编程

开发平台:

Visual C++

  1. // EsmeTransceiverCom.cpp : Implementation of CEsmeTransceiverCom
  2. #include "stdafx.h"
  3. #include "EsmeTransceiverCom.h"
  4. // CEsmeTransceiverCom
  5. STDMETHODIMP CEsmeTransceiverCom::bind(BSTR sysid, BSTR passwd, BSTR systype, ISmppAddressCom* iaddr, VARIANT_BOOL* pret)
  6. {
  7. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  8. // TODO: Add your implementation code here
  9. USES_CONVERSION;
  10. LPSTR sid, pwd, stype;
  11. sid = OLE2A(sysid);
  12. pwd = OLE2A(passwd);
  13. stype = OLE2A(systype);
  14. SHORT npi;
  15. SHORT ton;
  16. BSTR addr;
  17. iaddr->get_NPI(&npi);
  18. iaddr->get_TON(&ton);
  19. iaddr->get_Address(&addr);
  20. LPSTR paddr = OLE2A(addr);
  21. CSmppAddress srange(ton, npi, paddr);
  22. SysFreeString(addr);
  23. //setting finished, going to bind to SMSC
  24. EnterCriticalSection(&m_cs); //enter m_cs
  25. ResetEvent(m_response_event);
  26. CEsmeTransceiver::bind(sid, pwd, stype, srange);
  27. HANDLE hwait[] = {m_response_event, m_hDisconnectEvent, m_hKillEvent};
  28. DWORD ret = WaitForMultipleObjects(3, hwait, FALSE, 30000);
  29. if (ret == WAIT_OBJECT_0)
  30. {
  31. if (m_last_error)
  32. *pret = VARIANT_FALSE;
  33. else
  34. *pret = VARIANT_TRUE;
  35. }
  36. else
  37. *pret = VARIANT_FALSE;
  38. ResetEvent(m_response_event);
  39. LeaveCriticalSection(&m_cs); //leave m_cs
  40. return S_OK;
  41. }
  42. STDMETHODIMP CEsmeTransceiverCom::unbind(VARIANT_BOOL* pret)
  43. {
  44. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  45. // TODO: Add your implementation code here
  46. EnterCriticalSection(&m_cs); //enter m_cs
  47. ResetEvent(m_response_event);
  48. CEsmeTransceiver::unbind();
  49. HANDLE hwait[] = {m_response_event, m_hDisconnectEvent, m_hKillEvent};
  50. DWORD ret = WaitForMultipleObjects(3, hwait, FALSE, 30000);
  51. if (ret == WAIT_OBJECT_0)
  52. {
  53. if (m_last_error)
  54. *pret = VARIANT_FALSE;
  55. else
  56. *pret = VARIANT_TRUE;
  57. }
  58. else
  59. *pret = VARIANT_FALSE;
  60. ResetEvent(m_response_event);
  61. LeaveCriticalSection(&m_cs); //leave m_cs
  62. return S_OK;
  63. }
  64. STDMETHODIMP CEsmeTransceiverCom::enquireLink(VARIANT_BOOL* pret)
  65. {
  66. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  67. // TODO: Add your implementation code here
  68. EnterCriticalSection(&m_cs); //enter m_cs
  69. ResetEvent(m_response_event);
  70. CEsmeTransceiver::enquireLink();
  71. HANDLE hwait[] = {m_response_event, m_hDisconnectEvent, m_hKillEvent};
  72. DWORD ret = WaitForMultipleObjects(3, hwait, FALSE, 30000);
  73. if (ret == WAIT_OBJECT_0)
  74. {
  75. if (m_last_error)
  76. *pret = VARIANT_FALSE;
  77. else
  78. *pret = VARIANT_TRUE;
  79. }
  80. else
  81. *pret = VARIANT_FALSE;
  82. ResetEvent(m_response_event);
  83. LeaveCriticalSection(&m_cs); //leave m_cs
  84. return S_OK;
  85. }
  86. STDMETHODIMP CEsmeTransceiverCom::init(BSTR svrip, LONG port)
  87. {
  88. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  89. // TODO: Add your implementation code here
  90. USES_CONVERSION;
  91. LPSTR sip = OLE2A(svrip);
  92. CEsmeTransceiver::init(sip, port);
  93. return S_OK;
  94. }
  95. STDMETHODIMP CEsmeTransceiverCom::close(void)
  96. {
  97. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  98. // TODO: Add your implementation code here
  99. CEsmeTransceiver::close();
  100. return S_OK;
  101. }
  102. STDMETHODIMP CEsmeTransceiverCom::get_Connected(VARIANT_BOOL* pVal)
  103. {
  104. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  105. // TODO: Add your implementation code here
  106. if (CEsmeTransceiver::isConnected())
  107. {
  108. *pVal = VARIANT_TRUE;
  109. }
  110. else
  111. {
  112. *pVal = VARIANT_FALSE;
  113. }
  114. return S_OK;
  115. }
  116. STDMETHODIMP CEsmeTransceiverCom::submitMessage(ISubmitSMCom* isubmit, BSTR* pMsgid, VARIANT_BOOL* pret)
  117. {
  118. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  119. // TODO: Add your implementation code here
  120. CSubmitSM sm;
  121. USES_CONVERSION;
  122. BSTR svrtype;
  123. isubmit->get_ServiceType(&svrtype);
  124. LPSTR stype = OLE2A(svrtype);
  125. sm.setServiceType(stype);
  126. SHORT dc, esm, repif, priflag, proid, defmsg, regdel;
  127. isubmit->get_dataCoding(&dc);
  128. isubmit->get_esmClass(&esm);
  129. isubmit->get_replaceIfPresent(&repif);
  130. isubmit->get_priorityFlag(&priflag);
  131. isubmit->get_protocolID(&proid);
  132. isubmit->get_smDefaultMsgId(&defmsg);
  133. isubmit->get_registeredDelivery(&regdel);
  134. sm.setDataCoding(dc);
  135. sm.setEsmClass(esm);
  136. sm.setReplaceIfPresent(repif);
  137. sm.setPriorityFlag(priflag);
  138. sm.setProtocolId(proid);
  139. sm.setSmDefaultMsgId(defmsg);
  140. sm.setRegisteredDelivery(regdel);
  141. SHORT ton, npi;
  142. BSTR addr;
  143. ISmppAddressCom *iaddr;
  144. //getting source
  145. isubmit->get_Source(&iaddr);
  146. iaddr->get_TON(&ton);
  147. iaddr->get_NPI(&npi);
  148. iaddr->get_Address(&addr);
  149. iaddr->Release();
  150. LPSTR paddr = OLE2A(addr);
  151. SysFreeString(addr);
  152. CSmppAddress src(ton, npi, paddr);
  153. //getting destination
  154. isubmit->get_Destination(&iaddr);
  155. iaddr->get_TON(&ton);
  156. iaddr->get_NPI(&npi);
  157. iaddr->get_Address(&addr);
  158. iaddr->Release();
  159. paddr = OLE2A(addr);
  160. SysFreeString(addr);
  161. CSmppAddress dst(ton, npi, paddr);
  162. //assing source and destination
  163. sm.setSource(src);
  164. sm.setDestination(dst);
  165. ISmppDateCom *idate;
  166. BSTR strdate;
  167. //getting ScheduledDelivery
  168. isubmit->get_scheduledDelivery(&idate);
  169. idate->toString(&strdate);
  170. LPSTR sdt = OLE2A(strdate);
  171. idate->Release();
  172. CSmppDate schdel;
  173. schdel.setDate(sdt);
  174. //getting ValidityPeriod
  175. isubmit->get_validityPeriod(&idate);
  176. idate->toString(&strdate);
  177. sdt = OLE2A(strdate);
  178. idate->Release();
  179. CSmppDate valprd;
  180. valprd.setDate(sdt);
  181. //assign scheduledDelivery and validityPeriod to sm
  182. sm.setScheduledDelivery(schdel);
  183. sm.setValidityPeriod(valprd);
  184. VARIANT var;
  185. isubmit->getMessage(&var);
  186. SAFEARRAY *psa = var.parray;
  187. BYTE *padata;
  188. int nsize = psa->rgsabound->cElements;
  189. SafeArrayAccessData(psa, (void **) &padata);
  190. sm.setMessage(padata, nsize);
  191. SafeArrayUnaccessData(psa);
  192. //
  193. //okay, we've setting up the SubmitSM, send it
  194. //
  195. EnterCriticalSection(&m_cs); //enter m_cs
  196. ResetEvent(m_response_event);
  197. CEsmeTransceiver::submitMessage(sm);
  198. HANDLE hwait[] = {m_response_event, m_hDisconnectEvent, m_hKillEvent};
  199. DWORD ret = WaitForMultipleObjects(3, hwait, FALSE, 30000);
  200. if (ret == WAIT_OBJECT_0)
  201. {
  202. if (m_last_error)
  203. *pret = VARIANT_FALSE;
  204. else
  205. {
  206. *pret = VARIANT_TRUE;
  207. *pMsgid = m_last_msg_id.AllocSysString();
  208. }
  209. }
  210. else
  211. *pret = VARIANT_FALSE;
  212. ResetEvent(m_response_event);
  213. LeaveCriticalSection(&m_cs); //leave m_cs
  214. return S_OK;
  215. }
  216. //registered callback to handle SMPP packets sent from SMSC
  217. //(must be static class method or global procedure)
  218. void __stdcall CEsmeTransceiverCom::processPacketProc(CPacketBase *pak, LPVOID param)
  219. {
  220. CEsmeTransceiverCom *pTrans = (CEsmeTransceiverCom *) param;
  221. //route to instance method, so it can access instance attributes
  222. pTrans->processPacket(pak);
  223. }
  224. //actuallly SMPP packets are in turns handled here 
  225. void CEsmeTransceiverCom::processPacket(CPacketBase *pak)
  226. {
  227. switch (pak->getCommandId())
  228. {
  229. case SMPP_ENQUIRE_LINK:
  230. {
  231. //SMSC requested us to send querylink response
  232. CEnquireLink *pPak;
  233. pPak = static_cast<CEnquireLink *>(pak);
  234. //automatic reponse for enquery link
  235. CEnquireLinkResp elresp(*pPak);
  236. sendPacket(elresp);
  237. }
  238. break;
  239. case SMPP_DELIVER_SM:
  240. {
  241. //got a deliver SM
  242. CDeliverSM *pPak;
  243. pPak = static_cast<CDeliverSM *>(pak);
  244. //automatic response deliversm reponse
  245. CDeliverSMResp dresp (*pPak);
  246. sendPacket(dresp);
  247. //notify client for the deliver SM
  248. NotifyClientDeliverSM(pPak);
  249. }
  250. break;
  251. case SMPP_BIND_TRANSCEIVER_RESP:
  252. {
  253. //bind transceiver response
  254. CBindTransceiverResp *pPak;
  255. pPak = static_cast<CBindTransceiverResp *>(pak);
  256. if (pPak->getCommandStatus() == 0)
  257. {
  258. m_last_error = false;
  259. }
  260. else
  261. {
  262. m_last_error = true;
  263. }
  264. SetEvent(m_response_event);
  265. }
  266. break;
  267. case SMPP_UNBIND_RESP:
  268. {
  269. //unbind response
  270. CUnbindResp *pPak;
  271. pPak = static_cast<CUnbindResp *>(pak);
  272. if (pPak->getCommandStatus() == 0)
  273. {
  274. m_last_error = false;
  275. }
  276. else
  277. {
  278. m_last_error = true;
  279. }
  280. SetEvent(m_response_event);
  281. }
  282. break;
  283. case SMPP_SUBMIT_SM_RESP:
  284. {
  285. //Submit Short Message Response
  286. CSubmitSMResp *pPak;
  287. pPak = static_cast<CSubmitSMResp *>(pak);
  288. if (pPak->getCommandStatus() == 0)
  289. {
  290. m_last_msg_id = pPak->getMessageId();
  291. m_last_error = false;
  292. }
  293. else
  294. {
  295. m_last_error = true;
  296. }
  297. SetEvent(m_response_event);
  298. }
  299. break;
  300. case SMPP_ENQUIRE_LINK_RESP:
  301. {
  302. //Previous EnquireLink is responsed
  303. CEnquireLinkResp *pPak;
  304. pPak = static_cast<CEnquireLinkResp *>(pak);
  305. if (pPak->getCommandStatus() == 0)
  306. {
  307. m_last_error = false;
  308. SetEvent(m_response_event);
  309. }
  310. else
  311. {
  312. m_last_error = true;
  313. }
  314. SetEvent(m_response_event);
  315. }
  316. break;
  317. default:
  318. break;
  319. }
  320. }
  321. void CEsmeTransceiverCom::NotifyClientDeliverSM(CDeliverSM *pak)
  322. {
  323. IDeliverSMCom *pVal;
  324. //create an CDeliverSMCom instance to return
  325. CoCreateInstance( CLSID_DeliverSMCom,
  326. NULL,
  327. CLSCTX_ALL,
  328. IID_IDeliverSMCom,
  329. (void **) &pVal);
  330. USES_CONVERSION;
  331. pVal->put_dataCoding(pak->getDataCoding());
  332. pVal->put_esmClass(pak->getEsmClass());
  333. pVal->put_replaceIfPresent(pak->getReplaceIfPresent());
  334. pVal->put_priorityFlag(pak->getPriorityFlag());
  335. pVal->put_protocolID(pak->getProtocolId());
  336. pVal->put_smDefaultMsgId(pak->getSmDefaultMsgId());
  337. pVal->put_registeredDelivery(pak->getRegisteredDelivery());
  338. //create an CSmppAddressCom for setting addresses
  339. ISmppAddressCom *iaddr;
  340. CoCreateInstance( CLSID_SmppAddressCom,
  341. NULL,
  342. CLSCTX_ALL,
  343. IID_ISmppAddressCom,
  344. (void **) &iaddr);
  345. BSTR addrstr;
  346. //Setting source
  347. CSmppAddress source = pak->getSource();
  348. iaddr->put_TON(source.m_addr_ton);
  349. iaddr->put_NPI(source.m_addr_npi);
  350. addrstr = source.m_addr.AllocSysString();
  351. iaddr->put_Address(addrstr);
  352. SysFreeString(addrstr);
  353. pVal->put_Source(iaddr);
  354. //Setting Destination
  355. CSmppAddress destination = pak->getDestination();
  356. iaddr->put_TON(destination.m_addr_ton);
  357. iaddr->put_NPI(destination.m_addr_npi);
  358. addrstr = destination.m_addr.AllocSysString();
  359. iaddr->put_Address(addrstr);
  360. SysFreeString(addrstr);
  361. pVal->put_Destination(iaddr);
  362. iaddr->Release();
  363. //create an CSmppDate for setting dates
  364. ISmppDateCom *idate;
  365. CoCreateInstance( CLSID_SmppDateCom,
  366. NULL,
  367. CLSCTX_ALL,
  368. IID_ISmppDateCom,
  369. (void **) &idate);
  370. BSTR strdate;
  371. //setting scheduleddelivery
  372. CSmppDate schdate = pak->getScheduledDelivery();
  373. strdate = schdate.toString().AllocSysString();
  374. idate->setDate(strdate);
  375. pVal->put_scheduledDelivery(idate);
  376. SysFreeString(strdate);
  377. //setting validityperiod
  378. CSmppDate vldprd = pak->getValidityPeriod();
  379. strdate = vldprd.toString().AllocSysString();
  380. idate->setDate(strdate);
  381. pVal->put_validityPeriod(idate);
  382. SysFreeString(strdate);
  383. idate->Release();
  384. //setting message
  385. PBYTE pdata;
  386. uint32 nsize;
  387. pak->getMessage(pdata, nsize);
  388. VARIANT var;
  389. VariantInit(&var);
  390. var.vt = VT_ARRAY | VT_UI1;
  391. SAFEARRAY *psa;
  392. SAFEARRAYBOUND bounds = {nsize, 0};
  393. psa = SafeArrayCreate(VT_UI1, 1, &bounds);
  394. BYTE *padata;
  395. SafeArrayAccessData(psa, (void **) &padata);
  396. memcpy(padata, pdata, nsize);
  397. SafeArrayUnaccessData(psa);
  398. var.parray = psa;
  399. pVal->setMessage(var);
  400. //fire notification event
  401. Fire_OnDeliverSM(pVal);
  402. }