Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3097 lines
98 KiB

  1. /****************************************************************************
  2. *
  3. * $Archive: S:/STURGEON/SRC/Q931/VCS/q931.c_v $
  4. *
  5. * INTEL Corporation Prorietary Information
  6. *
  7. * This listing is supplied under the terms of a license agreement
  8. * with INTEL Corporation and may not be copied nor disclosed except
  9. * in accordance with the terms of that agreement.
  10. *
  11. * Copyright (c) 1993-1996 Intel Corporation.
  12. *
  13. * $Revision: 1.122 $
  14. * $Date: 04 Mar 1997 20:59:26 $
  15. * $Author: MANDREWS $
  16. *
  17. * BCL's revision info:
  18. * Revision: 1.99
  19. * Date: 19 Nov 1996 14:54:02
  20. * Author: rodellx
  21. *
  22. * Deliverable:
  23. *
  24. * Abstract:
  25. *
  26. *
  27. * Notes:
  28. *
  29. ***************************************************************************/
  30. // [ ] Add facility ie to FACILITY MSG.
  31. // [ ] Read Q931 Appendix D.
  32. #pragma warning ( disable : 4057 4100 4115 4201 4214 4514 )
  33. #include "precomp.h"
  34. #ifdef __cplusplus
  35. extern "C" {
  36. #endif
  37. #include <string.h>
  38. #include <stdio.h>
  39. #include <rpc.h>
  40. #include "apierror.h"
  41. #include "isrg.h"
  42. #include "incommon.h"
  43. #include "linkapi.h"
  44. #include "common.h"
  45. #include "q931.h"
  46. #include "utils.h"
  47. #include "hlisten.h"
  48. #include "hcall.h"
  49. #include "q931pdu.h"
  50. #if (defined(_DEBUG) || defined(PCS_COMPLIANCE))
  51. #include "interop.h"
  52. #include "q931plog.h"
  53. LPInteropLogger Q931Logger;
  54. #endif
  55. #define RECEIVE_BUFFER_SIZE 0x2000
  56. #define HANGUP_TIMEOUT 1000 // 1 second
  57. #define CANCEL_LISTEN_TIMEOUT 5000 // 5 seconds
  58. // variable needed to support ISR debug facility.
  59. #if (ISRDEBUGINFO >= 1)
  60. WORD ghISRInst = 0;
  61. #endif
  62. #ifdef UNICODE_TRACE
  63. // We include this header to fix problems with macro expansion when Unicode is turned on.
  64. #include "unifix.h"
  65. #endif
  66. #define _Unicode(x) L ## x
  67. #define Unicode(x) _Unicode(x)
  68. // global data used by WinSock.
  69. static BOOL bQ931Initialized = FALSE;
  70. static Q931_RECEIVE_PDU_CALLBACK gReceivePDUHookProc = NULL;
  71. static struct
  72. {
  73. DWORD TempID;
  74. CC_CONFERENCEID ConferenceID;
  75. CRITICAL_SECTION Lock;
  76. } ConferenceIDSource;
  77. extern VOID Q931PduInit();
  78. //====================================================================================
  79. //
  80. // PRIVATE FUNCTIONS
  81. //
  82. //====================================================================================
  83. //====================================================================================
  84. //====================================================================================
  85. void _FreeSetupASN(Q931_SETUP_ASN *pSetupASN)
  86. {
  87. ASSERT(pSetupASN != NULL);
  88. // Cleanup any dynamically allocated fields within SetupASN
  89. if (pSetupASN->NonStandardData.sData.pOctetString)
  90. {
  91. MemFree(pSetupASN->NonStandardData.sData.pOctetString);
  92. pSetupASN->NonStandardData.sData.pOctetString = NULL;
  93. }
  94. if (pSetupASN->VendorInfo.pProductNumber)
  95. {
  96. MemFree(pSetupASN->VendorInfo.pProductNumber);
  97. pSetupASN->VendorInfo.pProductNumber = NULL;
  98. }
  99. if (pSetupASN->VendorInfo.pVersionNumber)
  100. {
  101. MemFree(pSetupASN->VendorInfo.pVersionNumber);
  102. pSetupASN->VendorInfo.pVersionNumber = NULL;
  103. }
  104. Q931FreeAliasNames(pSetupASN->pCallerAliasList);
  105. pSetupASN->pCallerAliasList = NULL;
  106. Q931FreeAliasNames(pSetupASN->pCalleeAliasList);
  107. pSetupASN->pCalleeAliasList = NULL;
  108. Q931FreeAliasNames(pSetupASN->pExtraAliasList);
  109. pSetupASN->pExtraAliasList = NULL;
  110. Q931FreeAliasItem(pSetupASN->pExtensionAliasItem);
  111. pSetupASN->pExtensionAliasItem = NULL;
  112. }
  113. void _FreeReleaseCompleteASN(Q931_RELEASE_COMPLETE_ASN *pReleaseCompleteASN)
  114. {
  115. ASSERT(pReleaseCompleteASN != NULL);
  116. // Cleanup any dynamically allocated fields within SetupASN
  117. if (pReleaseCompleteASN->NonStandardData.sData.pOctetString)
  118. {
  119. MemFree(pReleaseCompleteASN->NonStandardData.sData.pOctetString);
  120. pReleaseCompleteASN->NonStandardData.sData.pOctetString = NULL;
  121. }
  122. }
  123. void _FreeFacilityASN(Q931_FACILITY_ASN *pFacilityASN)
  124. {
  125. ASSERT(pFacilityASN != NULL);
  126. // Cleanup any dynamically allocated fields within SetupASN
  127. if (pFacilityASN->NonStandardData.sData.pOctetString)
  128. {
  129. MemFree(pFacilityASN->NonStandardData.sData.pOctetString);
  130. pFacilityASN->NonStandardData.sData.pOctetString = NULL;
  131. }
  132. }
  133. void _FreeProceedingASN(Q931_CALL_PROCEEDING_ASN *pProceedingASN)
  134. {
  135. ASSERT(pProceedingASN != NULL);
  136. // Cleanup any dynamically allocated fields within SetupASN
  137. if (pProceedingASN->NonStandardData.sData.pOctetString)
  138. {
  139. MemFree(pProceedingASN->NonStandardData.sData.pOctetString);
  140. pProceedingASN->NonStandardData.sData.pOctetString = NULL;
  141. }
  142. }
  143. void _FreeAlertingASN(Q931_ALERTING_ASN *pAlertingASN)
  144. {
  145. ASSERT(pAlertingASN != NULL);
  146. // Cleanup any dynamically allocated fields within SetupASN
  147. if (pAlertingASN->NonStandardData.sData.pOctetString)
  148. {
  149. MemFree(pAlertingASN->NonStandardData.sData.pOctetString);
  150. pAlertingASN->NonStandardData.sData.pOctetString = NULL;
  151. }
  152. }
  153. void _FreeConnectASN(Q931_CONNECT_ASN *pConnectASN)
  154. {
  155. ASSERT(pConnectASN != NULL);
  156. // Cleanup any dynamically allocated fields within SetupASN
  157. if (pConnectASN->NonStandardData.sData.pOctetString)
  158. {
  159. MemFree(pConnectASN->NonStandardData.sData.pOctetString);
  160. pConnectASN->NonStandardData.sData.pOctetString = NULL;
  161. }
  162. if (pConnectASN->VendorInfo.pProductNumber)
  163. {
  164. MemFree(pConnectASN->VendorInfo.pProductNumber);
  165. pConnectASN->VendorInfo.pProductNumber = NULL;
  166. }
  167. if (pConnectASN->VendorInfo.pVersionNumber)
  168. {
  169. MemFree(pConnectASN->VendorInfo.pVersionNumber);
  170. pConnectASN->VendorInfo.pVersionNumber = NULL;
  171. }
  172. }
  173. void
  174. _ConferenceIDNew(
  175. CC_CONFERENCEID *pConferenceID)
  176. {
  177. UUID id;
  178. int iresult;
  179. EnterCriticalSection(&(ConferenceIDSource.Lock));
  180. memset(ConferenceIDSource.ConferenceID.buffer, 0,
  181. sizeof(ConferenceIDSource.ConferenceID.buffer));
  182. iresult = UuidCreate(&id);
  183. if ((iresult == RPC_S_OK) || (iresult ==RPC_S_UUID_LOCAL_ONLY))
  184. {
  185. memcpy(ConferenceIDSource.ConferenceID.buffer, &id,
  186. min(sizeof(ConferenceIDSource.ConferenceID.buffer), sizeof(UUID)));
  187. }
  188. else
  189. ASSERT(0);
  190. memcpy(pConferenceID->buffer, ConferenceIDSource.ConferenceID.buffer,
  191. sizeof(pConferenceID->buffer));
  192. LeaveCriticalSection(&(ConferenceIDSource.Lock));
  193. return;
  194. }
  195. //====================================================================================
  196. // This function is used internally whenever a function needs to send a PDU.
  197. // Note that before a datalinkSendRequest() is done, the call object is unlocked
  198. // and then subsequently locked after returning. This is necessary to prevent deadlock
  199. // in MT apps. Further, it is the responsibility of calling functions to revalidate
  200. // the call object before using it.
  201. //====================================================================================
  202. CS_STATUS
  203. Q931SendMessage(
  204. P_CALL_OBJECT pCallObject,
  205. BYTE* CodedPtrPDU,
  206. DWORD CodedLengthPDU,
  207. BOOL bOkToUnlock)
  208. {
  209. HQ931CALL hQ931Call;
  210. DWORD dwPhysicalId;
  211. HRESULT result;
  212. ASSERT(pCallObject != NULL);
  213. ASSERT(CodedPtrPDU != NULL);
  214. ASSERT(CodedLengthPDU != 0);
  215. hQ931Call = pCallObject->hQ931Call;
  216. dwPhysicalId = pCallObject->dwPhysicalId;
  217. // send the message.
  218. if (pCallObject->bConnected)
  219. {
  220. // Unlock the call object before we call down to Link Layer (if caller said it was ok)
  221. if(bOkToUnlock)
  222. CallObjectUnlock(pCallObject);
  223. #if (defined(_DEBUG) || defined(PCS_COMPLIANCE))
  224. InteropOutput(Q931Logger, (BYTE FAR*)CodedPtrPDU, CodedLengthPDU, Q931LOG_SENT_PDU);
  225. #endif
  226. result = datalinkSendRequest(dwPhysicalId, CodedPtrPDU, CodedLengthPDU);
  227. // Now attempt to lock the object again. Note: higher level funcs must
  228. // be sure to call CallObjectValidate before assuming they have a valid lock
  229. if (bOkToUnlock && ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL)))
  230. {
  231. ISRERROR(ghISRInst, "CallObjectLock() returned error (object not found).", 0L);
  232. }
  233. // Note: if we can't get the lock, perhaps we should pass back a specific return code
  234. // that higher layers can check for??? For now, they should call CallObjectValidate()
  235. // before assuming the call object is still good.
  236. if (FAILED(result))
  237. {
  238. ISRERROR(ghISRInst, "datalinkSendRequest() failed", 0L);
  239. MemFree(CodedPtrPDU);
  240. }
  241. return result;
  242. }
  243. ISRWARNING(ghISRInst, "Q931SendMessage: message not sent because bConnected is FALSE", 0L);
  244. MemFree(CodedPtrPDU);
  245. return CS_OK;
  246. }
  247. //====================================================================================
  248. //====================================================================================
  249. CS_STATUS
  250. Q931RingingInternal(P_CALL_OBJECT pCallObject, WORD wCRV)
  251. {
  252. CC_ENDPOINTTYPE EndpointType;
  253. DWORD CodedLengthASN;
  254. BYTE *CodedPtrASN;
  255. BINARY_STRING UserUserData;
  256. DWORD CodedLengthPDU;
  257. BYTE *CodedPtrPDU;
  258. HRESULT result = CS_OK;
  259. int nError = 0;
  260. HQ931CALL hQ931Call = pCallObject->hQ931Call;
  261. if (pCallObject->VendorInfoPresent)
  262. EndpointType.pVendorInfo = &pCallObject->VendorInfo;
  263. else
  264. EndpointType.pVendorInfo = NULL;
  265. EndpointType.bIsTerminal = pCallObject->bIsTerminal;
  266. EndpointType.bIsGateway = pCallObject->bIsGateway;
  267. result = Q931AlertingEncodeASN(
  268. NULL, /* pNonStandardData */
  269. NULL, /* h245Addr */
  270. &EndpointType,
  271. &pCallObject->World,
  272. &CodedPtrASN,
  273. &CodedLengthASN,
  274. &pCallObject->CallIdentifier);
  275. if (result != CS_OK || CodedLengthASN == 0 || CodedPtrASN == NULL)
  276. {
  277. ISRERROR(ghISRInst, "Q931AlertingEncodeASN() failed, nothing to send.", 0L);
  278. if (CodedPtrASN != NULL)
  279. {
  280. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  281. }
  282. return (result != CS_OK) ? result : CS_INTERNAL_ERROR;
  283. }
  284. UserUserData.length = (WORD)CodedLengthASN;
  285. UserUserData.ptr = CodedPtrASN;
  286. result = Q931AlertingEncodePDU(wCRV, &UserUserData, &CodedPtrPDU,
  287. &CodedLengthPDU);
  288. if (CodedPtrASN != NULL)
  289. {
  290. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  291. }
  292. if ((result != CS_OK) || (CodedLengthPDU == 0) ||
  293. (CodedPtrPDU == NULL))
  294. {
  295. ISRERROR(ghISRInst, "Q931AlertingEncodePDU() failed, nothing to send.", 0L);
  296. if (CodedPtrPDU != NULL)
  297. {
  298. MemFree(CodedPtrPDU);
  299. }
  300. if (result != CS_OK)
  301. {
  302. return result;
  303. }
  304. return CS_INTERNAL_ERROR;
  305. }
  306. else
  307. {
  308. result = Q931SendMessage(pCallObject, CodedPtrPDU, CodedLengthPDU, TRUE);
  309. if(CallObjectValidate(hQ931Call) != CS_OK)
  310. return(CS_INTERNAL_ERROR);
  311. }
  312. return result;
  313. }
  314. //====================================================================================
  315. //====================================================================================
  316. CS_STATUS
  317. Q931OnCallSetup(
  318. P_CALL_OBJECT pCallObject,
  319. Q931MESSAGE *pMessage,
  320. Q931_SETUP_ASN *pSetupASN)
  321. {
  322. DWORD result;
  323. HQ931CALL hQ931Call;
  324. HRESULT Status;
  325. // if the callstate is anything other than null, ignore...
  326. // if (pCallObject->bCallState != CALLSTATE_NULL)
  327. // {
  328. // return CS_OK;
  329. // }
  330. hQ931Call = pCallObject->hQ931Call;
  331. if (pMessage->CallReference & 0x8000)
  332. {
  333. // the message came from the callee, so this should be ignored???
  334. }
  335. pMessage->CallReference &= ~(0x8000); // strip off the high bit.
  336. pCallObject->wCRV = pMessage->CallReference;
  337. pCallObject->wGoal = pSetupASN->wGoal;
  338. pCallObject->bCallerIsMC = pSetupASN->bCallerIsMC;
  339. pCallObject->wCallType = pSetupASN->wCallType;
  340. pCallObject->ConferenceID = pSetupASN->ConferenceID;
  341. pCallObject->CallIdentifier = pSetupASN->CallIdentifier;
  342. pCallObject->bCallState = CALLSTATE_PRESENT;
  343. {
  344. CSS_CALL_INCOMING EventData;
  345. WCHAR szUnicodeDisplay[CC_MAX_DISPLAY_LENGTH + 1];
  346. WCHAR szUnicodeCalledPartyNumber[CC_MAX_PARTY_NUMBER_LEN + 1];
  347. EventData.wGoal = pCallObject->wGoal;
  348. EventData.wCallType = pCallObject->wCallType;
  349. EventData.bCallerIsMC = pCallObject->bCallerIsMC;
  350. EventData.ConferenceID = pCallObject->ConferenceID;
  351. EventData.pSourceAddr = NULL;
  352. if (pSetupASN->SourceAddrPresent)
  353. {
  354. EventData.pSourceAddr = &(pSetupASN->SourceAddr);
  355. }
  356. EventData.pCallerAddr = NULL;
  357. if (pSetupASN->CallerAddrPresent)
  358. {
  359. EventData.pCallerAddr = &(pSetupASN->CallerAddr);
  360. }
  361. EventData.pCalleeDestAddr = NULL;
  362. if (pSetupASN->CalleeDestAddrPresent)
  363. {
  364. EventData.pCalleeDestAddr = &(pSetupASN->CalleeDestAddr);
  365. }
  366. EventData.pLocalAddr = NULL;
  367. if (pSetupASN->CalleeAddrPresent)
  368. {
  369. EventData.pLocalAddr = &(pSetupASN->CalleeAddr);
  370. }
  371. if (!(pSetupASN->NonStandardDataPresent) ||
  372. (pSetupASN->NonStandardData.sData.wOctetStringLength == 0) ||
  373. (pSetupASN->NonStandardData.sData.pOctetString == NULL))
  374. {
  375. EventData.pNonStandardData = NULL;
  376. }
  377. else
  378. {
  379. EventData.pNonStandardData = &(pSetupASN->NonStandardData);
  380. }
  381. EventData.pCallerAliasList = pSetupASN->pCallerAliasList;
  382. EventData.pCalleeAliasList = pSetupASN->pCalleeAliasList;
  383. EventData.pExtraAliasList = pSetupASN->pExtraAliasList;
  384. EventData.pExtensionAliasItem = pSetupASN->pExtensionAliasItem;
  385. EventData.CallIdentifier = pSetupASN->CallIdentifier;
  386. EventData.pszDisplay = NULL;
  387. if (pMessage->Display.Present && pMessage->Display.Contents)
  388. {
  389. MultiByteToWideChar(CP_ACP, 0, (const char *)pMessage->Display.Contents, -1,
  390. szUnicodeDisplay, sizeof(szUnicodeDisplay) / sizeof(szUnicodeDisplay[0]));
  391. EventData.pszDisplay = szUnicodeDisplay;
  392. }
  393. EventData.pszCalledPartyNumber = NULL;
  394. if (pMessage->CalledPartyNumber.Present && pMessage->CalledPartyNumber.PartyNumberLength)
  395. {
  396. MultiByteToWideChar(CP_ACP, 0, (const char *)pMessage->CalledPartyNumber.PartyNumbers, -1,
  397. szUnicodeCalledPartyNumber, sizeof(szUnicodeCalledPartyNumber) / sizeof(szUnicodeCalledPartyNumber[0]));
  398. EventData.pszCalledPartyNumber = szUnicodeCalledPartyNumber;
  399. }
  400. EventData.pSourceEndpointType = &(pSetupASN->EndpointType);
  401. EventData.wCallReference = pMessage->CallReference;
  402. result = pCallObject->Callback((BYTE)Q931_CALL_INCOMING,
  403. pCallObject->hQ931Call, pCallObject->dwListenToken,
  404. pCallObject->dwUserToken, &EventData);
  405. }
  406. Status = CallObjectValidate(hQ931Call);
  407. if (Status != CS_OK)
  408. return Status;
  409. if (result == 0)
  410. {
  411. WORD wCRV = (WORD)(pMessage->CallReference | 0x8000);
  412. HRESULT Status;
  413. Status = Q931RingingInternal(pCallObject, wCRV);
  414. if (Status != CS_OK)
  415. {
  416. return Status;
  417. }
  418. pCallObject->bCallState = CALLSTATE_RECEIVED;
  419. }
  420. return CS_OK;
  421. }
  422. //====================================================================================
  423. //====================================================================================
  424. CS_STATUS
  425. Q931Ringing(
  426. HQ931CALL hQ931Call,
  427. WORD *pwCRV)
  428. {
  429. P_CALL_OBJECT pCallObject = NULL;
  430. CS_STATUS Status;
  431. WORD wCRV;
  432. if (bQ931Initialized == FALSE)
  433. {
  434. ASSERT(FALSE);
  435. return CS_NOT_INITIALIZED;
  436. }
  437. ISRTRACE(ghISRInst, "Entering Q931Ringing()...", 0L);
  438. // need parameter checking...
  439. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  440. {
  441. ISRERROR(ghISRInst, "CallObjectLock() returned error (object not found).", 0L);
  442. return CS_BAD_PARAM;
  443. }
  444. if (pwCRV != NULL)
  445. {
  446. wCRV = *pwCRV;
  447. }
  448. else
  449. {
  450. wCRV = pCallObject->wCRV;
  451. }
  452. Status = Q931RingingInternal(pCallObject, wCRV);
  453. if (Status != CS_OK)
  454. {
  455. return Status;
  456. }
  457. pCallObject->bCallState = CALLSTATE_RECEIVED;
  458. Status = CallObjectUnlock(pCallObject);
  459. return Status;
  460. }
  461. //====================================================================================
  462. //====================================================================================
  463. CS_STATUS
  464. Q931OnCallProceeding(
  465. P_CALL_OBJECT pCallObject,
  466. Q931MESSAGE *pMessage,
  467. Q931_CALL_PROCEEDING_ASN *pProceedingASN)
  468. {
  469. pCallObject->bCallState = CALLSTATE_OUTGOING;
  470. Q931StopTimer(pCallObject, Q931_TIMER_303);
  471. return CS_OK;
  472. }
  473. //====================================================================================
  474. //====================================================================================
  475. CS_STATUS
  476. Q931OnCallAlerting(
  477. P_CALL_OBJECT pCallObject,
  478. Q931MESSAGE *pMessage,
  479. Q931_ALERTING_ASN *pAlertingASN)
  480. {
  481. DWORD result;
  482. pCallObject->bCallState = CALLSTATE_DELIVERED;
  483. if (pAlertingASN != NULL)
  484. {
  485. // we could pass h245addr, userinfo, and conferenceid
  486. // if desired later...
  487. // (this would be passed in the pAlertingASN field)
  488. }
  489. Q931StopTimer(pCallObject, Q931_TIMER_303);
  490. Q931StartTimer(pCallObject, Q931_TIMER_301);
  491. result = pCallObject->Callback((BYTE)Q931_CALL_RINGING,
  492. pCallObject->hQ931Call, pCallObject->dwListenToken,
  493. pCallObject->dwUserToken, NULL);
  494. return CS_OK;
  495. }
  496. //====================================================================================
  497. //====================================================================================
  498. CS_STATUS
  499. Q931OnCallConnect(
  500. P_CALL_OBJECT pCallObject,
  501. Q931MESSAGE *pMessage,
  502. Q931_CONNECT_ASN *pConnectASN)
  503. {
  504. DWORD result;
  505. if ((pMessage->CallReference & 0x8000) == 0)
  506. {
  507. // the message came from the caller, so this should be ignored???
  508. }
  509. pMessage->CallReference &= ~(0x8000); // strip off the high bit.
  510. pCallObject->ConferenceID = pConnectASN->ConferenceID;
  511. pCallObject->bCallState = CALLSTATE_ACTIVE;
  512. {
  513. CSS_CALL_ACCEPTED EventData;
  514. WCHAR szUnicodeDisplay[CC_MAX_DISPLAY_LENGTH + 1];
  515. // populate the event data struct.
  516. EventData.ConferenceID = pCallObject->ConferenceID;
  517. if (pCallObject->PeerCallAddrPresent)
  518. {
  519. EventData.pCalleeAddr = &(pCallObject->PeerCallAddr);
  520. }
  521. else
  522. {
  523. EventData.pCalleeAddr = NULL;
  524. }
  525. EventData.pLocalAddr = &(pCallObject->LocalAddr);
  526. EventData.pH245Addr = NULL;
  527. if (pConnectASN->h245AddrPresent)
  528. {
  529. EventData.pH245Addr = &(pConnectASN->h245Addr);
  530. }
  531. if (!(pConnectASN->NonStandardDataPresent) ||
  532. (pConnectASN->NonStandardData.sData.wOctetStringLength == 0) ||
  533. (pConnectASN->NonStandardData.sData.pOctetString == NULL))
  534. {
  535. EventData.pNonStandardData = NULL;
  536. }
  537. else
  538. {
  539. EventData.pNonStandardData = &(pConnectASN->NonStandardData);
  540. }
  541. EventData.pszDisplay = NULL;
  542. if (pMessage->Display.Present && pMessage->Display.Contents)
  543. {
  544. MultiByteToWideChar(CP_ACP, 0, (const char *)pMessage->Display.Contents, -1,
  545. szUnicodeDisplay, sizeof(szUnicodeDisplay) / sizeof(szUnicodeDisplay[0]));
  546. EventData.pszDisplay = szUnicodeDisplay;
  547. }
  548. EventData.pDestinationEndpointType = &(pConnectASN->EndpointType);
  549. EventData.wCallReference = pMessage->CallReference;
  550. Q931StopTimer(pCallObject, Q931_TIMER_303);
  551. Q931StopTimer(pCallObject, Q931_TIMER_301);
  552. result = pCallObject->Callback((BYTE)Q931_CALL_ACCEPTED,
  553. pCallObject->hQ931Call, pCallObject->dwListenToken,
  554. pCallObject->dwUserToken, &EventData);
  555. }
  556. return CS_OK;
  557. }
  558. //====================================================================================
  559. //====================================================================================
  560. CS_STATUS
  561. Q931OnCallReleaseComplete(
  562. P_CALL_OBJECT pCallObject,
  563. Q931MESSAGE *pMessage,
  564. Q931_RELEASE_COMPLETE_ASN *pReleaseCompleteASN)
  565. {
  566. DWORD result;
  567. BYTE bCause = 0;
  568. if (pMessage && pMessage->Cause.Present &&
  569. (pMessage->Cause.Length >= 3))
  570. {
  571. bCause = (BYTE)(pMessage->Cause.Contents[2] & (~CAUSE_EXT_BIT));
  572. }
  573. Q931StopTimer(pCallObject, Q931_TIMER_303);
  574. Q931StopTimer(pCallObject, Q931_TIMER_301);
  575. // if this is the callee, or the call has been connected already,
  576. // then this message should be treated as hangup (not reject).
  577. if (!(pCallObject->fIsCaller) ||
  578. (pCallObject->bCallState == CALLSTATE_ACTIVE) ||
  579. (bCause == CAUSE_VALUE_NORMAL_CLEAR))
  580. {
  581. CSS_CALL_REMOTE_HANGUP EventData;
  582. EventData.bReason = CC_REJECT_NORMAL_CALL_CLEARING;
  583. pCallObject->bCallState = CALLSTATE_NULL;
  584. result = pCallObject->Callback((BYTE)Q931_CALL_REMOTE_HANGUP,
  585. pCallObject->hQ931Call, pCallObject->dwListenToken,
  586. pCallObject->dwUserToken, &EventData);
  587. }
  588. else
  589. {
  590. CSS_CALL_REJECTED EventData;
  591. pCallObject->bCallState = CALLSTATE_NULL;
  592. // populate the event data struct.
  593. switch (bCause)
  594. {
  595. case CAUSE_VALUE_NORMAL_CLEAR:
  596. EventData.bRejectReason = CC_REJECT_NORMAL_CALL_CLEARING;
  597. break;
  598. case CAUSE_VALUE_USER_BUSY:
  599. EventData.bRejectReason = CC_REJECT_USER_BUSY;
  600. break;
  601. case CAUSE_VALUE_SECURITY_DENIED:
  602. EventData.bRejectReason = CC_REJECT_SECURITY_DENIED;
  603. break;
  604. case CAUSE_VALUE_NO_ANSWER:
  605. EventData.bRejectReason = CC_REJECT_NO_ANSWER;
  606. break;
  607. case CAUSE_VALUE_NOT_IMPLEMENTED:
  608. EventData.bRejectReason = CC_REJECT_NOT_IMPLEMENTED;
  609. break;
  610. case CAUSE_VALUE_INVALID_CRV:
  611. EventData.bRejectReason = CC_REJECT_INVALID_IE_CONTENTS;
  612. break;
  613. case CAUSE_VALUE_IE_MISSING:
  614. EventData.bRejectReason = CC_REJECT_MANDATORY_IE_MISSING;
  615. break;
  616. case CAUSE_VALUE_IE_CONTENTS:
  617. EventData.bRejectReason = CC_REJECT_INVALID_IE_CONTENTS;
  618. break;
  619. case CAUSE_VALUE_TIMER_EXPIRED:
  620. EventData.bRejectReason = CC_REJECT_TIMER_EXPIRED;
  621. break;
  622. default:
  623. EventData.bRejectReason = pReleaseCompleteASN->bReason;
  624. break;
  625. }
  626. EventData.ConferenceID = pCallObject->ConferenceID;
  627. EventData.pAlternateAddr = NULL;
  628. if (!(pReleaseCompleteASN->NonStandardDataPresent) ||
  629. (pReleaseCompleteASN->NonStandardData.sData.wOctetStringLength == 0) ||
  630. (pReleaseCompleteASN->NonStandardData.sData.pOctetString == NULL))
  631. {
  632. EventData.pNonStandardData = NULL;
  633. }
  634. else
  635. {
  636. EventData.pNonStandardData = &(pReleaseCompleteASN->NonStandardData);
  637. }
  638. result = pCallObject->Callback((BYTE)Q931_CALL_REJECTED,
  639. pCallObject->hQ931Call, pCallObject->dwListenToken,
  640. pCallObject->dwUserToken, &EventData);
  641. }
  642. return CS_OK;
  643. }
  644. //====================================================================================
  645. //====================================================================================
  646. CS_STATUS
  647. Q931OnCallFacility(
  648. P_CALL_OBJECT pCallObject,
  649. Q931MESSAGE *pMessage,
  650. Q931_FACILITY_ASN *pFacilityASN)
  651. {
  652. DWORD result;
  653. // if this is the callee, or the call has been connected already,
  654. // then this message should be treated as hangup (not reject).
  655. if (!(pCallObject->fIsCaller) ||
  656. (pCallObject->bCallState == CALLSTATE_ACTIVE))
  657. {
  658. CSS_CALL_REMOTE_HANGUP EventData;
  659. EventData.bReason = pFacilityASN->bReason;
  660. pCallObject->bCallState = CALLSTATE_NULL;
  661. result = pCallObject->Callback((BYTE)Q931_CALL_REMOTE_HANGUP,
  662. pCallObject->hQ931Call, pCallObject->dwListenToken,
  663. pCallObject->dwUserToken, &EventData);
  664. }
  665. else
  666. {
  667. CSS_CALL_REJECTED EventData;
  668. pCallObject->bCallState = CALLSTATE_NULL;
  669. // populate the event data struct.
  670. EventData.bRejectReason = pFacilityASN->bReason;
  671. EventData.ConferenceID = pFacilityASN->ConferenceIDPresent ?
  672. pFacilityASN->ConferenceID : pCallObject->ConferenceID;
  673. EventData.pAlternateAddr = &(pFacilityASN->AlternativeAddr);
  674. if (!(pFacilityASN->NonStandardDataPresent) ||
  675. (pFacilityASN->NonStandardData.sData.wOctetStringLength == 0) ||
  676. (pFacilityASN->NonStandardData.sData.pOctetString == NULL))
  677. {
  678. EventData.pNonStandardData = NULL;
  679. }
  680. else
  681. {
  682. EventData.pNonStandardData = &(pFacilityASN->NonStandardData);
  683. }
  684. result = pCallObject->Callback((BYTE)Q931_CALL_REJECTED,
  685. pCallObject->hQ931Call, pCallObject->dwListenToken,
  686. pCallObject->dwUserToken, &EventData);
  687. }
  688. return CS_OK;
  689. }
  690. //====================================================================================
  691. //====================================================================================
  692. CS_STATUS
  693. Q931SendReleaseCompleteMessage(
  694. P_CALL_OBJECT pCallObject,
  695. BYTE bRejectReason,
  696. PCC_CONFERENCEID pConferenceID,
  697. PCC_ADDR pAlternateAddr,
  698. PCC_NONSTANDARDDATA pNonStandardData)
  699. {
  700. CS_STATUS result = CS_OK;
  701. HQ931CALL hQ931Call = pCallObject->hQ931Call;
  702. // since this call is going away, mark the call object for deletion so any other
  703. // threads attempting to use this object will fail to get a lock on it.
  704. CallObjectMarkForDelete(hQ931Call);
  705. if((bRejectReason == CC_REJECT_ROUTE_TO_GATEKEEPER) ||
  706. (bRejectReason == CC_REJECT_CALL_FORWARDED) ||
  707. (bRejectReason == CC_REJECT_ROUTE_TO_MC))
  708. {
  709. // send the FACILITY message to the peer to reject the call.
  710. DWORD CodedLengthASN;
  711. BYTE *CodedPtrASN;
  712. HRESULT ResultASN = CS_OK;
  713. CC_ADDR AltAddr;
  714. MakeBinaryADDR(pAlternateAddr, &AltAddr);
  715. ResultASN = Q931FacilityEncodeASN(pNonStandardData,
  716. (pAlternateAddr ? &AltAddr : NULL),
  717. bRejectReason, pConferenceID, NULL, &pCallObject->World,
  718. &CodedPtrASN, &CodedLengthASN, &pCallObject->CallIdentifier);
  719. if ((ResultASN != CS_OK) || (CodedLengthASN == 0) ||
  720. (CodedPtrASN == NULL))
  721. {
  722. ISRERROR(ghISRInst, "Q931FacilityEncodeASN() failed, nothing to send.", 0L);
  723. if (CodedPtrASN != NULL)
  724. {
  725. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  726. }
  727. result = CS_INTERNAL_ERROR;
  728. }
  729. else
  730. {
  731. DWORD CodedLengthPDU;
  732. BYTE *CodedPtrPDU;
  733. BINARY_STRING UserUserData;
  734. HRESULT ResultEncode = CS_OK;
  735. WORD wCRV;
  736. if (pCallObject->fIsCaller)
  737. {
  738. wCRV = (WORD)(pCallObject->wCRV & 0x7FFF);
  739. }
  740. else
  741. {
  742. wCRV = (WORD)(pCallObject->wCRV | 0x8000);
  743. }
  744. UserUserData.length = (WORD)CodedLengthASN;
  745. UserUserData.ptr = CodedPtrASN;
  746. ResultEncode = Q931FacilityEncodePDU(wCRV,
  747. &UserUserData, &CodedPtrPDU, &CodedLengthPDU);
  748. if (CodedPtrASN != NULL)
  749. {
  750. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  751. }
  752. if ((ResultEncode != CS_OK) || (CodedLengthPDU == 0) ||
  753. (CodedPtrPDU == NULL))
  754. {
  755. ISRERROR(ghISRInst, "Q931FacilityEncodePDU() failed, nothing to send.", 0L);
  756. if (CodedPtrPDU != NULL)
  757. {
  758. MemFree(CodedPtrPDU);
  759. }
  760. result = CS_INTERNAL_ERROR;
  761. }
  762. else
  763. {
  764. result = Q931SendMessage(pCallObject, CodedPtrPDU, CodedLengthPDU, FALSE);
  765. }
  766. }
  767. }
  768. else
  769. {
  770. // send the RELEASE COMPLETE message to the peer to reject call.
  771. DWORD CodedLengthASN;
  772. BYTE *CodedPtrASN;
  773. HRESULT ResultASN = CS_OK;
  774. BYTE bReasonUU = bRejectReason;
  775. BYTE *pbReasonUU = &bReasonUU;
  776. switch (bReasonUU)
  777. {
  778. case CC_REJECT_NO_BANDWIDTH: //noBandwidth_chosen
  779. case CC_REJECT_GATEKEEPER_RESOURCES: // gatekeeperResources_chosen
  780. case CC_REJECT_UNREACHABLE_DESTINATION: // unreachableDestination_chosen
  781. case CC_REJECT_DESTINATION_REJECTION: // destinationRejection_chosen
  782. case CC_REJECT_INVALID_REVISION: // ReleaseCompleteReason_invalidRevision_chosen
  783. case CC_REJECT_NO_PERMISSION: // noPermission_chosen
  784. case CC_REJECT_UNREACHABLE_GATEKEEPER: // unreachableGatekeeper_chosen
  785. case CC_REJECT_GATEWAY_RESOURCES: // gatewayResources_chosen
  786. case CC_REJECT_BAD_FORMAT_ADDRESS: // badFormatAddress_chosen
  787. case CC_REJECT_ADAPTIVE_BUSY: // adaptiveBusy_chosen
  788. case CC_REJECT_IN_CONF: // inConf_chosen
  789. case CC_REJECT_UNDEFINED_REASON: // ReleaseCompleteReason_undefinedReason_chosen
  790. case CC_REJECT_INTERNAL_ERROR: // will be mapped to ReleaseCompleteReason_undefinedReason_chosen
  791. case CC_REJECT_NORMAL_CALL_CLEARING: // will be mapped to ReleaseCompleteReason_undefinedReason_chosen
  792. case CC_REJECT_USER_BUSY: // will be mapped to inConf_chosen
  793. case CC_REJECT_CALL_DEFLECTION: // facilityCallDeflection_chosen
  794. case CC_REJECT_SECURITY_DENIED: // securityDenied_chosen
  795. break;
  796. default:
  797. pbReasonUU = NULL;
  798. break;
  799. }
  800. ResultASN = Q931ReleaseCompleteEncodeASN(pNonStandardData,
  801. pConferenceID, pbReasonUU, &pCallObject->World,
  802. &CodedPtrASN, &CodedLengthASN, &pCallObject->CallIdentifier);
  803. if ((ResultASN != CS_OK) || (CodedLengthASN == 0) ||
  804. (CodedPtrASN == NULL))
  805. {
  806. ISRERROR(ghISRInst, "Q931ReleaseCompleteEncodeASN() failed, nothing to send.", 0L);
  807. if (CodedPtrASN != NULL)
  808. {
  809. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  810. }
  811. result = CS_INTERNAL_ERROR;
  812. }
  813. else
  814. {
  815. DWORD CodedLengthPDU;
  816. BYTE *CodedPtrPDU;
  817. BINARY_STRING UserUserData;
  818. HRESULT ResultEncode = CS_OK;
  819. BYTE bCause = 0;
  820. BYTE *pbCause = &bCause;
  821. WORD wCRV;
  822. if (pCallObject->fIsCaller)
  823. {
  824. wCRV = (WORD)(pCallObject->wCRV & 0x7FFF);
  825. }
  826. else
  827. {
  828. wCRV = (WORD)(pCallObject->wCRV | 0x8000);
  829. }
  830. UserUserData.length = (WORD)CodedLengthASN;
  831. UserUserData.ptr = CodedPtrASN;
  832. switch (bRejectReason)
  833. {
  834. case CC_REJECT_NORMAL_CALL_CLEARING:
  835. bCause = CAUSE_VALUE_NORMAL_CLEAR;
  836. break;
  837. case CC_REJECT_USER_BUSY:
  838. bCause = CAUSE_VALUE_USER_BUSY;
  839. break;
  840. case CC_REJECT_SECURITY_DENIED:
  841. bCause = CAUSE_VALUE_SECURITY_DENIED;
  842. break;
  843. case CC_REJECT_NO_ANSWER:
  844. bCause = CAUSE_VALUE_NO_ANSWER;
  845. break;
  846. case CC_REJECT_NOT_IMPLEMENTED:
  847. bCause = CAUSE_VALUE_NOT_IMPLEMENTED;
  848. break;
  849. case CC_REJECT_MANDATORY_IE_MISSING:
  850. bCause = CAUSE_VALUE_IE_MISSING;
  851. break;
  852. case CC_REJECT_INVALID_IE_CONTENTS:
  853. bCause = CAUSE_VALUE_IE_CONTENTS;
  854. break;
  855. case CC_REJECT_TIMER_EXPIRED:
  856. bCause = CAUSE_VALUE_TIMER_EXPIRED;
  857. break;
  858. default:
  859. pbCause = NULL;
  860. break;
  861. }
  862. ResultEncode = Q931ReleaseCompleteEncodePDU(wCRV,
  863. pbCause, &UserUserData,
  864. &CodedPtrPDU, &CodedLengthPDU);
  865. if (CodedPtrASN != NULL)
  866. {
  867. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  868. }
  869. if ((ResultEncode != CS_OK) || (CodedLengthPDU == 0) ||
  870. (CodedPtrPDU == NULL))
  871. {
  872. ISRERROR(ghISRInst, "Q931ReleaseCompleteEncodePDU() failed, nothing to send.", 0L);
  873. if (CodedPtrPDU != NULL)
  874. {
  875. MemFree(CodedPtrPDU);
  876. }
  877. result = CS_INTERNAL_ERROR;
  878. }
  879. else
  880. {
  881. result = Q931SendMessage(pCallObject, CodedPtrPDU, CodedLengthPDU, FALSE);
  882. }
  883. }
  884. }
  885. pCallObject->bCallState = CALLSTATE_NULL;
  886. if (result != CS_OK)
  887. {
  888. return result;
  889. }
  890. return CS_OK;
  891. }
  892. //====================================================================================
  893. //====================================================================================
  894. CS_STATUS
  895. Q931SendStatusMessage(
  896. P_CALL_OBJECT pCallObject,
  897. Q931MESSAGE *pMessage,
  898. BYTE bCause)
  899. {
  900. CS_STATUS result = CS_OK;
  901. DWORD CodedLengthPDU;
  902. BYTE *CodedPtrPDU;
  903. HRESULT EncodePDU = CS_OK;
  904. int nError = 0;
  905. HQ931CALL hQ931Call = pCallObject->hQ931Call;
  906. WORD wCRV;
  907. if (pCallObject->fIsCaller)
  908. {
  909. wCRV = (WORD)(pCallObject->wCRV & 0x7FFF);
  910. }
  911. else
  912. {
  913. wCRV = (WORD)(pCallObject->wCRV | 0x8000);
  914. }
  915. EncodePDU = Q931StatusEncodePDU(wCRV, NULL, bCause,
  916. pCallObject->bCallState, &CodedPtrPDU, &CodedLengthPDU);
  917. if ((EncodePDU != CS_OK) || (CodedLengthPDU == 0) ||
  918. (CodedPtrPDU == NULL))
  919. {
  920. ISRERROR(ghISRInst, "Q931StatusEncodePDU() failed, nothing to send.", 0L);
  921. if (CodedPtrPDU != NULL)
  922. {
  923. MemFree(CodedPtrPDU);
  924. }
  925. result = CS_INTERNAL_ERROR;
  926. }
  927. else
  928. {
  929. result = Q931SendMessage(pCallObject, CodedPtrPDU, CodedLengthPDU, TRUE);
  930. if(CallObjectValidate(hQ931Call) != CS_OK)
  931. return(CS_INTERNAL_ERROR);
  932. }
  933. return(result);
  934. }
  935. //====================================================================================
  936. //====================================================================================
  937. CS_STATUS
  938. Q931SendProceedingMessage(
  939. HQ931CALL hQ931Call,
  940. WORD wCallReference,
  941. PCC_ENDPOINTTYPE pDestinationEndpointType,
  942. PCC_NONSTANDARDDATA pNonStandardData)
  943. {
  944. CS_STATUS result = CS_OK;
  945. DWORD CodedLengthASN;
  946. BYTE *CodedPtrASN;
  947. HRESULT ResultASN = CS_OK;
  948. DWORD dwPhysicalId = INVALID_PHYS_ID;
  949. P_CALL_OBJECT pCallObject = NULL;
  950. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  951. {
  952. ISRERROR(ghISRInst, "CallObjectLock() returned error", 0L);
  953. return CS_SUBSYSTEM_FAILURE;
  954. }
  955. dwPhysicalId = pCallObject->dwPhysicalId;
  956. // first build the ASN portion of the message (user to user part)
  957. ResultASN = Q931ProceedingEncodeASN(
  958. pNonStandardData,
  959. NULL, // No H245 address.
  960. pDestinationEndpointType, // EndpointType information.
  961. &pCallObject->World,
  962. &CodedPtrASN,
  963. &CodedLengthASN,
  964. &pCallObject->CallIdentifier);
  965. if ((ResultASN != CS_OK) || (CodedLengthASN == 0) ||
  966. (CodedPtrASN == NULL))
  967. {
  968. ISRERROR(ghISRInst, "Q931ProceedingEncodeASN() failed, nothing to send.", 0L);
  969. if (CodedPtrASN != NULL)
  970. {
  971. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  972. }
  973. result = CS_INTERNAL_ERROR;
  974. }
  975. else
  976. {
  977. // now build the rest of the message
  978. DWORD CodedLengthPDU;
  979. BYTE *CodedPtrPDU;
  980. BINARY_STRING UserUserData;
  981. HRESULT ResultEncode = CS_OK;
  982. WORD wCRV = (WORD)(wCallReference | 0x8000);
  983. UserUserData.length = (WORD)CodedLengthASN;
  984. UserUserData.ptr = CodedPtrASN;
  985. ResultEncode = Q931ProceedingEncodePDU(wCRV,
  986. &UserUserData, &CodedPtrPDU, &CodedLengthPDU);
  987. if (CodedPtrASN != NULL)
  988. {
  989. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  990. }
  991. if ((ResultEncode != CS_OK) || (CodedLengthPDU == 0) ||
  992. (CodedPtrPDU == NULL))
  993. {
  994. ISRERROR(ghISRInst, "Q931ProceedingEncodePDU() failed, nothing to send.", 0L);
  995. if (CodedPtrPDU != NULL)
  996. {
  997. MemFree(CodedPtrPDU);
  998. }
  999. result = CS_INTERNAL_ERROR;
  1000. }
  1001. else
  1002. {
  1003. result = Q931SendMessage(pCallObject, CodedPtrPDU, CodedLengthPDU, TRUE);
  1004. if (CallObjectValidate(hQ931Call) != CS_OK)
  1005. return(CS_INTERNAL_ERROR);
  1006. }
  1007. }
  1008. CallObjectUnlock(pCallObject);
  1009. return(result);
  1010. }
  1011. //====================================================================================
  1012. //====================================================================================
  1013. CS_STATUS
  1014. Q931SendPDU(HQ931CALL hQ931Call, BYTE* CodedPtrPDU, DWORD CodedLengthPDU)
  1015. {
  1016. CS_STATUS result = CS_OK;
  1017. HRESULT TempResult;
  1018. P_CALL_OBJECT pCallObject = NULL;
  1019. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) ||
  1020. (pCallObject == NULL))
  1021. {
  1022. ISRERROR(ghISRInst, "CallObjectLock() returned error", 0L);
  1023. return CS_SUBSYSTEM_FAILURE;
  1024. }
  1025. TempResult = Q931SendMessage(pCallObject, CodedPtrPDU, CodedLengthPDU, TRUE);
  1026. if (CallObjectValidate(hQ931Call) != CS_OK)
  1027. return(CS_INTERNAL_ERROR);
  1028. if(FAILED(TempResult))
  1029. {
  1030. CSS_CALL_FAILED EventData;
  1031. EventData.error = TempResult;
  1032. if ((pCallObject->bCallState == CALLSTATE_ACTIVE) &&
  1033. (pCallObject->bResolved))
  1034. {
  1035. pCallObject->Callback(Q931_CALL_CONNECTION_CLOSED,
  1036. pCallObject->hQ931Call, pCallObject->dwListenToken,
  1037. pCallObject->dwUserToken, NULL);
  1038. }
  1039. else
  1040. {
  1041. pCallObject->Callback(Q931_CALL_FAILED,
  1042. pCallObject->hQ931Call, pCallObject->dwListenToken,
  1043. pCallObject->dwUserToken, &EventData);
  1044. }
  1045. if (CallObjectValidate(hQ931Call) == CS_OK)
  1046. {
  1047. DWORD dwId = pCallObject->dwPhysicalId;
  1048. if ((pCallObject->bCallState != CALLSTATE_ACTIVE) ||
  1049. (!pCallObject->bResolved))
  1050. {
  1051. CallObjectDestroy(pCallObject);
  1052. pCallObject = NULL;
  1053. }
  1054. linkLayerShutdown(dwId);
  1055. if (pCallObject)
  1056. {
  1057. pCallObject->bConnected = FALSE;
  1058. }
  1059. }
  1060. return TempResult;
  1061. }
  1062. CallObjectUnlock(pCallObject);
  1063. return CS_OK;
  1064. }
  1065. //====================================================================================
  1066. //====================================================================================
  1067. CS_STATUS
  1068. Q931OnCallStatusEnquiry(
  1069. P_CALL_OBJECT pCallObject,
  1070. Q931MESSAGE *pMessage)
  1071. {
  1072. CS_STATUS SendStatus;
  1073. SendStatus = Q931SendStatusMessage(pCallObject, pMessage,
  1074. CAUSE_VALUE_ENQUIRY_RESPONSE);
  1075. return SendStatus;
  1076. }
  1077. //====================================================================================
  1078. //====================================================================================
  1079. void
  1080. Q931SendComplete(DWORD_PTR instance, HRESULT msg, PBYTE buf, DWORD length)
  1081. {
  1082. HQ931CALL hQ931Call = (HQ931CALL)instance;
  1083. P_CALL_OBJECT pCallObject = NULL;
  1084. ISRTRACE(ghISRInst, "Entering Q931SendComplete()...", 0L);
  1085. if (buf != NULL)
  1086. {
  1087. MemFree(buf);
  1088. }
  1089. if (FAILED(msg))
  1090. {
  1091. // shut down link layer; report failure to client
  1092. CSS_CALL_FAILED EventData;
  1093. ISRERROR(ghISRInst, "error in datalinkSendRequest()", 0L);
  1094. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  1095. {
  1096. ISRERROR(ghISRInst, "CallObjectLock() returned error", 0L);
  1097. return;
  1098. }
  1099. EventData.error = msg;
  1100. if ((pCallObject->bCallState == CALLSTATE_ACTIVE) &&
  1101. (pCallObject->bResolved))
  1102. {
  1103. pCallObject->Callback(Q931_CALL_CONNECTION_CLOSED,
  1104. pCallObject->hQ931Call, pCallObject->dwListenToken,
  1105. pCallObject->dwUserToken, NULL);
  1106. }
  1107. else
  1108. {
  1109. pCallObject->Callback(Q931_CALL_FAILED,
  1110. pCallObject->hQ931Call, pCallObject->dwListenToken,
  1111. pCallObject->dwUserToken, &EventData);
  1112. }
  1113. if (CallObjectValidate(hQ931Call) == CS_OK)
  1114. {
  1115. DWORD dwId = pCallObject->dwPhysicalId;
  1116. if ((pCallObject->bCallState != CALLSTATE_ACTIVE) ||
  1117. (!pCallObject->bResolved))
  1118. {
  1119. CallObjectDestroy(pCallObject);
  1120. pCallObject = NULL;
  1121. }
  1122. linkLayerShutdown(dwId);
  1123. if (pCallObject)
  1124. {
  1125. pCallObject->bConnected = FALSE;
  1126. }
  1127. }
  1128. return;
  1129. }
  1130. return;
  1131. }
  1132. //====================================================================================
  1133. //====================================================================================
  1134. static DWORD
  1135. PostReceiveBuffer(DWORD dwPhysicalId, BYTE *buf)
  1136. {
  1137. if (buf == NULL)
  1138. {
  1139. buf = MemAlloc(RECEIVE_BUFFER_SIZE);
  1140. }
  1141. return datalinkReceiveRequest(dwPhysicalId, buf, RECEIVE_BUFFER_SIZE);
  1142. }
  1143. //====================================================================================
  1144. //====================================================================================
  1145. void
  1146. OnReceiveCallback(DWORD_PTR instance, HRESULT message, Q931MESSAGE *pMessage, BYTE *buf, DWORD nbytes)
  1147. {
  1148. HQ931CALL hQ931Call = (HQ931CALL)instance;
  1149. P_CALL_OBJECT pCallObject = NULL;
  1150. DWORD dwPhysicalId;
  1151. ISRTRACE(ghISRInst, "Entering ReceiveCallback()...", 0L);
  1152. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  1153. {
  1154. if (buf)
  1155. {
  1156. MemFree(buf);
  1157. }
  1158. ISRTRACE(ghISRInst, "Call Object no longer available:", (DWORD)hQ931Call);
  1159. return;
  1160. }
  1161. if (message == LINK_RECV_DATA)
  1162. {
  1163. HRESULT Result = CS_OK;
  1164. if ((buf == NULL) || (nbytes == 0))
  1165. {
  1166. ISRERROR(ghISRInst, "Empty buffer received as data.", 0L);
  1167. CallObjectUnlock(pCallObject);
  1168. return;
  1169. }
  1170. // This block is the Q931 call re-connect implementation:
  1171. // if the object related to the incoming message is not yet resolved...
  1172. if (pCallObject->bResolved == FALSE)
  1173. {
  1174. // try to resolve the object.
  1175. HQ931CALL hFoundCallObject;
  1176. P_CALL_OBJECT pFoundCallObject = NULL;
  1177. // If found another object with matching CRV/Addr...
  1178. if (CallObjectFind(&hFoundCallObject, pCallObject->wCRV,
  1179. &(pCallObject->PeerConnectAddr)) &&
  1180. ((CallObjectLock(hFoundCallObject, &pFoundCallObject) == CS_OK) &&
  1181. (pFoundCallObject != NULL)))
  1182. {
  1183. // friendly channel close of the pFoundCallObject.
  1184. Q931SendReleaseCompleteMessage(pFoundCallObject,
  1185. CC_REJECT_UNDEFINED_REASON, &(pFoundCallObject->ConferenceID), NULL, NULL);
  1186. // unlock the call object before calling shutdown
  1187. CallObjectUnlock(pFoundCallObject);
  1188. linkLayerShutdown(pFoundCallObject->dwPhysicalId);
  1189. if((CallObjectLock(hFoundCallObject, &pFoundCallObject) != CS_OK) ||
  1190. (pFoundCallObject == NULL))
  1191. return;
  1192. // assign the new dwPhysicalId to found object.
  1193. pFoundCallObject->dwPhysicalId = pCallObject->dwPhysicalId;
  1194. // new object should be destroyed.
  1195. CallObjectDestroy(pCallObject);
  1196. pCallObject = pFoundCallObject;
  1197. }
  1198. else
  1199. {
  1200. // The call is a newly established call, so resolve it now.
  1201. pCallObject->bResolved = TRUE;
  1202. }
  1203. }
  1204. Result = Q931ParseMessage((BYTE *)buf, nbytes, pMessage);
  1205. #if (defined(_DEBUG) || defined(PCS_COMPLIANCE))
  1206. InteropOutput(Q931Logger, buf, nbytes, Q931LOG_RECEIVED_PDU);
  1207. #endif
  1208. if (Result != CS_OK)
  1209. {
  1210. Result = Q931SendStatusMessage(pCallObject, pMessage,
  1211. CAUSE_VALUE_INVALID_MSG);
  1212. ISRERROR(ghISRInst, "Q931ParseMessage(): failed.", 0L);
  1213. if(CallObjectValidate(hQ931Call) != CS_OK)
  1214. {
  1215. if (buf)
  1216. {
  1217. MemFree(buf);
  1218. }
  1219. return;
  1220. }
  1221. dwPhysicalId = pCallObject->dwPhysicalId;
  1222. CallObjectUnlock(pCallObject);
  1223. PostReceiveBuffer(dwPhysicalId, buf);
  1224. return;
  1225. }
  1226. if (pMessage->Shift.Present)
  1227. {
  1228. ISRERROR(ghISRInst, "Shift present in message: dropped.", 0L);
  1229. dwPhysicalId = pCallObject->dwPhysicalId;
  1230. CallObjectUnlock(pCallObject);
  1231. PostReceiveBuffer(dwPhysicalId, buf);
  1232. return;
  1233. }
  1234. // If a hooking procedure has been installed,
  1235. // give it first shot at acting on the received PDU.
  1236. // If it returns TRUE, then processing is finished.
  1237. if (gReceivePDUHookProc)
  1238. {
  1239. BOOL bHookProcessedMessage;
  1240. bHookProcessedMessage = gReceivePDUHookProc(pMessage,
  1241. pCallObject->hQ931Call, pCallObject->dwListenToken,
  1242. pCallObject->dwUserToken);
  1243. if (bHookProcessedMessage)
  1244. {
  1245. if (CallObjectValidate(hQ931Call) == CS_OK)
  1246. {
  1247. dwPhysicalId = pCallObject->dwPhysicalId;
  1248. CallObjectUnlock(pCallObject);
  1249. PostReceiveBuffer(dwPhysicalId, buf);
  1250. }
  1251. return;
  1252. }
  1253. }
  1254. // Message now contains the values of the Q931 PDU elements...
  1255. switch (pMessage->MessageType)
  1256. {
  1257. case SETUPMESSAGETYPE:
  1258. {
  1259. Q931_SETUP_ASN SetupASN;
  1260. if (!pMessage->UserToUser.Present || (pMessage->UserToUser.UserInformationLength == 0))
  1261. {
  1262. ISRERROR(ghISRInst, "ReceiveCallback(): Message is missing ASN.1 UserUser data...", 0L);
  1263. dwPhysicalId = pCallObject->dwPhysicalId;
  1264. CallObjectUnlock(pCallObject);
  1265. PostReceiveBuffer(dwPhysicalId, buf);
  1266. return;
  1267. }
  1268. ISRTRACE(ghISRInst, "ReceiveCallback(): received Setup message...", 0L);
  1269. Result = Q931SetupParseASN(&pCallObject->World, pMessage->UserToUser.UserInformation,
  1270. pMessage->UserToUser.UserInformationLength, &SetupASN);
  1271. if (Result == CS_OPTION_NOT_IMPLEMENTED)
  1272. {
  1273. //... maybe callback callcont in later drop.
  1274. // initiate a disconnect sequence from the caller side.
  1275. if (Q931SendReleaseCompleteMessage(pCallObject,
  1276. CC_REJECT_TIMER_EXPIRED, NULL, NULL, NULL) != CS_OK)
  1277. {
  1278. // nothing to do if this fails.
  1279. }
  1280. dwPhysicalId = pCallObject->dwPhysicalId;
  1281. CallObjectDestroy(pCallObject);
  1282. linkLayerShutdown(dwPhysicalId);
  1283. if (buf)
  1284. {
  1285. MemFree(buf);
  1286. buf = NULL;
  1287. }
  1288. return;
  1289. }
  1290. if (Result != CS_OK)
  1291. {
  1292. ISRERROR(ghISRInst, "ReceiveCallback(): Unable to parse ASN.1 data.", 0L);
  1293. break;
  1294. }
  1295. // The "CallerAddr is not passed in the PDU, so the
  1296. // only valuable addr to use is the connection addr
  1297. // passed from the link layer and saved into the call
  1298. // object at connect-time.
  1299. SetupASN.CallerAddrPresent = TRUE;
  1300. SetupASN.CallerAddr = pCallObject->PeerConnectAddr;
  1301. // The "CalleeAddr" which is passed in the PDU is ignored
  1302. // by the ASN parser, and supplied by the link layer
  1303. // instead and saved into the call object at connect-time.
  1304. // here, this address is used as the callee addr.
  1305. SetupASN.CalleeAddrPresent = TRUE;
  1306. SetupASN.CalleeAddr = pCallObject->LocalAddr;
  1307. Result = Q931OnCallSetup(pCallObject, pMessage, &SetupASN);
  1308. _FreeSetupASN(&SetupASN);
  1309. }
  1310. break;
  1311. case RELEASECOMPLMESSAGETYPE:
  1312. {
  1313. Q931_RELEASE_COMPLETE_ASN ReleaseCompleteASN;
  1314. if (!pMessage->UserToUser.Present || (pMessage->UserToUser.UserInformationLength == 0))
  1315. {
  1316. ISRERROR(ghISRInst, "ReceiveCallback(): Message is missing ASN.1 UserUser data...", 0L);
  1317. dwPhysicalId = pCallObject->dwPhysicalId;
  1318. CallObjectUnlock(pCallObject);
  1319. PostReceiveBuffer(dwPhysicalId, buf);
  1320. return;
  1321. }
  1322. ISRTRACE(ghISRInst, "ReceiveCallback(): received ReleaseComplete message...", 0L);
  1323. Result = Q931ReleaseCompleteParseASN(&pCallObject->World,
  1324. pMessage->UserToUser.UserInformation,
  1325. pMessage->UserToUser.UserInformationLength, &ReleaseCompleteASN);
  1326. if (Result != CS_OK)
  1327. {
  1328. ISRERROR(ghISRInst, "ReceiveCallback(): Unable to parse ASN.1 data.", 0L);
  1329. break;
  1330. }
  1331. Result = Q931OnCallReleaseComplete(pCallObject, pMessage, &ReleaseCompleteASN);
  1332. if (CallObjectValidate(hQ931Call) == CS_OK)
  1333. {
  1334. dwPhysicalId = pCallObject->dwPhysicalId;
  1335. CallObjectDestroy(pCallObject);
  1336. linkLayerShutdown(dwPhysicalId);
  1337. }
  1338. MemFree(buf);
  1339. _FreeReleaseCompleteASN(&ReleaseCompleteASN);
  1340. return;
  1341. }
  1342. break;
  1343. case FACILITYMESSAGETYPE:
  1344. {
  1345. Q931_FACILITY_ASN FacilityASN;
  1346. if (!pMessage->UserToUser.Present || (pMessage->UserToUser.UserInformationLength == 0))
  1347. {
  1348. ISRERROR(ghISRInst, "ReceiveCallback(): Message is missing ASN.1 UserUser data...", 0L);
  1349. dwPhysicalId = pCallObject->dwPhysicalId;
  1350. CallObjectUnlock(pCallObject);
  1351. PostReceiveBuffer(dwPhysicalId, buf);
  1352. return;
  1353. }
  1354. ISRTRACE(ghISRInst, "ReceiveCallback(): received Facility message...", 0L);
  1355. Result = Q931FacilityParseASN(&pCallObject->World, pMessage->UserToUser.UserInformation,
  1356. pMessage->UserToUser.UserInformationLength, &FacilityASN);
  1357. if (Result != CS_OK)
  1358. {
  1359. ISRERROR(ghISRInst, "ReceiveCallback(): Unable to parse ASN.1 data.", 0L);
  1360. break;
  1361. }
  1362. // initiate a disconnect sequence from the caller side.
  1363. Q931SendReleaseCompleteMessage(pCallObject,
  1364. CC_REJECT_CALL_DEFLECTION, NULL, NULL, NULL);
  1365. Result = Q931OnCallFacility(pCallObject, pMessage, &FacilityASN);
  1366. _FreeFacilityASN(&FacilityASN);
  1367. dwPhysicalId = pCallObject->dwPhysicalId;
  1368. CallObjectDestroy(pCallObject);
  1369. linkLayerShutdown(dwPhysicalId);
  1370. MemFree(buf);
  1371. return;
  1372. }
  1373. break;
  1374. case CONNECTMESSAGETYPE:
  1375. {
  1376. Q931_CONNECT_ASN ConnectASN;
  1377. if (!pMessage->UserToUser.Present || (pMessage->UserToUser.UserInformationLength == 0))
  1378. {
  1379. ISRERROR(ghISRInst, "ReceiveCallback(): Message is missing ASN.1 UserUser data...", 0L);
  1380. dwPhysicalId = pCallObject->dwPhysicalId;
  1381. CallObjectUnlock(pCallObject);
  1382. PostReceiveBuffer(dwPhysicalId, buf);
  1383. return;
  1384. }
  1385. ISRTRACE(ghISRInst, "ReceiveCallback(): received Connect message...", 0L);
  1386. Result = Q931ConnectParseASN(&pCallObject->World, pMessage->UserToUser.UserInformation,
  1387. pMessage->UserToUser.UserInformationLength, &ConnectASN);
  1388. if (Result != CS_OK)
  1389. {
  1390. ISRERROR(ghISRInst, "ReceiveCallback(): Unable to parse ASN.1 data.", 0L);
  1391. break;
  1392. }
  1393. Result = Q931OnCallConnect(pCallObject, pMessage, &ConnectASN);
  1394. _FreeConnectASN(&ConnectASN);
  1395. }
  1396. break;
  1397. case PROCEEDINGMESSAGETYPE:
  1398. {
  1399. Q931_CALL_PROCEEDING_ASN ProceedingASN;
  1400. ISRTRACE(ghISRInst, "ReceiveCallback(): received Proceeding message...", 0L);
  1401. if (!pMessage->UserToUser.Present || (pMessage->UserToUser.UserInformationLength == 0))
  1402. {
  1403. Result = Q931OnCallProceeding(pCallObject, pMessage, NULL);
  1404. }
  1405. else
  1406. {
  1407. Result = Q931ProceedingParseASN(&pCallObject->World, pMessage->UserToUser.UserInformation,
  1408. pMessage->UserToUser.UserInformationLength, &ProceedingASN);
  1409. if (Result != CS_OK)
  1410. {
  1411. ISRERROR(ghISRInst, "ReceiveCallback(): Unable to parse ASN.1 data.", 0L);
  1412. break;
  1413. }
  1414. Result = Q931OnCallProceeding(pCallObject, pMessage, &ProceedingASN);
  1415. _FreeProceedingASN(&ProceedingASN);
  1416. }
  1417. }
  1418. break;
  1419. case ALERTINGMESSAGETYPE:
  1420. {
  1421. Q931_ALERTING_ASN AlertingASN;
  1422. ISRTRACE(ghISRInst, "ReceiveCallback(): received Alerting message...", 0L);
  1423. if (!pMessage->UserToUser.Present || (pMessage->UserToUser.UserInformationLength == 0))
  1424. {
  1425. Result = Q931OnCallAlerting(pCallObject, pMessage, NULL);
  1426. }
  1427. else
  1428. {
  1429. Result = Q931AlertingParseASN(&pCallObject->World, pMessage->UserToUser.UserInformation,
  1430. pMessage->UserToUser.UserInformationLength, &AlertingASN);
  1431. if (Result != CS_OK)
  1432. {
  1433. ISRERROR(ghISRInst, "ReceiveCallback(): Unable to parse ASN.1 data.", 0L);
  1434. break;
  1435. }
  1436. Result = Q931OnCallAlerting(pCallObject, pMessage, &AlertingASN);
  1437. _FreeAlertingASN(&AlertingASN);
  1438. }
  1439. }
  1440. break;
  1441. case RELEASEMESSAGETYPE:
  1442. case STATUSMESSAGETYPE:
  1443. ISRWARNING(ghISRInst, "ReceiveCallback(): message not yet supported.", 0L);
  1444. break;
  1445. case STATUSENQUIRYMESSAGETYPE:
  1446. ISRWARNING(ghISRInst, "ReceiveCallback(): message not yet supported.", 0L);
  1447. Result = Q931OnCallStatusEnquiry(pCallObject, pMessage);
  1448. break;
  1449. default:
  1450. ISRERROR(ghISRInst, "ReceiveCallback(): unknown message received.", 0L);
  1451. break;
  1452. }
  1453. // re-validate the call object:
  1454. if (CallObjectValidate(hQ931Call) == CS_OK)
  1455. {
  1456. dwPhysicalId = pCallObject->dwPhysicalId;
  1457. CallObjectUnlock(pCallObject);
  1458. PostReceiveBuffer(dwPhysicalId, buf);
  1459. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  1460. return;
  1461. }
  1462. else
  1463. {
  1464. if (buf)
  1465. {
  1466. MemFree(buf);
  1467. }
  1468. return;
  1469. }
  1470. if (Result == CS_INCOMPATIBLE_VERSION)
  1471. {
  1472. // initiate a disconnect sequence from the caller side.
  1473. Q931SendReleaseCompleteMessage(pCallObject,
  1474. CC_REJECT_INVALID_REVISION, NULL, NULL, NULL);
  1475. dwPhysicalId = pCallObject->dwPhysicalId;
  1476. CallObjectDestroy(pCallObject);
  1477. linkLayerShutdown(dwPhysicalId);
  1478. return;
  1479. }
  1480. if (Result == CS_MANDATORY_IE_MISSING)
  1481. {
  1482. Q931SendStatusMessage(pCallObject, pMessage,
  1483. CAUSE_VALUE_IE_MISSING);
  1484. }
  1485. else if (Result == CS_BAD_IE_CONTENT)
  1486. {
  1487. Q931SendStatusMessage(pCallObject, pMessage,
  1488. CAUSE_VALUE_IE_CONTENTS);
  1489. }
  1490. }
  1491. else if (message == LINK_RECV_CLOSED)
  1492. {
  1493. // Socket closed
  1494. if (buf)
  1495. {
  1496. MemFree(buf);
  1497. }
  1498. pCallObject->Callback(Q931_CALL_CONNECTION_CLOSED, pCallObject->hQ931Call,
  1499. pCallObject->dwListenToken,
  1500. pCallObject->dwUserToken, NULL);
  1501. if (CallObjectValidate(hQ931Call) == CS_OK)
  1502. {
  1503. dwPhysicalId = pCallObject->dwPhysicalId;
  1504. pCallObject->bConnected = FALSE;
  1505. CallObjectDestroy(pCallObject);
  1506. linkLayerShutdown(dwPhysicalId);
  1507. }
  1508. return;
  1509. }
  1510. else if (buf)
  1511. {
  1512. // unknown condition?
  1513. MemFree(buf);
  1514. }
  1515. if (CallObjectValidate(hQ931Call) == CS_OK)
  1516. {
  1517. CallObjectUnlock(pCallObject);
  1518. }
  1519. return;
  1520. }
  1521. //====================================================================================
  1522. //====================================================================================
  1523. void
  1524. Q931ReceiveCallback(DWORD_PTR instance, HRESULT message, BYTE *buf, DWORD nbytes)
  1525. {
  1526. Q931MESSAGE *pMessage = NULL;
  1527. if (message == LINK_RECV_DATA)
  1528. {
  1529. pMessage = (Q931MESSAGE *)MemAlloc(sizeof(Q931MESSAGE));
  1530. if (pMessage == NULL)
  1531. {
  1532. ISRERROR(ghISRInst, "Not enough memory to process Q931 message.", 0L);
  1533. // something more should be done here to indicate SERIOUS error...
  1534. return;
  1535. }
  1536. }
  1537. OnReceiveCallback(instance, message, pMessage, buf, nbytes);
  1538. if (pMessage)
  1539. {
  1540. MemFree(pMessage);
  1541. }
  1542. return;
  1543. }
  1544. //====================================================================================
  1545. //====================================================================================
  1546. void
  1547. Q931ConnectCallback(DWORD_PTR dwInstance, HRESULT dwMessage,
  1548. CC_ADDR *pLocalAddr, CC_ADDR *pPeerAddr)
  1549. {
  1550. HQ931CALL hQ931Call = (HQ931CALL)dwInstance;
  1551. P_CALL_OBJECT pCallObject = NULL;
  1552. HRESULT TempResult;
  1553. DWORD dwPhysicalId;
  1554. ISRTRACE(ghISRInst, "Entering Q931ConnectCallback()...", 0L);
  1555. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  1556. {
  1557. ISRERROR(ghISRInst, "CallObjectLock() returned error", 0L);
  1558. return;
  1559. }
  1560. pCallObject->bConnected = TRUE;
  1561. if (FAILED(dwMessage))
  1562. {
  1563. // shut down link layer; report failure to client
  1564. CSS_CALL_FAILED EventData;
  1565. ISRERROR(ghISRInst, "error in connect", 0L);
  1566. EventData.error = dwMessage;
  1567. pCallObject->Callback(Q931_CALL_FAILED, pCallObject->hQ931Call,
  1568. pCallObject->dwListenToken,
  1569. pCallObject->dwUserToken, &EventData);
  1570. if (CallObjectValidate(hQ931Call) == CS_OK)
  1571. {
  1572. DWORD dwId = pCallObject->dwPhysicalId;
  1573. CallObjectDestroy(pCallObject);
  1574. linkLayerShutdown(dwId);
  1575. }
  1576. return;
  1577. }
  1578. if (dwMessage != LINK_CONNECT_COMPLETE)
  1579. {
  1580. ISRERROR(ghISRInst, "unexpected connect callback", 0L);
  1581. CallObjectUnlock(pCallObject);
  1582. return;
  1583. }
  1584. if (pCallObject->bCallState == CALLSTATE_NULL)
  1585. {
  1586. pCallObject->bCallState = CALLSTATE_INITIATED;
  1587. }
  1588. ASSERT(pLocalAddr);
  1589. pCallObject->LocalAddr = *pLocalAddr;
  1590. ASSERT(pPeerAddr);
  1591. pCallObject->PeerConnectAddr = *pPeerAddr;
  1592. // if the user specified a binary source address with address = 0,
  1593. // fill in the address with the local address and send.
  1594. if ((pCallObject->SourceAddrPresent) &&
  1595. (pCallObject->SourceAddr.nAddrType == CC_IP_BINARY) &&
  1596. (!pCallObject->SourceAddr.Addr.IP_Binary.dwAddr))
  1597. {
  1598. pCallObject->SourceAddr = *pLocalAddr;
  1599. }
  1600. if ((pCallObject->fIsCaller) &&
  1601. (pCallObject->bCallState == CALLSTATE_INITIATED))
  1602. {
  1603. // send the SETUP message to the peer.
  1604. DWORD CodedLengthASN;
  1605. BYTE *CodedPtrASN;
  1606. HRESULT ResultASN = CS_OK;
  1607. DWORD CodedLengthPDU;
  1608. BYTE *CodedPtrPDU;
  1609. HRESULT ResultPDU = CS_OK;
  1610. int nError = 0;
  1611. BOOL ResultSend = FALSE;
  1612. BINARY_STRING UserUserData;
  1613. PCC_VENDORINFO pVendorInfo = NULL;
  1614. CC_NONSTANDARDDATA *pNonStandardData = NULL;
  1615. DWORD dwId;
  1616. if (pCallObject->VendorInfoPresent)
  1617. {
  1618. pVendorInfo = &(pCallObject->VendorInfo);
  1619. }
  1620. if (pCallObject->NonStandardDataPresent)
  1621. {
  1622. pNonStandardData = &(pCallObject->NonStandardData);
  1623. }
  1624. // if there is a special callee alias list, load the calledparty#.
  1625. if (pCallObject->szCalledPartyNumber[0] == 0 &&
  1626. pCallObject->pCalleeAliasList != NULL &&
  1627. pCallObject->pCalleeAliasList->wCount == 1 &&
  1628. pCallObject->pCalleeAliasList->pItems[0].wType == CC_ALIAS_H323_PHONE &&
  1629. pCallObject->pCalleeAliasList->pItems[0].wDataLength > 0 &&
  1630. pCallObject->pCalleeAliasList->pItems[0].pData != NULL)
  1631. {
  1632. PCC_ALIASITEM pItem = &pCallObject->pCalleeAliasList->pItems[0];
  1633. WCHAR szWidePartyNumber[CC_MAX_PARTY_NUMBER_LEN + 1];
  1634. memset(szWidePartyNumber, 0 , CC_MAX_PARTY_NUMBER_LEN + 1);
  1635. if (pItem->wPrefixLength > 0 && pItem->pPrefix != NULL)
  1636. {
  1637. ASSERT((pItem->wPrefixLength + pItem->wDataLength +1) <= (sizeof(szWidePartyNumber)/sizeof(szWidePartyNumber[0])));
  1638. memcpy(&szWidePartyNumber[0],
  1639. pItem->pPrefix,
  1640. (pItem->wPrefixLength) * sizeof(WCHAR));
  1641. memcpy(&szWidePartyNumber[pItem->wPrefixLength],
  1642. pItem->pData,
  1643. pItem->wDataLength * sizeof(WCHAR));
  1644. }
  1645. else
  1646. {
  1647. ASSERT((pItem->wDataLength +1) <= (sizeof(szWidePartyNumber)/sizeof(szWidePartyNumber[0])));
  1648. memcpy(szWidePartyNumber,
  1649. pCallObject->pCalleeAliasList->pItems[0].pData,
  1650. pItem->wDataLength * sizeof(WCHAR));
  1651. }
  1652. WideCharToMultiByte(CP_ACP, 0, szWidePartyNumber,
  1653. pItem->wPrefixLength + pItem->wDataLength * sizeof(WCHAR),
  1654. pCallObject->szCalledPartyNumber,
  1655. sizeof(pCallObject->szCalledPartyNumber), NULL, NULL);
  1656. }
  1657. // may wish to pass alias parms later instead of NULL, NULL.
  1658. ResultASN = Q931SetupEncodeASN(pNonStandardData,
  1659. pCallObject->SourceAddrPresent ? &(pCallObject->SourceAddr) : NULL,
  1660. pCallObject->PeerCallAddrPresent ? &(pCallObject->PeerCallAddr) : NULL, // callee
  1661. pCallObject->wGoal,
  1662. pCallObject->wCallType,
  1663. pCallObject->bCallerIsMC,
  1664. &(pCallObject->ConferenceID),
  1665. pCallObject->pCallerAliasList,
  1666. pCallObject->pCalleeAliasList,
  1667. pCallObject->pExtraAliasList,
  1668. pCallObject->pExtensionAliasItem,
  1669. pVendorInfo,
  1670. pCallObject->bIsTerminal,
  1671. pCallObject->bIsGateway,
  1672. &pCallObject->World,
  1673. &CodedPtrASN,
  1674. &CodedLengthASN,
  1675. &pCallObject->CallIdentifier);
  1676. if ((ResultASN != CS_OK) || (CodedLengthASN == 0) ||
  1677. (CodedPtrASN == NULL))
  1678. {
  1679. CSS_CALL_FAILED EventData;
  1680. ISRERROR(ghISRInst, "Q931SetupEncodeASN() failed, nothing to send.", 0L);
  1681. if (CodedPtrASN != NULL)
  1682. {
  1683. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  1684. }
  1685. EventData.error = CS_INTERNAL_ERROR;
  1686. dwId = pCallObject->dwPhysicalId;
  1687. pCallObject->Callback(Q931_CALL_FAILED, pCallObject->hQ931Call,
  1688. pCallObject->dwListenToken,
  1689. pCallObject->dwUserToken, &EventData);
  1690. linkLayerShutdown(dwId);
  1691. if (CallObjectValidate(hQ931Call) == CS_OK)
  1692. CallObjectDestroy(pCallObject);
  1693. return;
  1694. }
  1695. UserUserData.length = (WORD)CodedLengthASN;
  1696. UserUserData.ptr = CodedPtrASN;
  1697. ResultPDU = Q931SetupEncodePDU(pCallObject->wCRV,
  1698. pCallObject->szDisplay, pCallObject->szCalledPartyNumber,
  1699. &UserUserData, &CodedPtrPDU, &CodedLengthPDU);
  1700. if (CodedPtrASN != NULL)
  1701. {
  1702. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  1703. }
  1704. if ((ResultPDU != CS_OK) || (CodedLengthPDU == 0) ||
  1705. (CodedPtrPDU == NULL))
  1706. {
  1707. CSS_CALL_FAILED EventData;
  1708. ISRERROR(ghISRInst, "Q931SetupEncodePDU() failed, nothing to send.", 0L);
  1709. if (CodedPtrPDU != NULL)
  1710. {
  1711. MemFree(CodedPtrPDU);
  1712. }
  1713. EventData.error = CS_INTERNAL_ERROR;
  1714. dwId = pCallObject->dwPhysicalId;
  1715. pCallObject->Callback(Q931_CALL_FAILED, pCallObject->hQ931Call,
  1716. pCallObject->dwListenToken,
  1717. pCallObject->dwUserToken, &EventData);
  1718. linkLayerShutdown(dwId);
  1719. if (CallObjectValidate(hQ931Call) == CS_OK)
  1720. CallObjectDestroy(pCallObject);
  1721. return;
  1722. }
  1723. if (pCallObject->NonStandardDataPresent)
  1724. {
  1725. if (pCallObject->NonStandardData.sData.pOctetString != NULL)
  1726. {
  1727. MemFree(pCallObject->NonStandardData.sData.pOctetString);
  1728. pCallObject->NonStandardData.sData.pOctetString = NULL;
  1729. }
  1730. pCallObject->NonStandardDataPresent = FALSE;
  1731. }
  1732. Q931FreeAliasNames(pCallObject->pCallerAliasList);
  1733. pCallObject->pCallerAliasList = NULL;
  1734. Q931FreeAliasNames(pCallObject->pCalleeAliasList);
  1735. pCallObject->pCalleeAliasList = NULL;
  1736. Q931FreeAliasNames(pCallObject->pExtraAliasList);
  1737. pCallObject->pExtraAliasList = NULL;
  1738. Q931FreeAliasItem(pCallObject->pExtensionAliasItem);
  1739. pCallObject->pExtensionAliasItem = NULL;
  1740. TempResult=Q931SendMessage(pCallObject, CodedPtrPDU, CodedLengthPDU, TRUE);
  1741. if (CallObjectValidate(hQ931Call) != CS_OK)
  1742. return;
  1743. if(FAILED(TempResult))
  1744. {
  1745. CSS_CALL_FAILED EventData;
  1746. EventData.error = TempResult;
  1747. dwId = pCallObject->dwPhysicalId;
  1748. pCallObject->Callback(Q931_CALL_FAILED, pCallObject->hQ931Call,
  1749. pCallObject->dwListenToken,
  1750. pCallObject->dwUserToken, &EventData);
  1751. linkLayerShutdown(dwId);
  1752. if (CallObjectValidate(hQ931Call) == CS_OK)
  1753. CallObjectDestroy(pCallObject);
  1754. return;
  1755. }
  1756. Q931StartTimer(pCallObject, Q931_TIMER_303);
  1757. }
  1758. dwPhysicalId = pCallObject->dwPhysicalId;
  1759. CallObjectUnlock(pCallObject);
  1760. PostReceiveBuffer(dwPhysicalId, NULL);
  1761. }
  1762. //====================================================================================
  1763. //====================================================================================
  1764. void
  1765. Q931ListenCallback(DWORD_PTR dwInstance, HRESULT dwMessage,
  1766. CC_ADDR *LocalAddr, CC_ADDR *PeerAddr)
  1767. {
  1768. HQ931LISTEN hListenObject = (HQ931LISTEN)dwInstance;
  1769. P_LISTEN_OBJECT pListenObject = NULL;
  1770. CS_STATUS CreateObjectResult;
  1771. HQ931CALL hQ931Call;
  1772. P_CALL_OBJECT pCallObject = NULL;
  1773. HRESULT TempResult;
  1774. DWORD dwPhysicalId;
  1775. ISRTRACE(ghISRInst, "Q931ListenCallback.", 0L);
  1776. if (dwMessage != LINK_CONNECT_REQUEST)
  1777. {
  1778. ISRERROR(ghISRInst, "unexpected callback received on listen socket", 0L);
  1779. return;
  1780. }
  1781. if (FAILED(dwMessage))
  1782. {
  1783. ISRERROR(ghISRInst, "error on listen socket", 0L);
  1784. return;
  1785. }
  1786. if ((ListenObjectLock(hListenObject, &pListenObject) != CS_OK) || (pListenObject == NULL))
  1787. {
  1788. ISRERROR(ghISRInst, "ListenObjectLock() returned error", 0L);
  1789. return;
  1790. }
  1791. // create call object with all known attributes of this call.
  1792. // a handle of the call object is returned in phQ931Call.
  1793. CreateObjectResult = CallObjectCreate(&hQ931Call,
  1794. pListenObject->dwUserToken,
  1795. CC_INVALID_HANDLE,
  1796. pListenObject->ListenCallback,
  1797. FALSE, // I am NOT the caller.
  1798. LocalAddr, // Local address on which channel is connected
  1799. PeerAddr, // Address to which channel is connected
  1800. NULL, // Address of opposite call end-point.
  1801. NULL, // no source addr
  1802. NULL, // no conference id yet.
  1803. CSG_NONE, // no goal yet.
  1804. CC_CALLTYPE_UNKNOWN, // no call type yet.
  1805. FALSE, // caller is assumed to not be the MC.
  1806. NULL, // no display yet.
  1807. NULL, // no called party number yet.
  1808. NULL, // no caller aliases yet.
  1809. NULL, // no callee aliases yet.
  1810. NULL, // no extra aliases yet.
  1811. NULL, // no extension aliases.
  1812. NULL, // no EndpointType info yet.
  1813. NULL,
  1814. 0, // no CRV yet.
  1815. NULL); // no h225 CallIdentifier yet.
  1816. if (CreateObjectResult != CS_OK)
  1817. {
  1818. ISRERROR(ghISRInst, "CallObjectCreate() failed.", 0L);
  1819. ListenObjectUnlock(pListenObject);
  1820. return;
  1821. }
  1822. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  1823. {
  1824. ISRERROR(ghISRInst, "CallObjectLock() returned error", 0L);
  1825. ListenObjectUnlock(pListenObject);
  1826. return;
  1827. }
  1828. TempResult = linkLayerInit(&pCallObject->dwPhysicalId, hQ931Call,
  1829. Q931ReceiveCallback, Q931SendComplete);
  1830. if (FAILED(TempResult))
  1831. {
  1832. ISRERROR(ghISRInst, "linkLayerInit() failed", 0);
  1833. linkLayerReject(pListenObject->dwPhysicalId);
  1834. CallObjectDestroy(pCallObject);
  1835. ListenObjectUnlock(pListenObject);
  1836. return;
  1837. }
  1838. // pCallObject->bCallState = CALLSTATE_NULL;
  1839. // unlock CallObject before calling down into h245ws in order to prevent deadlock - which
  1840. // is probably unlikely with linkLayerAccept(), but just to be safe and consistent...
  1841. // not sure if we need to worry about unlocking the listen object???
  1842. dwPhysicalId = pCallObject->dwPhysicalId;
  1843. CallObjectUnlock(pCallObject);
  1844. TempResult = linkLayerAccept(pListenObject->dwPhysicalId,
  1845. dwPhysicalId, Q931ConnectCallback);
  1846. if (FAILED(TempResult))
  1847. {
  1848. if((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  1849. {
  1850. ListenObjectUnlock(pListenObject);
  1851. return;
  1852. }
  1853. ISRERROR(ghISRInst, "linkLayerAccept() failed", 0);
  1854. {
  1855. DWORD dwId = pCallObject->dwPhysicalId;
  1856. CallObjectDestroy(pCallObject);
  1857. linkLayerShutdown(dwId);
  1858. }
  1859. ListenObjectUnlock(pListenObject);
  1860. return;
  1861. }
  1862. ListenObjectUnlock(pListenObject);
  1863. }
  1864. //====================================================================================
  1865. //
  1866. // PUBLIC FUNCTIONS
  1867. //
  1868. //====================================================================================
  1869. //====================================================================================
  1870. //====================================================================================
  1871. CS_STATUS
  1872. H225Init()
  1873. {
  1874. CS_STATUS result;
  1875. if (H225_InitModule() != ASN1_SUCCESS)
  1876. {
  1877. ASSERT(FALSE);
  1878. return CS_SUBSYSTEM_FAILURE;
  1879. }
  1880. return CS_OK;
  1881. }
  1882. CS_STATUS
  1883. H225DeInit()
  1884. {
  1885. CS_STATUS result;
  1886. result = H225_TermModule();
  1887. if (result != CS_OK)
  1888. {
  1889. return CS_SUBSYSTEM_FAILURE;
  1890. }
  1891. return CS_OK;
  1892. }
  1893. CS_STATUS
  1894. Q931Init()
  1895. {
  1896. CS_STATUS result;
  1897. if (bQ931Initialized == TRUE)
  1898. {
  1899. ASSERT(FALSE);
  1900. return CS_DUPLICATE_INITIALIZE;
  1901. }
  1902. bQ931Initialized = TRUE;
  1903. // Register Call Setup for debug output
  1904. ISRREGISTERMODULE(&ghISRInst, "Q931", "Q931 Call Setup");
  1905. // Initialize the current conference ID to 0's, which is intentionally
  1906. // assigned to an invalid conference ID. Must create one for it
  1907. // to be valid.
  1908. memset(&(ConferenceIDSource), 0, sizeof(ConferenceIDSource));
  1909. InitializeCriticalSection(&(ConferenceIDSource.Lock));
  1910. if ((result = ListenListCreate()) != CS_OK)
  1911. {
  1912. return result;
  1913. }
  1914. if ((result = CallListCreate()) != CS_OK)
  1915. {
  1916. ListenListDestroy();
  1917. return result;
  1918. }
  1919. // init protocol ID structures
  1920. Q931PduInit();
  1921. #if (defined(_DEBUG) || defined(PCS_COMPLIANCE))
  1922. Q931Logger = InteropLoad(Q931LOG_PROTOCOL);
  1923. #endif
  1924. return CS_OK;
  1925. }
  1926. //====================================================================================
  1927. //====================================================================================
  1928. CS_STATUS
  1929. Q931DeInit()
  1930. {
  1931. CS_STATUS result1;
  1932. CS_STATUS result2;
  1933. if (bQ931Initialized == FALSE)
  1934. {
  1935. return CS_NOT_INITIALIZED;
  1936. }
  1937. #if (defined(_DEBUG) || defined(PCS_COMPLIANCE))
  1938. // This causes a protection exception, so don't do it for now. DAC 12/9/96
  1939. // InteropUnload(Q931Logger);
  1940. #endif
  1941. result1 = ListenListDestroy();
  1942. result2 = CallListDestroy();
  1943. DeleteCriticalSection(&(ConferenceIDSource.Lock));
  1944. bQ931Initialized = FALSE;
  1945. if (result1 != CS_OK)
  1946. {
  1947. return result1;
  1948. }
  1949. return result2;
  1950. }
  1951. //====================================================================================
  1952. //====================================================================================
  1953. CS_STATUS
  1954. Q931Listen(
  1955. PHQ931LISTEN phQ931Listen,
  1956. PCC_ADDR pListenAddr,
  1957. DWORD_PTR dwListenToken,
  1958. Q931_CALLBACK ListenCallback)
  1959. {
  1960. CS_STATUS CreateObjectResult;
  1961. P_LISTEN_OBJECT pListenObject = NULL;
  1962. HRESULT TempResult;
  1963. // make sure q931 is initialized with an initialize flag.
  1964. if (bQ931Initialized == FALSE)
  1965. {
  1966. return CS_NOT_INITIALIZED;
  1967. }
  1968. // make sure parms are validated.
  1969. if ((phQ931Listen == NULL) || (ListenCallback == NULL) || (pListenAddr == NULL))
  1970. {
  1971. ASSERT(FALSE);
  1972. return CS_BAD_PARAM;
  1973. }
  1974. SetDefaultPort(pListenAddr);
  1975. // create listen object with all known attributes of this listen session.
  1976. // a handle of the listen object is returned in phQ931Listen.
  1977. CreateObjectResult = ListenObjectCreate(phQ931Listen, dwListenToken, ListenCallback);
  1978. if (CreateObjectResult != CS_OK)
  1979. {
  1980. return CS_SUBSYSTEM_FAILURE;
  1981. }
  1982. if (ListenObjectLock(*phQ931Listen, &pListenObject) != CS_OK)
  1983. {
  1984. return CS_BAD_PARAM;
  1985. }
  1986. TempResult = linkLayerListen(&pListenObject->dwPhysicalId, *phQ931Listen,
  1987. pListenAddr, Q931ListenCallback);
  1988. ListenObjectUnlock(pListenObject);
  1989. if (FAILED(TempResult))
  1990. {
  1991. ISRTRACE(ghISRInst, "Q931Listen() linkLayerListen failed.", 0L);
  1992. return TempResult;
  1993. }
  1994. ISRTRACE(ghISRInst, "Q931Listen() completed successfully.", 0L);
  1995. return CS_OK;
  1996. }
  1997. //====================================================================================
  1998. // In the old code, this blocked until thread and socket were finished
  1999. // closing...
  2000. //====================================================================================
  2001. CS_STATUS
  2002. Q931CancelListen(
  2003. HQ931LISTEN hQ931Listen)
  2004. {
  2005. P_LISTEN_OBJECT pListenObject = NULL;
  2006. CS_STATUS Status;
  2007. // make sure q931 is initialized with an initialize flag.
  2008. if (bQ931Initialized == FALSE)
  2009. {
  2010. return CS_NOT_INITIALIZED;
  2011. }
  2012. ISRTRACE(ghISRInst, "Q931CancelListen() finding listen object...", 0L);
  2013. // lock the listen object, get the event to wait for, and unlock the listen object.
  2014. if (ListenObjectLock(hQ931Listen, &pListenObject) != CS_OK)
  2015. {
  2016. return CS_BAD_PARAM;
  2017. }
  2018. {
  2019. DWORD dwId = pListenObject->dwPhysicalId;
  2020. linkLayerShutdown(dwId);
  2021. // destroy the object. dont need to unlock it since entire object will be destroyed.
  2022. ISRTRACE(ghISRInst, "Q931CancelListen(): destroying listen object...", 0L);
  2023. Status = ListenObjectDestroy(pListenObject);
  2024. }
  2025. return Status;
  2026. }
  2027. //====================================================================================
  2028. //====================================================================================
  2029. CS_STATUS
  2030. Q931PlaceCall(
  2031. PHQ931CALL phQ931Call,
  2032. LPWSTR pszDisplay,
  2033. PCC_ALIASNAMES pCallerAliasList,
  2034. PCC_ALIASNAMES pCalleeAliasList,
  2035. PCC_ALIASNAMES pExtraAliasList,
  2036. PCC_ALIASITEM pExtensionAliasItem,
  2037. PCC_NONSTANDARDDATA pNonStandardData,
  2038. PCC_ENDPOINTTYPE pSourceEndpointType,
  2039. LPWSTR pszCalledPartyNumber,
  2040. PCC_ADDR pControlAddr,
  2041. PCC_ADDR pDestinationAddr,
  2042. PCC_ADDR pSourceAddr,
  2043. BOOL bCallerIsMC,
  2044. CC_CONFERENCEID *pConferenceID,
  2045. WORD wGoal,
  2046. WORD wCallType,
  2047. DWORD_PTR dwUserToken,
  2048. Q931_CALLBACK ConnectCallback,
  2049. WORD wCRV,
  2050. LPGUID pCallIdentifier)
  2051. {
  2052. CS_STATUS CreateObjectResult;
  2053. P_CALL_OBJECT pCallObject = NULL;
  2054. CC_ADDR PeerCallAddr;
  2055. CC_ADDR PeerConnectAddr;
  2056. CC_ADDR SourceAddr;
  2057. HRESULT TempResult;
  2058. char szAsciiDisplay[CC_MAX_DISPLAY_LENGTH + 1];
  2059. char szAsciiPartyNumber[CC_MAX_PARTY_NUMBER_LEN + 1];
  2060. DWORD dwPhysicalId;
  2061. // make sure q931 is initialized with an initialize flag.
  2062. if (bQ931Initialized == FALSE)
  2063. {
  2064. return CS_NOT_INITIALIZED;
  2065. }
  2066. // make sure parms are validated.
  2067. if ((phQ931Call == NULL) || (ConnectCallback == NULL) ||
  2068. ((pControlAddr == NULL) && (pDestinationAddr == NULL)) ||
  2069. (pSourceEndpointType == NULL))
  2070. {
  2071. return CS_BAD_PARAM;
  2072. }
  2073. {
  2074. CS_STATUS TempStatus;
  2075. TempStatus = Q931ValidateAddr(pControlAddr);
  2076. if (TempStatus != CS_OK)
  2077. {
  2078. return TempStatus;
  2079. }
  2080. TempStatus = Q931ValidateAddr(pDestinationAddr);
  2081. if (TempStatus != CS_OK)
  2082. {
  2083. return TempStatus;
  2084. }
  2085. TempStatus = Q931ValidateAddr(pSourceAddr);
  2086. if (TempStatus != CS_OK)
  2087. {
  2088. return TempStatus;
  2089. }
  2090. TempStatus = Q931ValidateVendorInfo(pSourceEndpointType->pVendorInfo);
  2091. if (TempStatus != CS_OK)
  2092. {
  2093. return TempStatus;
  2094. }
  2095. TempStatus = Q931ValidateDisplay(pszDisplay);
  2096. if (TempStatus != CS_OK)
  2097. {
  2098. return TempStatus;
  2099. }
  2100. TempStatus = Q931ValidatePartyNumber(pszCalledPartyNumber);
  2101. if (TempStatus != CS_OK)
  2102. {
  2103. return TempStatus;
  2104. }
  2105. szAsciiDisplay[0] = '\0';
  2106. if (pszDisplay && WideCharToMultiByte(CP_ACP, 0, pszDisplay, -1, szAsciiDisplay,
  2107. sizeof(szAsciiDisplay), NULL, NULL) == 0)
  2108. {
  2109. return CS_BAD_PARAM;
  2110. }
  2111. szAsciiPartyNumber[0] = '\0';
  2112. if (pszCalledPartyNumber && WideCharToMultiByte(CP_ACP, 0, pszCalledPartyNumber, -1, szAsciiPartyNumber,
  2113. sizeof(szAsciiPartyNumber), NULL, NULL) == 0)
  2114. {
  2115. return CS_BAD_PARAM;
  2116. }
  2117. TempStatus = Q931ValidateNonStandardData(pNonStandardData);
  2118. if (TempStatus != CS_OK)
  2119. {
  2120. return TempStatus;
  2121. }
  2122. TempStatus = Q931ValidateAliasNames(pCallerAliasList);
  2123. if (TempStatus != CS_OK)
  2124. {
  2125. return TempStatus;
  2126. }
  2127. TempStatus = Q931ValidateAliasNames(pCalleeAliasList);
  2128. if (TempStatus != CS_OK)
  2129. {
  2130. return TempStatus;
  2131. }
  2132. TempStatus = Q931ValidateAliasNames(pExtraAliasList);
  2133. if (TempStatus != CS_OK)
  2134. {
  2135. return TempStatus;
  2136. }
  2137. TempStatus = Q931ValidateAliasItem(pExtensionAliasItem);
  2138. if (TempStatus != CS_OK)
  2139. {
  2140. return TempStatus;
  2141. }
  2142. }
  2143. // get the correct callee and control address to use for the call.
  2144. if (pDestinationAddr)
  2145. {
  2146. if (!MakeBinaryADDR(pDestinationAddr, &PeerCallAddr))
  2147. {
  2148. return CS_BAD_PARAM;
  2149. }
  2150. SetDefaultPort(&PeerCallAddr);
  2151. }
  2152. if (pControlAddr)
  2153. {
  2154. if (!MakeBinaryADDR(pControlAddr, &PeerConnectAddr))
  2155. {
  2156. return CS_BAD_PARAM;
  2157. }
  2158. SetDefaultPort(&PeerConnectAddr);
  2159. }
  2160. else
  2161. {
  2162. PeerConnectAddr = PeerCallAddr;
  2163. }
  2164. // get the correct callee and control address to use for the call.
  2165. if (pSourceAddr)
  2166. {
  2167. if (!MakeBinaryADDR(pSourceAddr, &SourceAddr))
  2168. {
  2169. return CS_BAD_PARAM;
  2170. }
  2171. SetDefaultPort(&SourceAddr);
  2172. }
  2173. if (wGoal == CSG_CREATE)
  2174. {
  2175. // caller is asking to start a new conference.
  2176. if (((DWORD *)pConferenceID->buffer)[0] == 0 &&
  2177. ((DWORD *)pConferenceID->buffer)[1] == 0 &&
  2178. ((DWORD *)pConferenceID->buffer)[2] == 0 &&
  2179. ((DWORD *)pConferenceID->buffer)[3] == 0)
  2180. {
  2181. _ConferenceIDNew(pConferenceID);
  2182. }
  2183. }
  2184. // create call object with all known attributes of this call.
  2185. // a handle of the call object is returned in phQ931Call.
  2186. CreateObjectResult = CallObjectCreate(phQ931Call,
  2187. CC_INVALID_HANDLE,
  2188. dwUserToken,
  2189. ConnectCallback,
  2190. TRUE, // I am the caller.
  2191. NULL, // no local address yet.
  2192. &PeerConnectAddr,
  2193. pDestinationAddr ? &PeerCallAddr : NULL,
  2194. pSourceAddr ? &SourceAddr : NULL,
  2195. pConferenceID,
  2196. wGoal,
  2197. wCallType,
  2198. bCallerIsMC,
  2199. pszDisplay ? szAsciiDisplay : NULL,
  2200. pszCalledPartyNumber ? szAsciiPartyNumber : NULL,
  2201. pCallerAliasList,
  2202. pCalleeAliasList,
  2203. pExtraAliasList,
  2204. pExtensionAliasItem,
  2205. pSourceEndpointType,
  2206. pNonStandardData,
  2207. wCRV,
  2208. pCallIdentifier);
  2209. if (CreateObjectResult != CS_OK)
  2210. {
  2211. return CS_SUBSYSTEM_FAILURE;
  2212. }
  2213. if ((CallObjectLock(*phQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  2214. {
  2215. ISRERROR(ghISRInst, "CallObjectLock() returned error", 0L);
  2216. return CS_SUBSYSTEM_FAILURE;
  2217. }
  2218. TempResult = linkLayerInit(&pCallObject->dwPhysicalId, *phQ931Call,
  2219. Q931ReceiveCallback, Q931SendComplete);
  2220. if (FAILED(TempResult))
  2221. {
  2222. ISRERROR(ghISRInst, "linkLayerInit() failed", 0);
  2223. CallObjectDestroy(pCallObject);
  2224. *phQ931Call = 0;
  2225. return TempResult;
  2226. }
  2227. // unlock CallObject before calling down into h245ws in order to prevent deadlock - which
  2228. // is probably unlikely with linkLayerConnect(), but just to be safe and consistent...
  2229. dwPhysicalId = pCallObject->dwPhysicalId;
  2230. CallObjectUnlock(pCallObject);
  2231. TempResult = linkLayerConnect(dwPhysicalId, &PeerConnectAddr,
  2232. Q931ConnectCallback);
  2233. if((CallObjectLock(*phQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  2234. {
  2235. *phQ931Call = 0;
  2236. return(CS_INTERNAL_ERROR);
  2237. }
  2238. if (FAILED(TempResult))
  2239. {
  2240. ISRERROR(ghISRInst, "linkLayerConnect() failed", 0);
  2241. {
  2242. DWORD dwId = pCallObject->dwPhysicalId;
  2243. CallObjectDestroy(pCallObject);
  2244. linkLayerShutdown(dwId);
  2245. }
  2246. *phQ931Call = 0;
  2247. return TempResult;
  2248. }
  2249. // pCallObject->bCallState = CALLSTATE_NULL;
  2250. CallObjectUnlock(pCallObject);
  2251. ISRTRACE(ghISRInst, "Q931PlaceCall() completed successfully.", 0L);
  2252. return CS_OK;
  2253. }
  2254. //====================================================================================
  2255. // In the old code, this blocked until thread and socket were finished
  2256. // closing...
  2257. //====================================================================================
  2258. CS_STATUS
  2259. Q931Hangup(
  2260. HQ931CALL hQ931Call,
  2261. BYTE bReason)
  2262. {
  2263. P_CALL_OBJECT pCallObject = NULL;
  2264. CS_STATUS Status;
  2265. if (bQ931Initialized == FALSE)
  2266. {
  2267. return CS_NOT_INITIALIZED;
  2268. }
  2269. ISRTRACE(ghISRInst, "Entering Q931Hangup()...", 0L);
  2270. // need parameter checking...
  2271. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  2272. {
  2273. ISRTRACE(ghISRInst, "Call Object no longer available:", (DWORD)hQ931Call);
  2274. return CS_BAD_PARAM;
  2275. }
  2276. {
  2277. CS_STATUS SendStatus = CS_OK;
  2278. if (pCallObject->bCallState != CALLSTATE_NULL)
  2279. {
  2280. // send the RELEASE COMPLETE message to the peer to hang-up.
  2281. SendStatus = Q931SendReleaseCompleteMessage(pCallObject,
  2282. bReason, &(pCallObject->ConferenceID), NULL, NULL);
  2283. }
  2284. {
  2285. DWORD dwId = pCallObject->dwPhysicalId;
  2286. Status = CallObjectDestroy(pCallObject);
  2287. linkLayerShutdown(dwId);
  2288. }
  2289. if (FAILED(SendStatus))
  2290. {
  2291. return SendStatus;
  2292. }
  2293. }
  2294. return Status;
  2295. }
  2296. //====================================================================================
  2297. //====================================================================================
  2298. CS_STATUS
  2299. Q931AcceptCall(
  2300. HQ931CALL hQ931Call,
  2301. LPWSTR pszDisplay,
  2302. PCC_NONSTANDARDDATA pNonStandardData,
  2303. PCC_ENDPOINTTYPE pDestinationEndpointType,
  2304. PCC_ADDR pH245Addr,
  2305. DWORD_PTR dwUserToken)
  2306. {
  2307. P_CALL_OBJECT pCallObject = NULL;
  2308. CS_STATUS result = CS_OK;
  2309. char szAsciiDisplay[CC_MAX_DISPLAY_LENGTH + 1];
  2310. if (bQ931Initialized == FALSE)
  2311. {
  2312. return CS_NOT_INITIALIZED;
  2313. }
  2314. ISRTRACE(ghISRInst, "Entering Q931AcceptCall()...", 0L);
  2315. if ((pDestinationEndpointType == NULL) ||
  2316. (pDestinationEndpointType->pVendorInfo == NULL))
  2317. {
  2318. return CS_BAD_PARAM;
  2319. }
  2320. {
  2321. CS_STATUS TempStatus;
  2322. TempStatus = Q931ValidateVendorInfo(pDestinationEndpointType->pVendorInfo);
  2323. if (TempStatus != CS_OK)
  2324. {
  2325. return TempStatus;
  2326. }
  2327. TempStatus = Q931ValidateDisplay(pszDisplay);
  2328. if (TempStatus != CS_OK)
  2329. {
  2330. return TempStatus;
  2331. }
  2332. szAsciiDisplay[0] = '\0';
  2333. if (pszDisplay && WideCharToMultiByte(CP_ACP, 0, pszDisplay, -1, szAsciiDisplay,
  2334. sizeof(szAsciiDisplay), NULL, NULL) == 0)
  2335. {
  2336. return CS_BAD_PARAM;
  2337. }
  2338. TempStatus = Q931ValidateNonStandardData(pNonStandardData);
  2339. if (TempStatus != CS_OK)
  2340. {
  2341. return TempStatus;
  2342. }
  2343. }
  2344. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  2345. {
  2346. ISRERROR(ghISRInst, "CallObjectLock() returned error (Socket not found).", 0L);
  2347. return CS_INTERNAL_ERROR;
  2348. }
  2349. if (pCallObject->fIsCaller)
  2350. {
  2351. ISRERROR(ghISRInst, "Caller attempted to accept call.", 0L);
  2352. CallObjectUnlock(pCallObject);
  2353. return CS_OUT_OF_SEQUENCE;
  2354. }
  2355. // label with the user supplied UserToken for this call object.
  2356. pCallObject->dwUserToken = dwUserToken;
  2357. // send the CONNECT message to peer to accept call.
  2358. {
  2359. DWORD CodedLengthASN;
  2360. BYTE *CodedPtrASN;
  2361. HRESULT ResultASN = CS_OK;
  2362. CC_ADDR h245Addr;
  2363. if (pH245Addr != NULL)
  2364. {
  2365. MakeBinaryADDR(pH245Addr, &h245Addr);
  2366. }
  2367. ResultASN = Q931ConnectEncodeASN(pNonStandardData,
  2368. &(pCallObject->ConferenceID),
  2369. (pH245Addr ? &h245Addr : NULL),
  2370. pDestinationEndpointType,
  2371. &pCallObject->World,
  2372. &CodedPtrASN,
  2373. &CodedLengthASN,
  2374. &pCallObject->CallIdentifier);
  2375. if ((ResultASN != CS_OK) || (CodedLengthASN == 0) ||
  2376. (CodedPtrASN == NULL))
  2377. {
  2378. ISRERROR(ghISRInst, "Q931ConnectEncodeASN() failed, nothing to send.", 0L);
  2379. if (CodedPtrASN != NULL)
  2380. {
  2381. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  2382. }
  2383. CallObjectUnlock(pCallObject);
  2384. return CS_SUBSYSTEM_FAILURE;
  2385. }
  2386. else
  2387. {
  2388. DWORD CodedLengthPDU;
  2389. BYTE *CodedPtrPDU;
  2390. BINARY_STRING UserUserData;
  2391. HRESULT ResultEncode = CS_OK;
  2392. HRESULT TempResult;
  2393. WORD wCRV = (WORD)(pCallObject->wCRV | 0x8000);
  2394. UserUserData.length = (WORD)CodedLengthASN;
  2395. UserUserData.ptr = CodedPtrASN;
  2396. ResultEncode = Q931ConnectEncodePDU(wCRV,
  2397. szAsciiDisplay, &UserUserData, &CodedPtrPDU, &CodedLengthPDU);
  2398. if (CodedPtrASN != NULL)
  2399. {
  2400. Q931FreeEncodedBuffer(&pCallObject->World, CodedPtrASN);
  2401. }
  2402. if ((ResultEncode != CS_OK) || (CodedLengthPDU == 0) ||
  2403. (CodedPtrPDU == NULL))
  2404. {
  2405. ISRERROR(ghISRInst, "Q931ConnectEncodePDU() failed, nothing to send.", 0L);
  2406. if (CodedPtrPDU != NULL)
  2407. {
  2408. MemFree(CodedPtrPDU);
  2409. }
  2410. CallObjectUnlock(pCallObject);
  2411. return CS_SUBSYSTEM_FAILURE;
  2412. }
  2413. TempResult = Q931SendMessage(pCallObject, CodedPtrPDU, CodedLengthPDU, TRUE);
  2414. if (CallObjectValidate(hQ931Call) != CS_OK)
  2415. return CS_INTERNAL_ERROR;
  2416. if (FAILED(TempResult))
  2417. {
  2418. ISRERROR(ghISRInst, "datalinkSendRequest() failed", 0);
  2419. if (CodedPtrPDU != NULL)
  2420. {
  2421. MemFree(CodedPtrPDU);
  2422. }
  2423. // when the connect notification fails...what should we do anyway????
  2424. CallObjectUnlock(pCallObject);
  2425. return TempResult;
  2426. }
  2427. }
  2428. }
  2429. pCallObject->bCallState = CALLSTATE_ACTIVE;
  2430. CallObjectUnlock(pCallObject);
  2431. return CS_OK;
  2432. }
  2433. //====================================================================================
  2434. //====================================================================================
  2435. CS_STATUS
  2436. Q931RejectCall(
  2437. HQ931CALL hQ931Call,
  2438. BYTE bRejectReason,
  2439. PCC_CONFERENCEID pConferenceID,
  2440. PCC_ADDR pAlternateAddr,
  2441. PCC_NONSTANDARDDATA pNonStandardData)
  2442. {
  2443. P_CALL_OBJECT pCallObject = NULL;
  2444. CS_STATUS result = CS_OK;
  2445. CS_STATUS Status = CS_OK;
  2446. if (bQ931Initialized == FALSE)
  2447. {
  2448. return CS_NOT_INITIALIZED;
  2449. }
  2450. ISRTRACE(ghISRInst, "Entering Q931RejectCall()...", 0L);
  2451. {
  2452. CS_STATUS TempStatus;
  2453. TempStatus = Q931ValidateNonStandardData(pNonStandardData);
  2454. if (TempStatus != CS_OK)
  2455. {
  2456. return TempStatus;
  2457. }
  2458. }
  2459. // if reason is alternate addr, but there is no alternate addr -->err
  2460. if (((bRejectReason == CC_REJECT_ROUTE_TO_GATEKEEPER) ||
  2461. (bRejectReason == CC_REJECT_CALL_FORWARDED) ||
  2462. (bRejectReason == CC_REJECT_ROUTE_TO_MC)) &&
  2463. (pAlternateAddr == NULL))
  2464. {
  2465. return CS_BAD_PARAM;
  2466. }
  2467. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  2468. {
  2469. ISRERROR(ghISRInst, "CallObjectLock() returned error (Socket not found).", 0L);
  2470. return CS_INTERNAL_ERROR;
  2471. }
  2472. if (pCallObject->fIsCaller)
  2473. {
  2474. ISRERROR(ghISRInst, "Caller attempted to reject call.", 0L);
  2475. CallObjectUnlock(pCallObject);
  2476. return CS_OUT_OF_SEQUENCE;
  2477. }
  2478. result = Q931SendReleaseCompleteMessage(pCallObject,
  2479. bRejectReason, pConferenceID, pAlternateAddr, pNonStandardData);
  2480. {
  2481. DWORD dwId = pCallObject->dwPhysicalId;
  2482. Status = CallObjectDestroy(pCallObject);
  2483. linkLayerShutdown(dwId);
  2484. }
  2485. if (result != CS_OK)
  2486. {
  2487. return result;
  2488. }
  2489. return Status;
  2490. }
  2491. //====================================================================================
  2492. //====================================================================================
  2493. CS_STATUS
  2494. Q931ReOpenConnection(
  2495. HQ931CALL hQ931Call)
  2496. {
  2497. P_CALL_OBJECT pCallObject = NULL;
  2498. HRESULT TempResult = CS_OK;
  2499. CC_ADDR PeerConnectAddr;
  2500. DWORD dwPhysicalId;
  2501. if (bQ931Initialized == FALSE)
  2502. {
  2503. return CS_NOT_INITIALIZED;
  2504. }
  2505. ISRTRACE(ghISRInst, "Entering Q931ReOpenConnection()...", 0L);
  2506. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  2507. {
  2508. ISRERROR(ghISRInst, "CallObjectLock() returned error.", 0L);
  2509. return CS_INTERNAL_ERROR;
  2510. }
  2511. if (pCallObject->bConnected)
  2512. {
  2513. return CS_OUT_OF_SEQUENCE;
  2514. }
  2515. Q931MakePhysicalID(&pCallObject->dwPhysicalId);
  2516. TempResult = linkLayerInit(&pCallObject->dwPhysicalId, hQ931Call,
  2517. Q931ReceiveCallback, Q931SendComplete);
  2518. if (FAILED(TempResult))
  2519. {
  2520. ISRERROR(ghISRInst, "linkLayerInit() failed on re-connect.", 0);
  2521. CallObjectUnlock(pCallObject);
  2522. return TempResult;
  2523. }
  2524. // unlock CallObject before calling down into h245ws in order to prevent deadlock - which
  2525. // is probably unlikely with linkLayerConnect, but just to be safe and consistent...
  2526. // copy stuff we need out of call object before we unlock it
  2527. dwPhysicalId = pCallObject->dwPhysicalId;
  2528. PeerConnectAddr = pCallObject->PeerConnectAddr;
  2529. CallObjectUnlock(pCallObject);
  2530. TempResult = linkLayerConnect(dwPhysicalId,
  2531. &PeerConnectAddr, Q931ConnectCallback);
  2532. if((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  2533. {
  2534. return(CS_INTERNAL_ERROR);
  2535. }
  2536. if (FAILED(TempResult))
  2537. {
  2538. ISRERROR(ghISRInst, "linkLayerConnect() failed on re-connect.", 0);
  2539. linkLayerShutdown(pCallObject->dwPhysicalId);
  2540. CallObjectUnlock(pCallObject);
  2541. return TempResult;
  2542. }
  2543. CallObjectUnlock(pCallObject);
  2544. ISRTRACE(ghISRInst, "Q931ReOpenConnection() completed successfully.", 0L);
  2545. return CS_OK;
  2546. }
  2547. //====================================================================================
  2548. //====================================================================================
  2549. CS_STATUS
  2550. Q931GetVersion(
  2551. WORD wLength,
  2552. LPWSTR pszVersion)
  2553. {
  2554. WCHAR pszQ931Version[255];
  2555. // parameter validation.
  2556. if ((wLength == 0) || (pszVersion == NULL))
  2557. {
  2558. return CS_BAD_PARAM;
  2559. }
  2560. wcscpy(pszQ931Version, L"Call Setup ");
  2561. wcscat(pszQ931Version, Unicode(__DATE__));
  2562. wcscat(pszQ931Version, L" ");
  2563. wcscat(pszQ931Version, Unicode(__TIME__));
  2564. if (wcslen(pszQ931Version) >= wLength)
  2565. {
  2566. memcpy(pszVersion, pszQ931Version, (wLength-1)*sizeof(WCHAR));
  2567. pszQ931Version[wLength-1] = L'\0';
  2568. return CS_BAD_SIZE;
  2569. }
  2570. wcscpy(pszVersion, pszQ931Version);
  2571. return CS_OK;
  2572. }
  2573. //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2574. // Timer Routines...
  2575. //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2576. //====================================================================================
  2577. // Timer 301 has expired for this object...
  2578. //====================================================================================
  2579. void
  2580. CallBackT301(P_CALL_OBJECT pCallObject)
  2581. {
  2582. CSS_CALL_FAILED EventData;
  2583. HQ931CALL hQ931Call = pCallObject->hQ931Call;
  2584. EventData.error = CS_RINGING_TIMER_EXPIRED;
  2585. pCallObject->Callback(Q931_CALL_FAILED, pCallObject->hQ931Call,
  2586. pCallObject->dwListenToken,
  2587. pCallObject->dwUserToken, &EventData);
  2588. if (CallObjectValidate(hQ931Call) == CS_OK)
  2589. {
  2590. if (Q931SendReleaseCompleteMessage(pCallObject,
  2591. CC_REJECT_TIMER_EXPIRED, NULL, NULL, NULL) == CS_OK)
  2592. {
  2593. // nothing to do...
  2594. }
  2595. {
  2596. DWORD dwId = pCallObject->dwPhysicalId;
  2597. CallObjectDestroy(pCallObject);
  2598. linkLayerShutdown(dwId);
  2599. }
  2600. }
  2601. return;
  2602. }
  2603. //====================================================================================
  2604. // Timer 303 has expired for this object...
  2605. //====================================================================================
  2606. void
  2607. CallBackT303(P_CALL_OBJECT pCallObject)
  2608. {
  2609. CSS_CALL_FAILED EventData;
  2610. HQ931CALL hQ931Call = pCallObject->hQ931Call;
  2611. EventData.error = CS_SETUP_TIMER_EXPIRED;
  2612. pCallObject->Callback(Q931_CALL_FAILED, pCallObject->hQ931Call,
  2613. pCallObject->dwListenToken,
  2614. pCallObject->dwUserToken, &EventData);
  2615. if (CallObjectValidate(hQ931Call) == CS_OK)
  2616. {
  2617. if (Q931SendReleaseCompleteMessage(pCallObject,
  2618. CC_REJECT_TIMER_EXPIRED, NULL, NULL, NULL) == CS_OK)
  2619. {
  2620. // nothing to do...
  2621. }
  2622. {
  2623. DWORD dwId = pCallObject->dwPhysicalId;
  2624. CallObjectDestroy(pCallObject);
  2625. linkLayerShutdown(dwId);
  2626. }
  2627. }
  2628. return;
  2629. }
  2630. //====================================================================================
  2631. //====================================================================================
  2632. void
  2633. Q931SetReceivePDUHook(Q931_RECEIVE_PDU_CALLBACK Q931ReceivePDUCallback)
  2634. {
  2635. gReceivePDUHookProc = Q931ReceivePDUCallback;
  2636. return;
  2637. }
  2638. //====================================================================================
  2639. //====================================================================================
  2640. CS_STATUS
  2641. Q931FlushSendQueue(
  2642. HQ931CALL hQ931Call)
  2643. {
  2644. P_CALL_OBJECT pCallObject = NULL;
  2645. HRESULT TempResult = CS_OK;
  2646. DWORD dwPhysicalId;
  2647. if (bQ931Initialized == FALSE)
  2648. {
  2649. return CS_NOT_INITIALIZED;
  2650. }
  2651. ISRTRACE(ghISRInst, "Entering Q931FlushSendQueue()...", 0L);
  2652. // need parameter checking...
  2653. if ((CallObjectLock(hQ931Call, &pCallObject) != CS_OK) || (pCallObject == NULL))
  2654. {
  2655. ISRTRACE(ghISRInst, "Call Object no longer available:", (DWORD)hQ931Call);
  2656. return CS_INTERNAL_ERROR;
  2657. }
  2658. dwPhysicalId = pCallObject->dwPhysicalId;
  2659. CallObjectUnlock(pCallObject);
  2660. TempResult = linkLayerFlushChannel(dwPhysicalId, DATALINK_TRANSMIT);
  2661. if (FAILED(TempResult))
  2662. {
  2663. ISRERROR(ghISRInst, "datalinkSendRequest() failed", 0L);
  2664. }
  2665. return(TempResult);
  2666. }
  2667. #ifdef __cplusplus
  2668. }
  2669. #endif
  2670.