Leaked source code of windows server 2003
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.

11845 lines
323 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. call.cpp
  5. Abstract:
  6. TAPI Service Provider functions related to manipulating calls.
  7. TSPI_lineAnswer
  8. TSPI_lineCloseCall
  9. TSPI_lineDrop
  10. TSPI_lineGetCallAddressID
  11. TSPI_lineGetCallInfo
  12. TSPI_lineGetCallStatus
  13. TSPI_lineMakeCall
  14. TSPI_lineMonitorDigits
  15. TSPI_lineSendUserUserInfo
  16. TSPI_lineReleaseUserUserInfo
  17. Author:
  18. Nikhil Bobde (NikhilB)
  19. Revision History:
  20. --*/
  21. //
  22. // Include files
  23. //
  24. #include "globals.h"
  25. #include "line.h"
  26. #include "q931pdu.h"
  27. #include "q931obj.h"
  28. #include "ras.h"
  29. #include "config.h"
  30. #define SETUP_SENT_TIMEOUT 8000
  31. #define H450_ENCODED_ARG_LEN 0x4000
  32. #define MAX_DIVERSION_COUNTER 14
  33. static LONG g_H323CallID;
  34. static LONG g_lNumberOfcalls;
  35. LONG g_lCallReference;
  36. //
  37. // Public functions
  38. //
  39. //
  40. //The function that handles a network event(CONNECT|CLOSE) on any of the
  41. //Q931 calls. This function needs to find out the exact event
  42. // that took place and the socket on which it took place
  43. //
  44. void NTAPI Q931TransportEventHandler (
  45. IN PVOID Parameter,
  46. IN BOOLEAN TimerFired)
  47. {
  48. PH323_CALL pCall;
  49. H323DBG(( DEBUG_LEVEL_TRACE, "Q931 transport event recvd." ));
  50. pCall = g_pH323Line -> FindH323CallAndLock ((HDRVCALL) Parameter);
  51. if( pCall != NULL )
  52. {
  53. pCall -> HandleTransportEvent();
  54. pCall -> Unlock();
  55. }
  56. }
  57. //
  58. // returns S_OK if socket was consumed
  59. // returns E_FAIL if socket should be destroyed by caller
  60. //
  61. static HRESULT CallCreateIncomingCall (
  62. IN SOCKET Socket,
  63. IN SOCKADDR_IN * LocalAddress,
  64. IN SOCKADDR_IN * RemoteAddress)
  65. {
  66. PH323_CALL pCall;
  67. HANDLE SelectEvent;
  68. HANDLE SelectWaitHandle;
  69. BOOL fSuccess = TRUE;
  70. BOOL DeleteCall = FALSE;
  71. TCHAR ptstrEventName[100];
  72. BOOL retVal;
  73. pCall = new CH323Call;
  74. if( pCall == NULL )
  75. {
  76. H323DBG(( DEBUG_LEVEL_ERROR,
  77. "failed to allocate memory for CH323Call." ));
  78. return E_OUTOFMEMORY;
  79. }
  80. _stprintf( ptstrEventName, _T("%s-%p"),
  81. _T( "H323TSP_Incoming_TransportHandlerEvent" ), pCall );
  82. // create the wait event
  83. SelectEvent = H323CreateEvent (NULL, FALSE,
  84. FALSE, ptstrEventName );
  85. if( SelectEvent == NULL )
  86. {
  87. H323DBG(( DEBUG_LEVEL_ERROR, "CALL: failed to create select event." ));
  88. delete pCall;
  89. return GetLastResult();
  90. }
  91. retVal = pCall -> Initialize( NULL,
  92. LINECALLORIGIN_INBOUND,
  93. CALLTYPE_NORMAL );
  94. if( retVal == FALSE )
  95. {
  96. H323DBG ((DEBUG_LEVEL_ERROR, "failed to initialize CH323Call."));
  97. CloseHandle (SelectEvent);
  98. delete pCall;
  99. return E_FAIL;
  100. }
  101. //add it to the call context array
  102. if (!pCall -> InitializeQ931 (Socket))
  103. {
  104. H323DBG(( DEBUG_LEVEL_ERROR,
  105. "Failed to initialize incoming call Q.931 state." ));
  106. DeleteCall = FALSE;
  107. pCall -> Shutdown (&DeleteCall);
  108. delete pCall;
  109. if (SelectEvent)
  110. {
  111. CloseHandle (SelectEvent);
  112. }
  113. return E_FAIL;
  114. }
  115. pCall -> SetQ931CallState (Q931_CALL_CONNECTED);
  116. pCall -> Lock();
  117. if (!RegisterWaitForSingleObject(
  118. &SelectWaitHandle, // pointer to the returned handle.
  119. SelectEvent, // the event handle to wait for.
  120. Q931TransportEventHandler, // the callback function.
  121. (PVOID)pCall -> GetCallHandle(),// the context for the callback.
  122. INFINITE, // wait forever.
  123. WT_EXECUTEDEFAULT)) // use the wait thread to call the callback.
  124. {
  125. goto cleanup;
  126. }
  127. _ASSERTE( SelectWaitHandle );
  128. if( SelectWaitHandle == NULL )
  129. {
  130. goto cleanup;
  131. }
  132. //store this in the call context
  133. pCall -> SetNewCallInfo (SelectWaitHandle, SelectEvent,
  134. Q931_CALL_CONNECTED);
  135. SelectEvent = NULL;
  136. pCall -> InitializeRecvBuf();
  137. //post a buffer to winsock to accept messages from the peer
  138. if(!pCall -> PostReadBuffer())
  139. {
  140. H323DBG(( DEBUG_LEVEL_ERROR, "failed to post read buffer on call." ));
  141. goto cleanup;
  142. }
  143. pCall -> Unlock();
  144. H323DBG(( DEBUG_LEVEL_TRACE, "successfully created incoming Q.931 call." ));
  145. //success
  146. return S_OK;
  147. cleanup:
  148. if (pCall)
  149. {
  150. pCall -> Unlock();
  151. pCall -> Shutdown (&DeleteCall);
  152. delete pCall;
  153. }
  154. if (SelectEvent)
  155. {
  156. CloseHandle (SelectEvent);
  157. }
  158. return E_OUTOFMEMORY;
  159. }
  160. void CallProcessIncomingCall (
  161. IN SOCKET Socket,
  162. IN SOCKADDR_IN * LocalAddress,
  163. IN SOCKADDR_IN * RemoteAddress)
  164. {
  165. HRESULT hr;
  166. hr = CallCreateIncomingCall (Socket, LocalAddress, RemoteAddress);
  167. if (hr != S_OK)
  168. {
  169. closesocket (Socket);
  170. }
  171. }
  172. #if DBG
  173. DWORD
  174. ProcessTAPICallRequest(
  175. IN PVOID ContextParameter
  176. )
  177. {
  178. __try
  179. {
  180. return ProcessTAPICallRequestFre( ContextParameter );
  181. }
  182. __except( 1 )
  183. {
  184. TAPI_CALLREQUEST_DATA* pRequestData =
  185. (TAPI_CALLREQUEST_DATA*)ContextParameter;
  186. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI %s event threw exception: %p, %p.",
  187. EventIDToString(pRequestData -> EventID),
  188. pRequestData -> pCall,
  189. pRequestData -> pCallforwardParams ));
  190. _ASSERTE( FALSE );
  191. return 0;
  192. }
  193. }
  194. #endif
  195. DWORD
  196. ProcessTAPICallRequestFre(
  197. IN PVOID ContextParameter)
  198. {
  199. _ASSERTE( ContextParameter );
  200. TAPI_CALLREQUEST_DATA* pCallRequestData = (TAPI_CALLREQUEST_DATA*)ContextParameter;
  201. PH323_CALL pCall = pCallRequestData->pCall;
  202. BOOL fDelete = FALSE;
  203. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI %s event recvd.",
  204. EventIDToString(pCallRequestData -> EventID) ));
  205. pCall -> Lock();
  206. if( pCallRequestData -> EventID == TSPI_DELETE_CALL )
  207. {
  208. pCall -> Unlock();
  209. delete pCallRequestData;
  210. delete pCall;
  211. return EXIT_SUCCESS;
  212. }
  213. if( pCall -> IsCallShutdown() == FALSE )
  214. {
  215. switch( pCallRequestData -> EventID )
  216. {
  217. case TSPI_MAKE_CALL:
  218. pCall -> MakeCall();
  219. break;
  220. case TSPI_ANSWER_CALL:
  221. pCall -> AcceptCall();
  222. break;
  223. case TSPI_DROP_CALL:
  224. pCall -> DropUserInitiated( 0 );
  225. //pCall -> DropCall(0);
  226. break;
  227. case TSPI_RELEASE_U2U:
  228. pCall -> ReleaseU2U();
  229. break;
  230. case TSPI_CALL_HOLD:
  231. pCall -> Hold();
  232. break;
  233. case TSPI_CALL_UNHOLD:
  234. pCall -> UnHold();
  235. break;
  236. case TSPI_CALL_DIVERT:
  237. pCall -> CallDivertOnNoAnswer();
  238. break;
  239. case TSPI_LINEFORWARD_NOSPECIFIC:
  240. case TSPI_LINEFORWARD_SPECIFIC:
  241. pCall -> Forward( pCallRequestData -> EventID,
  242. pCallRequestData -> pCallforwardParams );
  243. break;
  244. case TSPI_SEND_U2U:
  245. pCall -> SendU2U( pCallRequestData -> pBuf->pbBuffer,
  246. pCallRequestData->pBuf->dwLength );
  247. delete pCallRequestData -> pBuf;
  248. break;
  249. default:
  250. _ASSERTE(0);
  251. break;
  252. }
  253. }
  254. pCall -> DecrementIoRefCount( &fDelete );
  255. pCall -> Unlock();
  256. delete pCallRequestData;
  257. if( fDelete == TRUE )
  258. {
  259. H323DBG((DEBUG_LEVEL_TRACE, "call delete:%p.", pCall ));
  260. delete pCall;
  261. }
  262. return EXIT_SUCCESS;
  263. }
  264. //
  265. // CH323Call Methods
  266. //
  267. CH323Call::CH323Call(void)
  268. {
  269. ZeroMemory( (PVOID)this, sizeof(CH323Call) );
  270. /*m_dwFlags = 0;
  271. m_pwszDisplay = NULL;
  272. m_fMonitoringDigits = FALSE;
  273. m_hdCall = NULL;
  274. m_htCall = NULL;
  275. m_dwCallState = NULL;
  276. m_dwOrigin = NULL;
  277. m_dwAddressType = NULL;
  278. m_dwIncomingModes = NULL;
  279. m_dwOutgoingModes = NULL;
  280. m_dwRequestedModes = NULL; // requested media modes
  281. m_hdMSPLine = NULL;
  282. m_htMSPLine = NULL;
  283. //m_fGateKeeperPresent = FALSE;
  284. m_fReadyToAnswer = FALSE;
  285. m_fCallAccepted = FALSE;
  286. // reset addresses
  287. memset((PVOID)&m_CalleeAddr,0,sizeof(H323_ADDR));
  288. memset((PVOID)&m_CallerAddr,0,sizeof(H323_ADDR));
  289. // reset addresses
  290. m_pCalleeAliasNames = NULL;
  291. m_pCallerAliasNames = NULL;
  292. //reset non standard data
  293. memset( (PVOID)&m_NonStandardData, 0, sizeof(H323NonStandardData ) );
  294. //reset the conference ID
  295. ZeroMemory (&m_ConferenceID, sizeof m_ConferenceID);
  296. pFastStart = NULL;
  297. //redet the peer information
  298. memset( (PVOID)&m_peerH245Addr, 0, sizeof(H323_ADDR) );
  299. memset( (PVOID)&m_selfH245Addr, 0, sizeof(H323_ADDR) );
  300. memset( (PVOID)&m_peerNonStandardData, 0, sizeof(H323NonStandardData ) );
  301. memset( (PVOID)&m_peerVendorInfo, 0, sizeof(H323_VENDORINFO) );
  302. memset( (PVOID)&m_peerEndPointType, 0, sizeof(H323_ENDPOINTTYPE) );
  303. m_pPeerFastStart = NULL;
  304. m_pPeerExtraAliasNames = NULL;
  305. m_pPeerDisplay = NULL;
  306. m_hCallEstablishmentTimer = NULL;
  307. m_hCallDivertOnNATimer = NULL;
  308. //Q931call data
  309. m_hTransport = NULL;
  310. m_hTransportWait = NULL;
  311. pRecvBuf = NULL;
  312. m_hSetupSentTimer = NULL;
  313. m_dwStateMachine = 0;
  314. m_dwQ931Flags = 0;
  315. //
  316. fActiveMC = FALSE;
  317. memset( (PVOID)&m_ASNCoderInfo, 0, sizeof(m_ASNCoderInfo));
  318. m_wCallReference = NULL;
  319. m_wQ931CallRef = NULL;
  320. m_IoRefCount = 0;
  321. //RAS call data
  322. wARQSeqNum = 0;
  323. m_wDRQSeqNum = 0;
  324. m_pARQExpireContext = NULL;
  325. m_pDRQExpireContext= NULL;
  326. m_hARQTimer = NULL;
  327. m_hDRQTimer = NULL;
  328. m_dwDRQRetryCount = 0;
  329. m_dwARQRetryCount = 0;
  330. m_fCallInTrnasition = FALSE
  331. m_dwAppSpecific = 0;*/
  332. m_dwFastStart = FAST_START_UNDECIDED;
  333. m_callSocket = INVALID_SOCKET;
  334. m_bStartOfPDU = TRUE;
  335. H323DBG(( DEBUG_LEVEL_TRACE,
  336. "Initialize:m_IoRefCount:%d:%p.", m_IoRefCount, this ));
  337. m_dwRASCallState = RASCALL_STATE_IDLE;
  338. if( InterlockedIncrement( &g_lNumberOfcalls ) == 1 )
  339. {
  340. H323DBG(( DEBUG_LEVEL_TRACE,
  341. "pCall no goes from 0 to 1:g_hCanUnloadDll set.", this ));
  342. ResetEvent( g_hCanUnloadDll );
  343. }
  344. H323DBG(( DEBUG_LEVEL_TRACE, "New pCall object created:%p.", this ));
  345. }
  346. CH323Call::~CH323Call()
  347. {
  348. CALL_SEND_CONTEXT* pSendBuf;
  349. PLIST_ENTRY pLE;
  350. H323DBG(( DEBUG_LEVEL_ERROR, "pCall object deleted:%p.", this ));
  351. if( m_dwFlags & CALLOBJECT_INITIALIZED )
  352. {
  353. while( IsListEmpty( &m_sendBufList ) == FALSE )
  354. {
  355. pLE = RemoveHeadList( &m_sendBufList );
  356. pSendBuf = CONTAINING_RECORD( pLE, CALL_SEND_CONTEXT, ListEntry);
  357. delete pSendBuf->WSABuf.buf;
  358. delete pSendBuf;
  359. }
  360. if( m_hTransportWait != NULL )
  361. {
  362. if( UnregisterWaitEx( m_hTransportWait, NULL ) == FALSE )
  363. {
  364. GetLastError();
  365. }
  366. m_hTransportWait = NULL;
  367. }
  368. if( m_hTransport != NULL )
  369. {
  370. if(!CloseHandle(m_hTransport))
  371. {
  372. WSAGetLastError();
  373. }
  374. m_hTransport = NULL;
  375. }
  376. if( m_callSocket != INVALID_SOCKET )
  377. {
  378. closesocket( m_callSocket );
  379. m_callSocket = INVALID_SOCKET;
  380. }
  381. TermASNCoder();
  382. DeleteCriticalSection( &m_CriticalSection );
  383. }
  384. if( InterlockedDecrement( &g_lNumberOfcalls ) == 0 )
  385. {
  386. H323DBG(( DEBUG_LEVEL_ERROR, "Unload dll event set.%p.", this ));
  387. SetEvent( g_hCanUnloadDll );
  388. }
  389. }
  390. //!!no need to lock
  391. BOOL
  392. CH323Call::Initialize(
  393. IN HTAPICALL htCall,
  394. IN DWORD dwOrigin,
  395. IN DWORD dwCallType
  396. )
  397. {
  398. int index;
  399. int rc;
  400. H323DBG(( DEBUG_LEVEL_ERROR, "call init entered:%p.",this ));
  401. m_pCallerAliasNames = new H323_ALIASNAMES;
  402. if( m_pCallerAliasNames == NULL )
  403. {
  404. H323DBG(( DEBUG_LEVEL_ERROR, "could not allocate caller name." ));
  405. return FALSE;
  406. }
  407. memset( (PVOID)m_pCallerAliasNames, 0, sizeof(H323_ALIASNAMES) );
  408. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  409. m_pCalleeAliasNames = new H323_ALIASNAMES;
  410. if( m_pCalleeAliasNames == NULL )
  411. {
  412. H323DBG(( DEBUG_LEVEL_ERROR, "could not allocate callee name." ));
  413. goto error1;
  414. }
  415. memset( (PVOID)m_pCalleeAliasNames, 0, sizeof(H323_ALIASNAMES) );
  416. __try
  417. {
  418. if( !InitializeCriticalSectionAndSpinCount( &m_CriticalSection,
  419. 0x80000000 ) )
  420. {
  421. H323DBG(( DEBUG_LEVEL_ERROR, "couldn't alloc critsec for call." ));
  422. goto error2;
  423. }
  424. }
  425. __except( 1 )
  426. {
  427. goto error2;
  428. }
  429. if( dwOrigin == LINECALLORIGIN_OUTBOUND )
  430. {
  431. int iresult = UuidCreate( &m_callIdentifier );
  432. if( (iresult != RPC_S_OK) && (iresult !=RPC_S_UUID_LOCAL_ONLY) )
  433. {
  434. goto error3;
  435. }
  436. }
  437. rc = InitASNCoder();
  438. if( rc != ASN1_SUCCESS )
  439. {
  440. H323DBG((DEBUG_LEVEL_ERROR, "Q931_InitCoder() returned: %d ", rc));
  441. goto error3;
  442. }
  443. rc = InitH450ASNCoder();
  444. if( rc != ASN1_SUCCESS )
  445. {
  446. H323DBG((DEBUG_LEVEL_ERROR, "Q931_InitCoder() returned: %d ", rc));
  447. goto error4;
  448. }
  449. //Create the CRV for this call.
  450. do
  451. {
  452. m_wCallReference = ((WORD)InterlockedIncrement( &g_lCallReference ))
  453. & 0x7fff;
  454. } while( (m_wCallReference == 0) ||
  455. g_pH323Line->CallReferenceDuped( m_wCallReference ) );
  456. //add the call to the call table
  457. index = g_pH323Line -> AddCallToTable((PH323_CALL)this);
  458. if( index == -1 )
  459. {
  460. H323DBG(( DEBUG_LEVEL_ERROR,
  461. "could not add call to call table." ));
  462. goto error5;
  463. }
  464. //By incrementing the g_H323CallID and taking lower 16 bits we get 65536
  465. //unique values and then same values are repeated. Thus we can have only
  466. //65535 simultaneous calls. By using the call table index we make sure that
  467. //no two existing calls have same call handle.
  468. do
  469. {
  470. m_hdCall = (HDRVCALL)( ((BYTE*)NULL) +
  471. MAKELONG( LOWORD((DWORD)index),
  472. (WORD)InterlockedIncrement(&g_H323CallID) ));
  473. } while ( m_hdCall == NULL );
  474. ZeroMemory( (PVOID)&m_prepareToAnswerMsgData, sizeof(BUFFERDESCR) );
  475. m_dwFlags |= CALLOBJECT_INITIALIZED;
  476. m_htCall = htCall;
  477. m_dwCallState = LINECALLSTATE_IDLE;
  478. m_dwOrigin = dwOrigin;
  479. m_hdConf = NULL;
  480. m_wQ931CallRef = m_wCallReference;
  481. m_dwCallType = dwCallType;
  482. // initialize user user information
  483. InitializeListHead( &m_IncomingU2U );
  484. InitializeListHead( &m_OutgoingU2U );
  485. InitializeListHead( &m_sendBufList );
  486. H323DBG(( DEBUG_LEVEL_TRACE,
  487. "m_hdCall:%lx m_htCall:%lx m_wCallReference:%lx : %p .",
  488. m_hdCall, m_htCall, m_wCallReference, this ));
  489. H323DBG(( DEBUG_LEVEL_TRACE, "call init exited:%p.",this ));
  490. return TRUE;
  491. error5:
  492. TermH450ASNCoder();
  493. error4:
  494. TermASNCoder();
  495. error3:
  496. DeleteCriticalSection( &m_CriticalSection );
  497. error2:
  498. delete m_pCalleeAliasNames;
  499. m_pCalleeAliasNames = NULL;
  500. error1:
  501. delete m_pCallerAliasNames;
  502. m_pCallerAliasNames = NULL;
  503. return FALSE;
  504. }
  505. //
  506. //!!must be always called in a lock
  507. //Queues a request made by TAPI to the thread pool
  508. //
  509. BOOL
  510. CH323Call::QueueTAPICallRequest(
  511. IN DWORD EventID,
  512. IN PVOID pBuf
  513. )
  514. {
  515. TAPI_CALLREQUEST_DATA * pCallRequestData = new TAPI_CALLREQUEST_DATA;
  516. BOOL fResult = TRUE;
  517. if( pCallRequestData != NULL )
  518. {
  519. pCallRequestData -> EventID = EventID;
  520. pCallRequestData -> pCall = this;
  521. pCallRequestData -> pBuf = (PBUFFERDESCR)pBuf;
  522. if( !QueueUserWorkItem( ProcessTAPICallRequest, pCallRequestData,
  523. WT_EXECUTEDEFAULT ) )
  524. {
  525. delete pCallRequestData;
  526. fResult = FALSE;
  527. }
  528. m_IoRefCount++;
  529. H323DBG(( DEBUG_LEVEL_TRACE, "TAPICallRequest:m_IoRefCount:%d:%p.",
  530. m_IoRefCount, this ));
  531. }
  532. else
  533. {
  534. fResult = FALSE;
  535. }
  536. return fResult;
  537. }
  538. //always called in lock
  539. void
  540. CH323Call::CopyCallStatus(
  541. IN LPLINECALLSTATUS pCallStatus
  542. )
  543. {
  544. H323DBG(( DEBUG_LEVEL_ERROR, "CopyCallStatus entered:%p.",this ));
  545. // transer call state information
  546. pCallStatus->dwCallState = m_dwCallState;
  547. pCallStatus->dwCallStateMode = m_dwCallStateMode;
  548. // determine call feature based on state
  549. pCallStatus->dwCallFeatures = ( m_dwCallState != LINECALLSTATE_IDLE)?
  550. (H323_CALL_FEATURES) : 0;
  551. H323DBG(( DEBUG_LEVEL_ERROR, "CopyCallStatus exited:%p.",this ));
  552. }
  553. //always called in lock
  554. LONG
  555. CH323Call::CopyCallInfo(
  556. IN LPLINECALLINFO pCallInfo
  557. )
  558. {
  559. DWORD dwCalleeNameSize = 0;
  560. DWORD dwCallerNameSize = 0;
  561. DWORD dwCallerAddressSize = 0;
  562. WCHAR wszIPAddress[20];
  563. DWORD dwNextOffset = sizeof(LINECALLINFO);
  564. DWORD dwU2USize = 0;
  565. PBYTE pU2U = NULL;
  566. LONG retVal = NOERROR;
  567. DWORD dwDivertingNameSize = 0;
  568. DWORD dwDiversionNameSize = 0;
  569. DWORD dwDivertedToNameSize = 0;
  570. DWORD dwCallDataSize = 0;
  571. H323DBG(( DEBUG_LEVEL_ERROR, "CopyCallInfo entered:%p.",this ));
  572. // see if user user info available
  573. if( IsListEmpty( &m_IncomingU2U) == FALSE )
  574. {
  575. PLIST_ENTRY pLE;
  576. PUserToUserLE pU2ULE;
  577. // get first list entry
  578. pLE = m_IncomingU2U.Flink;
  579. // convert to user user structure
  580. pU2ULE = CONTAINING_RECORD(pLE, UserToUserLE, Link);
  581. // transfer info
  582. dwU2USize = pU2ULE->dwU2USize;
  583. pU2U = pU2ULE->pU2U;
  584. }
  585. // initialize caller and callee id flags now
  586. pCallInfo->dwCalledIDFlags = LINECALLPARTYID_UNAVAIL;
  587. pCallInfo->dwCallerIDFlags = LINECALLPARTYID_UNAVAIL;
  588. pCallInfo->dwRedirectingIDFlags = LINECALLPARTYID_UNAVAIL;
  589. pCallInfo->dwRedirectionIDFlags = LINECALLPARTYID_UNAVAIL;
  590. // calculate memory necessary for strings
  591. if( m_pCalleeAliasNames && m_pCalleeAliasNames -> wCount !=0 )
  592. {
  593. dwCalleeNameSize =
  594. H323SizeOfWSZ( m_pCalleeAliasNames -> pItems[0].pData );
  595. }
  596. if( m_pCallerAliasNames && (m_pCallerAliasNames->wCount) )
  597. {
  598. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  599. dwCallerNameSize =
  600. sizeof(WCHAR) * (m_pCallerAliasNames->pItems[0].wDataLength + 1);
  601. }
  602. if( m_CallerAddr.Addr.IP_Binary.dwAddr != 0 )
  603. {
  604. wsprintfW(wszIPAddress, L"%d.%d.%d.%d",
  605. (m_CallerAddr.Addr.IP_Binary.dwAddr >> 24) & 0xff,
  606. (m_CallerAddr.Addr.IP_Binary.dwAddr >> 16) & 0xff,
  607. (m_CallerAddr.Addr.IP_Binary.dwAddr >> 8) & 0xff,
  608. (m_CallerAddr.Addr.IP_Binary.dwAddr) & 0xff
  609. );
  610. dwCallerAddressSize = (wcslen(wszIPAddress) + 1) * sizeof(WCHAR);
  611. }
  612. if( m_dwCallType & CALLTYPE_DIVERTEDDEST )
  613. {
  614. if( m_pCallReroutingInfo->divertingNrAlias &&
  615. (m_pCallReroutingInfo->divertingNrAlias->wCount !=0) )
  616. {
  617. dwDivertingNameSize = H323SizeOfWSZ(
  618. m_pCallReroutingInfo->divertingNrAlias-> pItems[0].pData );
  619. }
  620. if( m_pCallReroutingInfo->divertedToNrAlias &&
  621. (m_pCallReroutingInfo->divertedToNrAlias->wCount != 0) )
  622. {
  623. dwDivertedToNameSize = sizeof(WCHAR) *
  624. m_pCallReroutingInfo->divertedToNrAlias->pItems[0].wDataLength;
  625. }
  626. }
  627. if( m_dwCallType & CALLTYPE_DIVERTEDSRC_NOROUTING )
  628. {
  629. if( m_pCallReroutingInfo->divertedToNrAlias &&
  630. (m_pCallReroutingInfo->divertedToNrAlias->wCount != 0) )
  631. {
  632. dwDivertedToNameSize = sizeof(WCHAR) *
  633. m_pCallReroutingInfo->divertedToNrAlias->pItems[0].wDataLength;
  634. }
  635. }
  636. if( m_dwCallType & CALLTYPE_DIVERTEDSRC)
  637. {
  638. if( m_pCallReroutingInfo->divertedToNrAlias &&
  639. (m_pCallReroutingInfo->divertedToNrAlias->wCount != 0) )
  640. {
  641. dwDivertedToNameSize = sizeof(WCHAR) *
  642. m_pCallReroutingInfo->divertedToNrAlias->pItems[0].wDataLength;
  643. }
  644. if( m_pCallReroutingInfo->divertingNrAlias &&
  645. (m_pCallReroutingInfo->divertingNrAlias->wCount !=0) )
  646. {
  647. dwDivertingNameSize = H323SizeOfWSZ(
  648. m_pCallReroutingInfo->divertingNrAlias-> pItems[0].pData );
  649. }
  650. }
  651. if( m_CallData.wOctetStringLength != 0 )
  652. {
  653. dwCallDataSize = m_CallData.wOctetStringLength;
  654. }
  655. // determine number of bytes needed
  656. pCallInfo->dwNeededSize = sizeof(LINECALLINFO) +
  657. dwCalleeNameSize +
  658. dwCallerNameSize +
  659. dwCallerAddressSize +
  660. dwDivertingNameSize +
  661. dwDiversionNameSize +
  662. dwDivertedToNameSize +
  663. dwU2USize +
  664. dwCallDataSize
  665. ;
  666. // see if structure size is large enough
  667. if (pCallInfo->dwTotalSize >= pCallInfo->dwNeededSize)
  668. {
  669. // record number of bytes used
  670. pCallInfo->dwUsedSize = pCallInfo->dwNeededSize;
  671. // validate string size
  672. if (dwCalleeNameSize > 0)
  673. {
  674. if( m_pCalleeAliasNames -> pItems[0].wType == e164_chosen )
  675. {
  676. // callee number was specified
  677. pCallInfo->dwCalledIDFlags = LINECALLPARTYID_ADDRESS;
  678. // determine size and offset for callee number
  679. pCallInfo->dwCalledIDSize = dwCalleeNameSize;
  680. pCallInfo->dwCalledIDOffset = dwNextOffset;
  681. // copy call info after fixed portion
  682. CopyMemory(
  683. (PVOID)((LPBYTE)pCallInfo + pCallInfo->dwCalledIDOffset),
  684. (LPBYTE)m_pCalleeAliasNames -> pItems[0].pData,
  685. pCallInfo->dwCalledIDSize );
  686. }
  687. else
  688. {
  689. // callee name was specified
  690. pCallInfo->dwCalledIDFlags = LINECALLPARTYID_NAME;
  691. // determine size and offset for callee name
  692. pCallInfo->dwCalledIDNameSize = dwCalleeNameSize;
  693. pCallInfo->dwCalledIDNameOffset = dwNextOffset;
  694. // copy call info after fixed portion
  695. CopyMemory(
  696. (PVOID)((LPBYTE)pCallInfo + pCallInfo->dwCalledIDNameOffset),
  697. (LPBYTE)m_pCalleeAliasNames -> pItems[0].pData,
  698. pCallInfo->dwCalledIDNameSize );
  699. }
  700. // adjust offset to include string
  701. dwNextOffset += dwCalleeNameSize;
  702. H323DBG(( DEBUG_LEVEL_TRACE,
  703. "callee name: %S.", m_pCalleeAliasNames -> pItems[0].pData ));
  704. }
  705. // validate string size
  706. if (dwCallerNameSize > 0)
  707. {
  708. // caller name was specified
  709. pCallInfo->dwCallerIDFlags = LINECALLPARTYID_NAME;
  710. // determine size and offset for caller name
  711. pCallInfo->dwCallerIDNameSize = dwCallerNameSize;
  712. pCallInfo->dwCallerIDNameOffset = dwNextOffset;
  713. // copy call info after fixed portion
  714. CopyMemory(
  715. (PVOID)((LPBYTE)pCallInfo + pCallInfo->dwCallerIDNameOffset),
  716. (LPBYTE)m_pCallerAliasNames -> pItems[0].pData,
  717. pCallInfo->dwCallerIDNameSize );
  718. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  719. // adjust offset to include string
  720. dwNextOffset += dwCallerNameSize;
  721. H323DBG(( DEBUG_LEVEL_TRACE,
  722. "caller name: %S.", m_pCallerAliasNames -> pItems[0].pData ));
  723. }
  724. if( dwCallerAddressSize > 0 )
  725. {
  726. // caller number was specified
  727. pCallInfo->dwCallerIDFlags |= LINECALLPARTYID_ADDRESS;
  728. // determine size and offset for caller number
  729. pCallInfo->dwCallerIDSize = dwCallerAddressSize;
  730. pCallInfo->dwCallerIDOffset = dwNextOffset;
  731. // copy call info after fixed portion
  732. CopyMemory(
  733. (PVOID)((LPBYTE)pCallInfo + pCallInfo->dwCallerIDOffset),
  734. (LPBYTE)wszIPAddress,
  735. pCallInfo->dwCallerIDSize );
  736. // adjust offset to include string
  737. dwNextOffset += dwCallerAddressSize;
  738. }
  739. // validate buffer
  740. if (dwU2USize > 0)
  741. {
  742. // determine size and offset of info
  743. pCallInfo->dwUserUserInfoSize = dwU2USize;
  744. pCallInfo->dwUserUserInfoOffset = dwNextOffset;
  745. // copy user user info after fixed portion
  746. CopyMemory(
  747. (PVOID)((LPBYTE)pCallInfo + pCallInfo->dwUserUserInfoOffset),
  748. (LPBYTE)pU2U,
  749. pCallInfo->dwUserUserInfoSize );
  750. // adjust offset to include string
  751. dwNextOffset += pCallInfo->dwUserUserInfoSize;
  752. }
  753. if( dwDivertingNameSize > 0 )
  754. {
  755. // caller name was specified
  756. pCallInfo->dwRedirectingIDFlags = LINECALLPARTYID_NAME;
  757. // determine size and offset for caller name
  758. pCallInfo->dwRedirectingIDNameSize = dwDivertingNameSize;
  759. pCallInfo->dwRedirectingIDNameOffset = dwNextOffset;
  760. // copy call info after fixed portion
  761. CopyMemory(
  762. (PVOID)((LPBYTE)pCallInfo + pCallInfo->dwRedirectingIDNameOffset),
  763. (LPBYTE)(m_pCallReroutingInfo->divertingNrAlias->pItems[0].pData),
  764. pCallInfo->dwRedirectingIDNameSize );
  765. // adjust offset to include string
  766. dwNextOffset += dwDivertingNameSize;
  767. H323DBG(( DEBUG_LEVEL_TRACE, "diverting name: %S.",
  768. m_pCallReroutingInfo->divertingNrAlias->pItems[0].pData ));
  769. }
  770. if( dwDiversionNameSize > 0 )
  771. {
  772. // caller name was specified
  773. pCallInfo->dwRedirectionIDFlags = LINECALLPARTYID_NAME;
  774. // determine size and offset for caller name
  775. pCallInfo->dwRedirectionIDNameSize = dwDiversionNameSize;
  776. pCallInfo->dwRedirectionIDNameOffset = dwNextOffset;
  777. // copy call info after fixed portion
  778. CopyMemory(
  779. (PVOID)((LPBYTE)pCallInfo + pCallInfo->dwRedirectionIDNameOffset),
  780. (LPBYTE)(m_pCallReroutingInfo->diversionNrAlias->pItems[0].pData),
  781. pCallInfo->dwRedirectionIDNameSize );
  782. // adjust offset to include string
  783. dwNextOffset += dwDiversionNameSize;
  784. H323DBG(( DEBUG_LEVEL_TRACE, "redirection name: %S.",
  785. m_pCallReroutingInfo->diversionNrAlias->pItems[0].pData ));
  786. }
  787. if( dwDivertedToNameSize > 0 )
  788. {
  789. pCallInfo->dwRedirectionIDFlags = LINECALLPARTYID_NAME;
  790. // determine size and offset for caller name
  791. pCallInfo->dwRedirectionIDNameSize = dwDivertedToNameSize;
  792. pCallInfo->dwRedirectionIDNameOffset = dwNextOffset;
  793. // copy call info after fixed portion
  794. CopyMemory(
  795. (PVOID)((LPBYTE)pCallInfo + pCallInfo->dwRedirectionIDNameOffset),
  796. (LPBYTE)(m_pCallReroutingInfo->divertedToNrAlias->pItems[0].pData),
  797. pCallInfo->dwRedirectionIDNameSize );
  798. // adjust offset to include string
  799. dwNextOffset += pCallInfo->dwRedirectionIDNameSize;
  800. // adjust offset to include string
  801. dwNextOffset += dwDivertedToNameSize;
  802. H323DBG(( DEBUG_LEVEL_TRACE, "redirection name: %S.",
  803. m_pCallReroutingInfo->divertedToNrAlias->pItems[0].pData ));
  804. }
  805. //pass on the call data
  806. if( dwCallDataSize > 0 )
  807. {
  808. pCallInfo -> dwCallDataSize = dwCallDataSize;
  809. pCallInfo -> dwCallDataOffset = dwNextOffset;
  810. CopyMemory(
  811. (PVOID)((LPBYTE)pCallInfo + pCallInfo -> dwCallDataOffset),
  812. (LPBYTE)m_CallData.pOctetString,
  813. pCallInfo -> dwCallDataSize );
  814. dwNextOffset += dwCallDataSize;
  815. }
  816. }
  817. else if (pCallInfo->dwTotalSize >= sizeof(LINECALLINFO))
  818. {
  819. H323DBG(( DEBUG_LEVEL_WARNING,
  820. "linecallinfo structure too small for strings." ));
  821. // structure only contains fixed portion
  822. pCallInfo->dwUsedSize = sizeof(LINECALLINFO);
  823. }
  824. else
  825. {
  826. H323DBG(( DEBUG_LEVEL_ERROR, "linecallinfo structure too small." ));
  827. // structure is too small
  828. return LINEERR_STRUCTURETOOSMALL;
  829. }
  830. // initialize call line device and address info
  831. pCallInfo->dwLineDeviceID = g_pH323Line->GetDeviceID();
  832. pCallInfo->dwAddressID = 0;
  833. // initialize variable call parameters
  834. pCallInfo->dwOrigin = m_dwOrigin;
  835. pCallInfo->dwMediaMode = m_dwIncomingModes | m_dwOutgoingModes;
  836. if( m_dwCallType & CALLTYPE_DIVERTEDDEST )
  837. {
  838. if(m_pCallReroutingInfo->diversionReason==DiversionReason_cfu)
  839. {
  840. pCallInfo->dwReason = LINECALLREASON_FWDUNCOND;
  841. }
  842. else if(m_pCallReroutingInfo->diversionReason==DiversionReason_cfnr)
  843. {
  844. pCallInfo->dwReason = LINECALLREASON_FWDNOANSWER;
  845. }
  846. else
  847. {
  848. pCallInfo->dwReason = LINECALLREASON_FWDBUSY;
  849. }
  850. }
  851. if( m_dwCallType & CALLTYPE_TRANSFEREDDEST )
  852. {
  853. pCallInfo->dwReason = LINECALLREASON_TRANSFER;
  854. }
  855. else
  856. {
  857. pCallInfo->dwReason = LINECALLREASON_DIRECT;
  858. }
  859. pCallInfo->dwCallStates = (m_dwOrigin==LINECALLORIGIN_INBOUND)
  860. ? H323_CALL_INBOUNDSTATES
  861. : H323_CALL_OUTBOUNDSTATES
  862. ;
  863. // initialize constant call parameters
  864. pCallInfo->dwBearerMode = H323_LINE_BEARERMODES;
  865. pCallInfo->dwRate = H323_LINE_MAXRATE;
  866. // initialize unsupported call capabilities
  867. pCallInfo->dwConnectedIDFlags = LINECALLPARTYID_UNAVAIL;
  868. //pass on the dwAppSpecific info
  869. pCallInfo -> dwAppSpecific = m_dwAppSpecific;
  870. H323DBG(( DEBUG_LEVEL_ERROR, "CopyCallInfo exited:%p.",this ));
  871. return retVal;
  872. }
  873. //!!always called in lock
  874. BOOL
  875. CH323Call::HandleReadyToInitiate(
  876. IN PTspMspMessage pMessage
  877. )
  878. {
  879. Q931_SETUP_ASN setupASN;
  880. WORD wCount;
  881. DWORD dwAPDUType = 0;
  882. H323DBG(( DEBUG_LEVEL_ERROR, "HandleReadyToInitiate entered:%p.", this ));
  883. //set the additional callee addresses and callee aliases
  884. //see if there is a fast-connect proposal
  885. if( pMessage->dwEncodedASNSize != 0 )
  886. {
  887. if( !ParseSetupASN( pMessage ->pEncodedASNBuf,
  888. pMessage->dwEncodedASNSize,
  889. &setupASN,
  890. &dwAPDUType ))
  891. {
  892. goto cleanup;
  893. }
  894. if( setupASN.fFastStartPresent )
  895. {
  896. _ASSERTE( !m_pFastStart );
  897. m_pFastStart = setupASN.pFastStart;
  898. setupASN.pFastStart = NULL;
  899. m_dwFastStart = FAST_START_SELF_AVAIL;
  900. }
  901. else
  902. {
  903. m_dwFastStart = FAST_START_NOTAVAIL;
  904. }
  905. if( setupASN.pCallerAliasList && !RasIsRegistered() )
  906. {
  907. //_ASSERTE(0);
  908. if( m_pCallerAliasNames == NULL )
  909. {
  910. m_pCallerAliasNames = setupASN.pCallerAliasList;
  911. //dont release this alias list
  912. setupASN.pCallerAliasList = NULL;
  913. }
  914. else
  915. {
  916. wCount = m_pCallerAliasNames->wCount +
  917. setupASN.pCallerAliasList->wCount;
  918. PH323_ALIASITEM tempPtr = NULL;
  919. tempPtr = (PH323_ALIASITEM)realloc(
  920. (PVOID)setupASN.pCallerAliasList->pItems,
  921. wCount * sizeof(H323_ALIASITEM) );
  922. if( tempPtr == NULL )
  923. {
  924. //restore the old pointer in case enough memory was not
  925. //available to expand the memory block
  926. }
  927. else
  928. {
  929. setupASN.pCallerAliasList->pItems = tempPtr;
  930. CopyMemory(
  931. (PVOID)&(setupASN.pCallerAliasList->pItems[setupASN.pCallerAliasList->wCount]),
  932. (PVOID)m_pCallerAliasNames->pItems,
  933. m_pCallerAliasNames->wCount * sizeof(H323_ALIASITEM) );
  934. setupASN.pCallerAliasList->wCount = wCount;
  935. delete m_pCallerAliasNames->pItems;
  936. delete m_pCallerAliasNames;
  937. m_pCallerAliasNames = setupASN.pCallerAliasList;
  938. setupASN.pCallerAliasList = NULL;
  939. }
  940. }
  941. }
  942. //add the callee aliases sent by the MSP
  943. if( setupASN.pCalleeAliasList != NULL )
  944. {
  945. //_ASSERTE(0);
  946. if( m_pCalleeAliasNames == NULL )
  947. {
  948. m_pCalleeAliasNames = setupASN.pCalleeAliasList;
  949. //dont release this alias list
  950. setupASN.pCalleeAliasList = NULL;
  951. }
  952. else
  953. {
  954. wCount = m_pCalleeAliasNames->wCount +
  955. setupASN.pCalleeAliasList->wCount;
  956. PH323_ALIASITEM tempPtr = NULL;
  957. tempPtr = (PH323_ALIASITEM)realloc(
  958. (PVOID)m_pCalleeAliasNames->pItems,
  959. wCount * sizeof(H323_ALIASITEM) );
  960. if( tempPtr == NULL )
  961. {
  962. //restore the old pointer in case enough memory was not
  963. //available to expand the memory block
  964. goto cleanup;
  965. }
  966. m_pCalleeAliasNames->pItems = tempPtr;
  967. CopyMemory(
  968. (PVOID)&(m_pCalleeAliasNames->pItems[m_pCalleeAliasNames->wCount]),
  969. (PVOID)setupASN.pCalleeAliasList->pItems,
  970. setupASN.pCalleeAliasList->wCount * sizeof(H323_ALIASITEM) );
  971. m_pCalleeAliasNames->wCount = wCount;
  972. delete setupASN.pCalleeAliasList->pItems;
  973. delete setupASN.pCalleeAliasList;
  974. setupASN.pCalleeAliasList = NULL;
  975. }
  976. }
  977. FreeSetupASN( &setupASN );
  978. }
  979. else
  980. {
  981. m_dwFastStart = FAST_START_NOTAVAIL;
  982. }
  983. //send the setup message
  984. if( !SendSetupMessage() )
  985. {
  986. DropCall( 0 );
  987. }
  988. H323DBG(( DEBUG_LEVEL_ERROR, "HandleReadyToInitiate exited:%p.", this ));
  989. return TRUE;
  990. cleanup:
  991. CloseCall( 0 );
  992. FreeSetupASN( &setupASN );
  993. return FALSE;
  994. }
  995. //!!always called in lock
  996. BOOL
  997. CH323Call::HandleProceedWithAnswer(
  998. IN PTspMspMessage pMessage
  999. )
  1000. {
  1001. Q931_CALL_PROCEEDING_ASN proceedingASN;
  1002. DWORD dwAPDUType = 0;
  1003. PH323_ALIASITEM pwszDivertedToAlias = NULL;
  1004. WCHAR *pwszAliasName = NULL;
  1005. WORD wAliasLength = 0;
  1006. H323DBG(( DEBUG_LEVEL_TRACE, "HandleProceedWithAnswer entered:%p.", this ));
  1007. if( m_dwCallType & CALLTYPE_DIVERTED_SERVED )
  1008. {
  1009. H323DBG(( DEBUG_LEVEL_TRACE,
  1010. "Call already diverted. ignore the message:%p.", this ));
  1011. return TRUE;
  1012. }
  1013. //see if there is a fast-connect proposal
  1014. if( pMessage->dwEncodedASNSize != 0 )
  1015. {
  1016. if( !ParseProceedingASN(pMessage ->pEncodedASNBuf,
  1017. pMessage->dwEncodedASNSize,
  1018. &proceedingASN,
  1019. &dwAPDUType ) )
  1020. {
  1021. goto cleanup;
  1022. }
  1023. if( proceedingASN.fH245AddrPresent )
  1024. {
  1025. m_selfH245Addr = proceedingASN.h245Addr;
  1026. }
  1027. if( proceedingASN.fFastStartPresent &&
  1028. (m_dwFastStart!=FAST_START_NOTAVAIL) )
  1029. {
  1030. _ASSERTE( m_pFastStart == NULL );
  1031. m_pFastStart = proceedingASN.pFastStart;
  1032. m_dwFastStart = FAST_START_AVAIL;
  1033. //we keep a reference to the fast start list so don't release it
  1034. proceedingASN.pFastStart = NULL;
  1035. proceedingASN.fFastStartPresent = FALSE;
  1036. }
  1037. /*else
  1038. {
  1039. m_dwFastStart = FAST_START_NOTAVAIL;
  1040. }*/
  1041. FreeProceedingASN( &proceedingASN );
  1042. }
  1043. /*else
  1044. {
  1045. m_dwFastStart = FAST_START_NOTAVAIL;
  1046. }*/
  1047. //send proceeding message to the peer
  1048. if(!SendProceeding() )
  1049. {
  1050. goto cleanup;
  1051. }
  1052. //send alerting message to the peer
  1053. if( !SendQ931Message(NO_INVOKEID, 0, 0, ALERTINGMESSAGETYPE, NO_H450_APDU) )
  1054. {
  1055. goto cleanup;
  1056. }
  1057. m_dwStateMachine = Q931_ALERT_SENT;
  1058. //for TRANSFEREDDEST call directly accept the call wihtout the user
  1059. //answering the call
  1060. if( (m_dwCallType & CALLTYPE_TRANSFEREDDEST) && m_hdRelatedCall )
  1061. {
  1062. AcceptCall();
  1063. }
  1064. if( m_pCallerAliasNames && (m_pCallerAliasNames -> wCount > 0) )
  1065. {
  1066. pwszAliasName = m_pCallerAliasNames->pItems[0].pData;
  1067. wAliasLength = (m_pCallerAliasNames->pItems[0].wDataLength+1)
  1068. * sizeof(WCHAR);
  1069. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  1070. }
  1071. pwszDivertedToAlias = g_pH323Line->CallToBeDiverted(
  1072. pwszAliasName,
  1073. wAliasLength,
  1074. LINEFORWARDMODE_NOANSW | LINEFORWARDMODE_NOANSWSPECIFIC |
  1075. LINEFORWARDMODE_BUSYNA | LINEFORWARDMODE_BUSYNASPECIFIC );
  1076. //if call is to be diverted for no answer, start the timer
  1077. if( pwszDivertedToAlias != NULL )
  1078. {
  1079. if( !StartTimerForCallDiversionOnNA( pwszDivertedToAlias ) )
  1080. {
  1081. goto cleanup;
  1082. }
  1083. }
  1084. H323DBG(( DEBUG_LEVEL_TRACE, "HandleProceedWithAnswer exited:%p.",this ));
  1085. return TRUE;
  1086. cleanup:
  1087. CloseCall( 0 );
  1088. return FALSE;
  1089. }
  1090. //!!always called in lock
  1091. BOOL
  1092. CH323Call::HandleReadyToAnswer(
  1093. IN PTspMspMessage pMessage
  1094. )
  1095. {
  1096. Q931_CALL_PROCEEDING_ASN proceedingASN;
  1097. DWORD dwAPDUType = 0;
  1098. PH323_CALL pConsultCall = NULL;
  1099. H323DBG(( DEBUG_LEVEL_ERROR, "HandleReadyToAnswer entered:%p.",this ));
  1100. m_fReadyToAnswer = TRUE;
  1101. //see if there is a fast-connect proposal
  1102. if( pMessage->dwEncodedASNSize != 0 )
  1103. {
  1104. if( !ParseProceedingASN(pMessage ->pEncodedASNBuf,
  1105. pMessage->dwEncodedASNSize,
  1106. &proceedingASN,
  1107. &dwAPDUType) )
  1108. {
  1109. goto cleanup;
  1110. }
  1111. if( proceedingASN.fH245AddrPresent )
  1112. {
  1113. m_selfH245Addr = proceedingASN.h245Addr;
  1114. }
  1115. if( proceedingASN.fFastStartPresent &&
  1116. (m_dwFastStart!=FAST_START_NOTAVAIL) )
  1117. {
  1118. _ASSERTE( m_pFastStart == NULL );
  1119. m_pFastStart = proceedingASN.pFastStart;
  1120. m_dwFastStart = FAST_START_AVAIL;
  1121. //we keep a reference to the fast start list so don't release it
  1122. proceedingASN.pFastStart = NULL;
  1123. proceedingASN.fFastStartPresent = FALSE;
  1124. }
  1125. else
  1126. {
  1127. m_dwFastStart = FAST_START_NOTAVAIL;
  1128. }
  1129. FreeProceedingASN( &proceedingASN );
  1130. }
  1131. else
  1132. {
  1133. m_dwFastStart = FAST_START_NOTAVAIL;
  1134. }
  1135. if( m_fCallAccepted )
  1136. {
  1137. // validate status
  1138. if( !AcceptH323Call() )
  1139. {
  1140. H323DBG(( DEBUG_LEVEL_ERROR,
  1141. "error answering call 0x%08lx.", this ));
  1142. // failure
  1143. goto cleanup;
  1144. }
  1145. //lock the primary call after replacement call to avoid deadlock
  1146. if( (m_dwCallType & CALLTYPE_TRANSFEREDDEST) && m_hdRelatedCall )
  1147. {
  1148. QueueSuppServiceWorkItem( SWAP_REPLACEMENT_CALL,
  1149. m_hdCall, (ULONG_PTR)m_hdRelatedCall );
  1150. }
  1151. else
  1152. {
  1153. //send MSP start H245
  1154. SendMSPStartH245( NULL, NULL );
  1155. //tell MSP about connect state
  1156. SendMSPMessage( SP_MSG_ConnectComplete, 0, 0, NULL );
  1157. }
  1158. //change call state to accepted from offering
  1159. ChangeCallState( LINECALLSTATE_CONNECTED, 0 );
  1160. }
  1161. H323DBG(( DEBUG_LEVEL_ERROR, "HandleReadyToAnswer exited:%p.",this ));
  1162. return TRUE;
  1163. cleanup:
  1164. CloseCall( 0 );
  1165. return FALSE;
  1166. }
  1167. //!!This function must be always called in a lock. The calling function should
  1168. //not unlock the call object as this function itself unlocks the call object
  1169. BOOL
  1170. CH323Call::HandleMSPMessage(
  1171. IN PTspMspMessage pMessage,
  1172. IN HDRVMSPLINE hdMSPLine,
  1173. IN HTAPIMSPLINE htMSPLine
  1174. )
  1175. {
  1176. BOOL fResult = TRUE;
  1177. PH323_CALL pCall = NULL;
  1178. ASN1octetstring_t pH245PDU;
  1179. H323DBG(( DEBUG_LEVEL_TRACE, "HandleMSPMessage entered:%p.",this ));
  1180. H323DBG(( DEBUG_LEVEL_TRACE, "MSP message:%s recvd.",
  1181. H323TSPMessageToString(pMessage->MessageType) ));
  1182. switch( pMessage -> MessageType )
  1183. {
  1184. case SP_MSG_ReadyToInitiate:
  1185. // The Q.931 connection should be in the connected state by now
  1186. if( pMessage -> MsgBody.ReadyToInitiateMessage.hMSPReplacementCall != NULL )
  1187. {
  1188. //unlock the primary call before locking the related call
  1189. Unlock();
  1190. pCall=g_pH323Line -> FindH323CallAndLock(m_hdRelatedCall);
  1191. if( pCall == NULL )
  1192. {
  1193. //transfered call is not around so close the primary call
  1194. CloseCall( 0 );
  1195. return TRUE;
  1196. }
  1197. fResult = pCall -> HandleReadyToInitiate( pMessage );
  1198. pCall -> Unlock();
  1199. }
  1200. else
  1201. {
  1202. m_hdMSPLine = hdMSPLine;
  1203. m_htMSPLine = htMSPLine;
  1204. fResult = HandleReadyToInitiate( pMessage );
  1205. Unlock();
  1206. }
  1207. break;
  1208. case SP_MSG_ProceedWithAnswer:
  1209. if( pMessage -> MsgBody.ProceedWithAnswerMessage.hMSPReplacementCall != NULL )
  1210. {
  1211. //unlock the primary call before locking the related call
  1212. Unlock();
  1213. pCall=g_pH323Line -> FindH323CallAndLock(m_hdRelatedCall);
  1214. if( pCall == NULL )
  1215. {
  1216. //transfered call is not around so close the primary call
  1217. CloseCall( 0 );
  1218. return FALSE;
  1219. }
  1220. fResult = pCall -> HandleProceedWithAnswer( pMessage );
  1221. pCall -> Unlock();
  1222. }
  1223. else
  1224. {
  1225. m_hdMSPLine = hdMSPLine;
  1226. m_htMSPLine = htMSPLine;
  1227. fResult = HandleProceedWithAnswer( pMessage );
  1228. Unlock();
  1229. }
  1230. break;
  1231. case SP_MSG_ReadyToAnswer:
  1232. if( pMessage -> MsgBody.ReadyToAnswerMessage.hMSPReplacementCall != NULL )
  1233. {
  1234. //unlock the primary call before locking the related call
  1235. Unlock();
  1236. pCall=g_pH323Line -> FindH323CallAndLock(m_hdRelatedCall);
  1237. if( pCall== NULL )
  1238. {
  1239. //transfered call is not around so close the primary call
  1240. CloseCall( 0 );
  1241. return FALSE;
  1242. }
  1243. fResult = pCall -> HandleReadyToAnswer( pMessage );
  1244. pCall -> Unlock();
  1245. }
  1246. else
  1247. {
  1248. //decode call_proceding message and extract local fast
  1249. //start inforamtion and local H245 address
  1250. fResult = HandleReadyToAnswer( pMessage );
  1251. Unlock();
  1252. }
  1253. break;
  1254. case SP_MSG_ReleaseCall:
  1255. //shutdown the H323 call
  1256. CloseCall( LINEDISCONNECTMODE_CANCELLED );
  1257. Unlock();
  1258. break;
  1259. case SP_MSG_H245Terminated:
  1260. //shutdown the H323 call
  1261. CloseCall( LINEDISCONNECTMODE_NORMAL );
  1262. Unlock();
  1263. break;
  1264. case SP_MSG_SendDTMFDigits:
  1265. if( m_fMonitoringDigits == TRUE )
  1266. {
  1267. WCHAR * pwch = pMessage->pWideChars;
  1268. H323DBG(( DEBUG_LEVEL_VERBOSE, "dtmf digits recvd:%S.", pwch));
  1269. // process each digit
  1270. WORD indexI=0;
  1271. while( indexI < pMessage->MsgBody.SendDTMFDigitsMessage.wNumDigits )
  1272. {
  1273. // signal incoming
  1274. PostLineEvent(
  1275. LINE_MONITORDIGITS,
  1276. (DWORD_PTR)*pwch,
  1277. LINEDIGITMODE_DTMF,
  1278. GetTickCount()
  1279. );
  1280. ++pwch;
  1281. indexI++;
  1282. }
  1283. }
  1284. Unlock();
  1285. break;
  1286. case SP_MSG_LegacyDefaultAlias:
  1287. if( pMessage -> MsgBody.LegacyDefaultAliasMessage.wNumChars > 0 )
  1288. {
  1289. if( !RasIsRegistered() )
  1290. {
  1291. _ASSERTE( m_pwszDisplay == NULL );
  1292. m_pwszDisplay = new WCHAR[
  1293. pMessage -> MsgBody.LegacyDefaultAliasMessage.wNumChars ];
  1294. if( m_pwszDisplay != NULL )
  1295. {
  1296. CopyMemory(
  1297. (PVOID)m_pwszDisplay,
  1298. pMessage->pWideChars,
  1299. sizeof(WCHAR) * pMessage -> MsgBody.LegacyDefaultAliasMessage.wNumChars
  1300. );
  1301. }
  1302. }
  1303. }
  1304. Unlock();
  1305. break;
  1306. case SP_MSG_H245PDU:
  1307. if( (pMessage ->pEncodedASNBuf) && (pMessage->dwEncodedASNSize != 0) )
  1308. {
  1309. pH245PDU.value = pMessage ->pEncodedASNBuf;
  1310. pH245PDU.length = pMessage->dwEncodedASNSize;
  1311. fResult = SendQ931Message( NO_INVOKEID, 0, (ULONG_PTR)&pH245PDU,
  1312. FACILITYMESSAGETYPE, NO_H450_APDU );
  1313. }
  1314. Unlock();
  1315. break;
  1316. case SP_MSG_RASRegistrationEvent:
  1317. default:
  1318. _ASSERTE(0);
  1319. Unlock();
  1320. break;
  1321. }
  1322. H323DBG(( DEBUG_LEVEL_ERROR, "HandleMSPMessage exited:%p.",this ));
  1323. return fResult;
  1324. }
  1325. //!!always called in a lock
  1326. void
  1327. CH323Call::SendMSPMessage(
  1328. IN TspMspMessageType messageType,
  1329. IN BYTE* pbEncodedBuf,
  1330. IN DWORD dwLength,
  1331. IN HDRVCALL hReplacementCall
  1332. )
  1333. {
  1334. TspMspMessageEx messageEx;
  1335. HTAPIMSPLINE hMSP = MSP_HANDLE_UNKNOWN;
  1336. int iError = 0;
  1337. int iLen = sizeof(SOCKADDR_IN);
  1338. SOCKADDR_IN* psaLocalQ931Addr = NULL;
  1339. H323DBG(( DEBUG_LEVEL_ERROR, "SendMSPMessage:%s entered:%p.",
  1340. H323TSPMessageToString(messageType), this ));
  1341. messageEx.message.MessageType = messageType;
  1342. switch( messageType )
  1343. {
  1344. case SP_MSG_InitiateCall:
  1345. messageEx.message.MsgBody.InitiateCallMessage.hTSPReplacementCall =
  1346. (HANDLE)hReplacementCall;
  1347. messageEx.message.MsgBody.InitiateCallMessage.hTSPConferenceCall =
  1348. m_hdConf;
  1349. psaLocalQ931Addr =
  1350. &messageEx.message.MsgBody.InitiateCallMessage.saLocalQ931Addr;
  1351. ZeroMemory( (PVOID)psaLocalQ931Addr, sizeof(SOCKADDR_IN) );
  1352. *psaLocalQ931Addr = m_LocalAddr;
  1353. psaLocalQ931Addr->sin_family = AF_INET;
  1354. break;
  1355. case SP_MSG_PrepareToAnswer:
  1356. if( (dwLength<=0) || (dwLength > sizeof(messageEx.pEncodedASN)) ||
  1357. (!pbEncodedBuf) )
  1358. {
  1359. CloseCall( 0 );
  1360. return;
  1361. }
  1362. messageEx.message.MsgBody.PrepareToAnswerMessage.hReplacementCall =
  1363. (HANDLE)hReplacementCall;
  1364. psaLocalQ931Addr =
  1365. &messageEx.message.MsgBody.PrepareToAnswerMessage.saLocalQ931Addr;
  1366. ZeroMemory( (PVOID)psaLocalQ931Addr, sizeof(SOCKADDR_IN) );
  1367. *psaLocalQ931Addr = m_LocalAddr;
  1368. psaLocalQ931Addr->sin_family = AF_INET;
  1369. //send the received Setup message. This should have the information
  1370. //about m_pPeerFastStart param as wel
  1371. CopyMemory( (PVOID)messageEx.message.pEncodedASNBuf,
  1372. (PVOID)pbEncodedBuf, dwLength );
  1373. break;
  1374. case SP_MSG_SendDTMFDigits:
  1375. if( (dwLength<=0) || (dwLength > sizeof(messageEx.pEncodedASN)) ||
  1376. (!pbEncodedBuf) )
  1377. {
  1378. CloseCall( 0 );
  1379. return;
  1380. }
  1381. hMSP = m_htMSPLine;
  1382. messageEx.message.MsgBody.SendDTMFDigitsMessage.wNumDigits =
  1383. (WORD)dwLength;
  1384. dwLength = (dwLength+1) * sizeof(WCHAR);
  1385. CopyMemory( (PVOID)messageEx.message.pEncodedASNBuf,
  1386. (PVOID)pbEncodedBuf, dwLength );
  1387. break;
  1388. case SP_MSG_ConnectComplete:
  1389. case SP_MSG_CallShutdown:
  1390. //dont set anything
  1391. hMSP = m_htMSPLine;
  1392. break;
  1393. case SP_MSG_H245PDU:
  1394. case SP_MSG_AnswerCall:
  1395. hMSP = m_htMSPLine;
  1396. break;
  1397. case SP_MSG_Hold:
  1398. hMSP = m_htMSPLine;
  1399. messageEx.message.MsgBody.HoldMessage.fHold = (BOOL)dwLength;
  1400. dwLength = 0;
  1401. break;
  1402. }
  1403. messageEx.message.dwMessageSize = sizeof(TspMspMessage) + dwLength
  1404. - ((dwLength)?sizeof(WORD):0);
  1405. if( messageType == SP_MSG_SendDTMFDigits )
  1406. {
  1407. messageEx.message.dwEncodedASNSize = 0;
  1408. }
  1409. else
  1410. {
  1411. messageEx.message.dwEncodedASNSize = dwLength;
  1412. }
  1413. //send msp message
  1414. PostLineEvent (
  1415. LINE_SENDMSPDATA,
  1416. (DWORD_PTR)hMSP, //This handle should be NULL when htCall param is a valid value
  1417. (DWORD_PTR)&(messageEx.message),
  1418. messageEx.message.dwMessageSize);
  1419. H323DBG(( DEBUG_LEVEL_ERROR, "SendMSPMessage exited:%p.",this ));
  1420. return;
  1421. }
  1422. //always called in lock
  1423. void
  1424. CH323Call::SendMSPStartH245(
  1425. PH323_ADDR pPeerH245Addr,
  1426. PH323_FASTSTART pPeerFastStart
  1427. )
  1428. {
  1429. TspMspMessageEx messageEx;
  1430. WORD wEncodedLength;
  1431. BYTE* pEncodedASNBuffer;
  1432. H323DBG(( DEBUG_LEVEL_ERROR, "SendMSPStartH245 entered:%p.", this ));
  1433. wEncodedLength = 0;
  1434. messageEx.message.MessageType = SP_MSG_StartH245;
  1435. messageEx.message.MsgBody.StartH245Message.hMSPReplaceCall = NULL;
  1436. messageEx.message.MsgBody.StartH245Message.hTSPReplacementCall =
  1437. (HANDLE)pPeerH245Addr;
  1438. ZeroMemory( messageEx.message.MsgBody.StartH245Message.ConferenceID,
  1439. sizeof(GUID) );
  1440. messageEx.message.MsgBody.StartH245Message.fH245TunnelCapability = FALSE;
  1441. messageEx.message.MsgBody.StartH245Message.fH245AddressPresent = FALSE;
  1442. memset( (PVOID)&messageEx.message.MsgBody.StartH245Message.saH245Addr,
  1443. 0, sizeof(SOCKADDR_IN) );
  1444. //for outgoing call send the fast start proposal.
  1445. if( (m_dwOrigin==LINECALLORIGIN_OUTBOUND) || pPeerH245Addr )
  1446. {
  1447. if( pPeerH245Addr == NULL )
  1448. {
  1449. pPeerFastStart = m_pPeerFastStart;
  1450. }
  1451. if( pPeerFastStart != NULL )
  1452. {
  1453. if( !EncodeFastStartProposal( pPeerFastStart, &pEncodedASNBuffer,
  1454. &wEncodedLength ) )
  1455. {
  1456. CloseCall( 0 );
  1457. return;
  1458. }
  1459. CopyMemory( (PVOID)messageEx.message.pEncodedASNBuf,
  1460. (PVOID)pEncodedASNBuffer, wEncodedLength );
  1461. ASN1_FreeEncoded(m_ASNCoderInfo.pEncInfo, pEncodedASNBuffer );
  1462. }
  1463. }
  1464. //If outgoing call send peer's H245 address
  1465. if( (m_dwOrigin == LINECALLORIGIN_OUTBOUND) || pPeerH245Addr )
  1466. {
  1467. if( pPeerH245Addr == NULL )
  1468. {
  1469. pPeerH245Addr = &m_peerH245Addr;
  1470. }
  1471. messageEx.message.MsgBody.StartH245Message.fH245AddressPresent = FALSE;
  1472. if( pPeerH245Addr->Addr.IP_Binary.dwAddr != 0 )
  1473. {
  1474. messageEx.message.MsgBody.StartH245Message.saH245Addr.sin_family = AF_INET;
  1475. messageEx.message.MsgBody.StartH245Message.saH245Addr.sin_port =
  1476. htons(pPeerH245Addr->Addr.IP_Binary.wPort);
  1477. messageEx.message.MsgBody.StartH245Message.saH245Addr.sin_addr.s_addr =
  1478. htonl(pPeerH245Addr->Addr.IP_Binary.dwAddr);
  1479. messageEx.message.MsgBody.StartH245Message.fH245AddressPresent = TRUE;
  1480. }
  1481. }
  1482. //set the Q931 address
  1483. ZeroMemory( (PVOID)&messageEx.message.MsgBody.StartH245Message.saQ931Addr,
  1484. sizeof(SOCKADDR_IN) );
  1485. messageEx.message.MsgBody.StartH245Message.saQ931Addr.sin_family = AF_INET;
  1486. messageEx.message.MsgBody.StartH245Message.saQ931Addr.sin_port =
  1487. htons( m_CalleeAddr.Addr.IP_Binary.wPort );
  1488. messageEx.message.MsgBody.StartH245Message.saQ931Addr.sin_addr.s_addr =
  1489. htonl( m_CalleeAddr.Addr.IP_Binary.dwAddr );
  1490. messageEx.message.MsgBody.StartH245Message.fH245TunnelCapability =
  1491. (m_fh245Tunneling & REMOTE_H245_TUNNELING) &&
  1492. (m_fh245Tunneling & LOCAL_H245_TUNNELING);
  1493. messageEx.message.dwMessageSize = sizeof(messageEx.message) +
  1494. wEncodedLength - ((wEncodedLength)?1:0);
  1495. messageEx.message.dwEncodedASNSize = wEncodedLength;
  1496. // send msp message
  1497. PostLineEvent (
  1498. LINE_SENDMSPDATA,
  1499. //this handle should be NULL when htCall is a valid handle.
  1500. (DWORD_PTR)NULL,
  1501. (DWORD_PTR)&(messageEx.message),
  1502. messageEx.message.dwMessageSize);
  1503. m_dwFlags |= H245_START_MSG_SENT;
  1504. H323DBG(( DEBUG_LEVEL_ERROR, "SendMSPStartH245 exited:%p.",this ));
  1505. return;
  1506. }
  1507. //always called in lock
  1508. BOOL
  1509. CH323Call::AddU2U(
  1510. IN DWORD dwDirection,
  1511. IN DWORD dwDataSize,
  1512. IN PBYTE pData
  1513. )
  1514. /*++
  1515. Routine Description:
  1516. Create user user structure and adds to list.
  1517. Arguments:
  1518. pLftHead - Pointer to list in which to add user user info.
  1519. dwDataSize - Size of buffer pointed to by pData.
  1520. pData - Pointer to user user info.
  1521. Return Values:
  1522. Returns true if successful.
  1523. --*/
  1524. {
  1525. PLIST_ENTRY pListHead = NULL;
  1526. PUserToUserLE pU2ULE;
  1527. H323DBG(( DEBUG_LEVEL_ERROR, "AddU2U entered:%p.",this ));
  1528. if( dwDirection == U2U_OUTBOUND )
  1529. {
  1530. pListHead = &m_OutgoingU2U;
  1531. }
  1532. else
  1533. {
  1534. pListHead = &m_IncomingU2U;
  1535. }
  1536. // validate data buffer pointer and size
  1537. if( (pData != NULL) && (dwDataSize > 0) )
  1538. {
  1539. // allocate memory for user user info
  1540. pU2ULE = new UserToUserLE;
  1541. // validate pointer
  1542. if (pU2ULE == NULL)
  1543. {
  1544. H323DBG(( DEBUG_LEVEL_ERROR,
  1545. "could not allocate user user info." ));
  1546. // failure
  1547. return FALSE;
  1548. }
  1549. // aim pointer at the end of the buffer by default
  1550. pU2ULE->pU2U = new BYTE[ dwDataSize ];
  1551. // validate pointer
  1552. if (pU2ULE->pU2U == NULL)
  1553. {
  1554. H323DBG(( DEBUG_LEVEL_ERROR,
  1555. "could not allocate user user info." ));
  1556. delete pU2ULE;
  1557. // failure
  1558. return FALSE;
  1559. }
  1560. pU2ULE->dwU2USize = dwDataSize;
  1561. // transfer user user info into list entry
  1562. CopyMemory( (PVOID)pU2ULE->pU2U, (PVOID)pData, pU2ULE->dwU2USize);
  1563. // add list entry to back of list
  1564. InsertTailList(pListHead, &pU2ULE->Link);
  1565. H323DBG(( DEBUG_LEVEL_VERBOSE,
  1566. "added user user info 0x%08lx (%d bytes).",
  1567. pU2ULE->pU2U,
  1568. pU2ULE->dwU2USize
  1569. ));
  1570. }
  1571. H323DBG(( DEBUG_LEVEL_ERROR, "AddU2U exited:%p.",this ));
  1572. // success
  1573. return TRUE;
  1574. }
  1575. /*++
  1576. Routine Description:
  1577. Create user user structure and adds to list.
  1578. !!always called in lock.
  1579. Arguments:
  1580. pLftHead - Pointer to list in which to add user user info.
  1581. dwDataSize - Size of buffer pointed to by pData.
  1582. pData - Pointer to user user info.
  1583. Return Values:
  1584. Returns true if successful.
  1585. --*/
  1586. BOOL
  1587. CH323Call::AddU2UNoAlloc(
  1588. IN DWORD dwDirection,
  1589. IN DWORD dwDataSize,
  1590. IN PBYTE pData
  1591. )
  1592. {
  1593. PLIST_ENTRY pListHead = NULL;
  1594. PUserToUserLE pU2ULE;
  1595. H323DBG(( DEBUG_LEVEL_ERROR, "AddU2U entered:%p.",this ));
  1596. if( dwDirection == U2U_OUTBOUND )
  1597. {
  1598. pListHead = &m_OutgoingU2U;
  1599. }
  1600. else
  1601. {
  1602. pListHead = &m_IncomingU2U;
  1603. }
  1604. // validate data buffer pointer and size
  1605. if( (pData != NULL) && (dwDataSize > 0) )
  1606. {
  1607. // allocate memory for user user info
  1608. pU2ULE = new UserToUserLE;
  1609. // validate pointer
  1610. if (pU2ULE == NULL)
  1611. {
  1612. H323DBG(( DEBUG_LEVEL_ERROR,
  1613. "could not allocate user user info." ));
  1614. // failure
  1615. return FALSE;
  1616. }
  1617. // aim pointer at the end of the buffer by default
  1618. pU2ULE->pU2U = pData;
  1619. pU2ULE->dwU2USize = dwDataSize;
  1620. // add list entry to back of list
  1621. InsertTailList(pListHead, &pU2ULE->Link);
  1622. H323DBG(( DEBUG_LEVEL_VERBOSE,
  1623. "added user user info 0x%08lx (%d bytes).",
  1624. pU2ULE->pU2U,
  1625. pU2ULE->dwU2USize
  1626. ));
  1627. }
  1628. H323DBG(( DEBUG_LEVEL_ERROR, "AddU2U exited:%p.",this ));
  1629. // success
  1630. return TRUE;
  1631. }
  1632. //!!must be always called in a lock.
  1633. BOOL
  1634. CH323Call::RemoveU2U(
  1635. IN DWORD dwDirection,
  1636. IN PUserToUserLE * ppU2ULE
  1637. )
  1638. /*++
  1639. Routine Description:
  1640. Removes user user info structure from list.
  1641. Arguments:
  1642. pListHead - Pointer to list in which to remove user user info.
  1643. ppU2ULE - Pointer to pointer to list entry.
  1644. Return Values:
  1645. Returns true if successful.
  1646. --*/
  1647. {
  1648. PLIST_ENTRY pListHead = NULL;
  1649. PLIST_ENTRY pLE;
  1650. H323DBG(( DEBUG_LEVEL_ERROR, "RemoveU2U entered:%p.",this ));
  1651. if( dwDirection == U2U_OUTBOUND )
  1652. {
  1653. pListHead = &m_OutgoingU2U;
  1654. }
  1655. else
  1656. {
  1657. pListHead = &m_IncomingU2U;
  1658. }
  1659. // process list until empty
  1660. if( IsListEmpty(pListHead) == FALSE )
  1661. {
  1662. // retrieve first entry
  1663. pLE = RemoveHeadList(pListHead);
  1664. // convert list entry to structure pointer
  1665. *ppU2ULE = CONTAINING_RECORD(pLE, UserToUserLE, Link);
  1666. H323DBG(( DEBUG_LEVEL_VERBOSE,
  1667. "removed user user info 0x%08lx (%d bytes).",
  1668. (*ppU2ULE)->pU2U, (*ppU2ULE)->dwU2USize ));
  1669. H323DBG(( DEBUG_LEVEL_ERROR, "RemoveU2U exited:%p.",this ));
  1670. // success
  1671. return TRUE;
  1672. }
  1673. // failure
  1674. return FALSE;
  1675. }
  1676. BOOL
  1677. CH323Call::FreeU2U(
  1678. IN DWORD dwDirection
  1679. )
  1680. /*++
  1681. Routine Description:
  1682. Releases memory for user user list.
  1683. !!must be always called in a lock.
  1684. Arguments
  1685. pListHead - Pointer to list in which to free user user info.
  1686. Return Values:
  1687. Returns true if successful.
  1688. --*/
  1689. {
  1690. PLIST_ENTRY pLE;
  1691. PUserToUserLE pU2ULE;
  1692. PLIST_ENTRY pListHead = NULL;
  1693. H323DBG(( DEBUG_LEVEL_ERROR, "FreeU2U entered:%p.",this ));
  1694. if( dwDirection == U2U_OUTBOUND )
  1695. {
  1696. pListHead = &m_OutgoingU2U;
  1697. }
  1698. else
  1699. {
  1700. pListHead = &m_IncomingU2U;
  1701. }
  1702. // process list until empty
  1703. while( IsListEmpty(pListHead) == FALSE )
  1704. {
  1705. // retrieve first entry
  1706. pLE = RemoveHeadList(pListHead);
  1707. // convert list entry to structure pointer
  1708. pU2ULE = CONTAINING_RECORD(pLE, UserToUserLE, Link);
  1709. // release memory
  1710. if( pU2ULE )
  1711. {
  1712. delete pU2ULE;
  1713. pU2ULE = NULL;
  1714. }
  1715. }
  1716. H323DBG(( DEBUG_LEVEL_ERROR, "FreeU2U exited:%p.",this ));
  1717. // success
  1718. return TRUE;
  1719. }
  1720. /*++
  1721. Routine Description:
  1722. Resets call object to original state for re-use.
  1723. Arguments:
  1724. Return Values:
  1725. Returns true if successful.
  1726. --*/
  1727. void
  1728. CH323Call::Shutdown(
  1729. OUT BOOL * fDelete
  1730. )
  1731. {
  1732. H323DBG(( DEBUG_LEVEL_ERROR, "Shutdown entered:%p.",this ));
  1733. if( !(m_dwFlags & CALLOBJECT_INITIALIZED) )
  1734. {
  1735. return;
  1736. }
  1737. //acquire the lock on call table before acquiring the lock on call object
  1738. g_pH323Line -> LockCallTable();
  1739. Lock();
  1740. if( m_dwFlags & CALLOBJECT_SHUTDOWN )
  1741. {
  1742. Unlock();
  1743. g_pH323Line -> UnlockCallTable();
  1744. return;
  1745. }
  1746. // reset tapi info
  1747. m_dwCallState = LINECALLSTATE_UNKNOWN;
  1748. m_dwCallStateMode = 0;
  1749. m_dwOrigin = LINECALLORIGIN_UNKNOWN;
  1750. m_dwAddressType = 0;
  1751. m_dwIncomingModes = 0;
  1752. m_dwOutgoingModes = 0;
  1753. m_dwRequestedModes = 0;
  1754. m_fMonitoringDigits = FALSE;
  1755. // reset tapi handles
  1756. m_htCall = (HTAPICALL)NULL;
  1757. // reset addresses
  1758. memset( (PVOID)&m_CalleeAddr,0,sizeof(H323_ADDR));
  1759. memset( (PVOID)&m_CallerAddr,0,sizeof(H323_ADDR));
  1760. H323DBG(( DEBUG_LEVEL_ERROR, "deleting calleealias:%p.",this ));
  1761. FreeAliasNames( m_pCalleeAliasNames );
  1762. m_pCalleeAliasNames = NULL;
  1763. if( m_pCallerAliasNames != NULL )
  1764. {
  1765. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  1766. FreeAliasNames( m_pCallerAliasNames );
  1767. m_pCallerAliasNames = NULL;
  1768. }
  1769. //reset non standard data
  1770. memset( (PVOID)&m_NonStandardData, 0, sizeof(H323NonStandardData) );
  1771. // release user user information
  1772. FreeU2U( U2U_OUTBOUND );
  1773. FreeU2U( U2U_INBOUND );
  1774. //shutdown the Q931 call if not shutdown yet
  1775. if( m_hSetupSentTimer != NULL )
  1776. {
  1777. DeleteTimerQueueTimer( H323TimerQueue, m_hSetupSentTimer, NULL );
  1778. m_hSetupSentTimer = NULL;
  1779. }
  1780. if( m_hCallEstablishmentTimer )
  1781. {
  1782. DeleteTimerQueueTimer(H323TimerQueue, m_hCallEstablishmentTimer, NULL);
  1783. m_hCallEstablishmentTimer = NULL;
  1784. }
  1785. if( m_hCallDivertOnNATimer )
  1786. {
  1787. DeleteTimerQueueTimer(H323TimerQueue, m_hCallDivertOnNATimer, NULL);
  1788. m_hCallDivertOnNATimer = NULL;
  1789. }
  1790. *fDelete = FALSE;
  1791. if( m_IoRefCount == 0 )
  1792. {
  1793. *fDelete = TRUE;
  1794. }
  1795. m_dwStateMachine = Q931_CALL_STATE_NONE;
  1796. if( m_callSocket != INVALID_SOCKET )
  1797. {
  1798. if(shutdown( m_callSocket, SD_BOTH ) == SOCKET_ERROR)
  1799. {
  1800. H323DBG((DEBUG_LEVEL_TRACE, "couldn't shutdown the socket:%d, %p.",
  1801. WSAGetLastError(), this ));
  1802. }
  1803. closesocket( m_callSocket );
  1804. m_callSocket = INVALID_SOCKET;
  1805. }
  1806. m_pwszDisplay = NULL;
  1807. FreeVendorInfo( &m_peerVendorInfo );
  1808. if( m_peerNonStandardData.sData.pOctetString )
  1809. {
  1810. H323DBG(( DEBUG_LEVEL_ERROR, "deleting nonstd:%p.",this ));
  1811. delete m_peerNonStandardData.sData.pOctetString;
  1812. m_peerNonStandardData.sData.pOctetString = NULL;
  1813. }
  1814. H323DBG(( DEBUG_LEVEL_ERROR, "deleting xtraalias:%p.",this ));
  1815. FreeAliasNames( m_pPeerExtraAliasNames );
  1816. m_pPeerExtraAliasNames = NULL;
  1817. H323DBG(( DEBUG_LEVEL_ERROR, "deleting display:%p.",this ));
  1818. if( m_pPeerDisplay )
  1819. {
  1820. delete m_pPeerDisplay;
  1821. m_pPeerDisplay = NULL;
  1822. }
  1823. if( m_CallData.pOctetString != NULL )
  1824. {
  1825. delete m_CallData.pOctetString;
  1826. }
  1827. H323DBG(( DEBUG_LEVEL_ERROR, "deleting hdconf:%p.",this ));
  1828. // delete conference
  1829. if( m_hdConf != NULL )
  1830. {
  1831. g_pH323Line -> GetH323ConfTable() -> Remove( m_hdConf );
  1832. delete m_hdConf;
  1833. m_hdConf = NULL;
  1834. }
  1835. H323DBG(( DEBUG_LEVEL_ERROR, "deleting preparetoans:%p.",this ));
  1836. if( m_prepareToAnswerMsgData.pbBuffer )
  1837. {
  1838. delete m_prepareToAnswerMsgData.pbBuffer;
  1839. }
  1840. ZeroMemory( (PVOID)&m_prepareToAnswerMsgData, sizeof(BUFFERDESCR) );
  1841. H323DBG(( DEBUG_LEVEL_ERROR, "deleting drq timer:%p.",this ));
  1842. //ras related data structures
  1843. if( m_hDRQTimer != NULL )
  1844. {
  1845. DeleteTimerQueueTimer( H323TimerQueue, m_hDRQTimer, NULL );
  1846. m_hDRQTimer = NULL;
  1847. }
  1848. H323DBG(( DEBUG_LEVEL_ERROR, "deleting arq timer:%p.",this ));
  1849. if( m_hARQTimer != NULL )
  1850. {
  1851. DeleteTimerQueueTimer( H323TimerQueue, m_hARQTimer, NULL );
  1852. m_hARQTimer = NULL;
  1853. }
  1854. if( m_pPeerFastStart != NULL )
  1855. {
  1856. FreeFastStart( m_pPeerFastStart );
  1857. m_pPeerFastStart = NULL;
  1858. }
  1859. if( m_pFastStart != NULL )
  1860. {
  1861. FreeFastStart( m_pFastStart );
  1862. m_pFastStart = NULL;
  1863. }
  1864. if( m_pARQExpireContext != NULL )
  1865. {
  1866. delete m_pARQExpireContext;
  1867. m_pARQExpireContext = NULL;
  1868. }
  1869. if( m_pDRQExpireContext != NULL )
  1870. {
  1871. delete m_pDRQExpireContext;
  1872. m_pDRQExpireContext = NULL;
  1873. }
  1874. FreeCallForwardData();
  1875. g_pH323Line -> RemoveCallFromTable (m_hdCall);
  1876. m_dwFlags |= CALLOBJECT_SHUTDOWN;
  1877. Unlock();
  1878. g_pH323Line -> UnlockCallTable();
  1879. H323DBG(( DEBUG_LEVEL_ERROR, "Shutdown exited:%p.",this ));
  1880. return;
  1881. }
  1882. void
  1883. CH323Call::FreeCallForwardData()
  1884. {
  1885. if( m_pCallReroutingInfo )
  1886. {
  1887. FreeCallReroutingInfo();
  1888. }
  1889. if( m_hCheckRestrictionTimer )
  1890. {
  1891. DeleteTimerQueueTimer( H323TimerQueue, m_hCheckRestrictionTimer,
  1892. NULL );
  1893. m_hCheckRestrictionTimer = NULL;
  1894. }
  1895. if( m_hCallReroutingTimer )
  1896. {
  1897. DeleteTimerQueueTimer( H323TimerQueue, m_hCallReroutingTimer, NULL );
  1898. m_hCallReroutingTimer = NULL;
  1899. }
  1900. if( m_hCTIdentifyTimer )
  1901. {
  1902. DeleteTimerQueueTimer( H323TimerQueue, m_hCTIdentifyTimer, NULL );
  1903. m_hCTIdentifyTimer = NULL;
  1904. }
  1905. if( m_hCTIdentifyRRTimer )
  1906. {
  1907. DeleteTimerQueueTimer( H323TimerQueue, m_hCTIdentifyRRTimer, NULL );
  1908. m_hCTIdentifyRRTimer = NULL;
  1909. }
  1910. if( m_hCTInitiateTimer )
  1911. {
  1912. DeleteTimerQueueTimer( H323TimerQueue, m_hCTInitiateTimer, NULL );
  1913. m_hCTInitiateTimer = NULL;
  1914. }
  1915. if( m_pTransferedToAlias )
  1916. {
  1917. FreeAliasNames( m_pTransferedToAlias );
  1918. m_pTransferedToAlias = NULL;
  1919. }
  1920. if( m_dwCallType & CALLTYPE_TRANSFERED2_CONSULT )
  1921. {
  1922. g_pH323Line -> RemoveFromCTCallIdentityTable( m_hdCall );
  1923. }
  1924. if( m_H450ASNCoderInfo.pEncInfo )
  1925. {
  1926. TermH450ASNCoder();
  1927. }
  1928. if( m_pCallForwardParams )
  1929. {
  1930. FreeCallForwardParams( m_pCallForwardParams );
  1931. m_pCallForwardParams = NULL;
  1932. }
  1933. if( m_pForwardAddress )
  1934. {
  1935. FreeForwardAddress( m_pForwardAddress );
  1936. m_pForwardAddress = NULL;
  1937. }
  1938. }
  1939. BOOL
  1940. CH323Call::ResolveCallerAddress(void)
  1941. /*++
  1942. Routine Description:
  1943. Resolves caller address from callee address.
  1944. !!must be always called in a lock.
  1945. Arguments:
  1946. Return Values:
  1947. Returns true if successful.
  1948. --*/
  1949. {
  1950. INT nStatus;
  1951. SOCKET hCtrlSocket = INVALID_SOCKET;
  1952. SOCKADDR CalleeSockAddr;
  1953. SOCKADDR CallerSockAddr;
  1954. DWORD dwNumBytesReturned = 0;
  1955. H323DBG(( DEBUG_LEVEL_ERROR, "ResolveCallerAddress entered:%p.",this ));
  1956. // allocate control socket
  1957. hCtrlSocket = WSASocket(
  1958. AF_INET, // af
  1959. SOCK_DGRAM, // type
  1960. IPPROTO_IP, // protocol
  1961. NULL, // lpProtocolInfo
  1962. 0, // g
  1963. WSA_FLAG_OVERLAPPED // dwFlags
  1964. );
  1965. // validate control socket
  1966. if (hCtrlSocket == INVALID_SOCKET)
  1967. {
  1968. H323DBG(( DEBUG_LEVEL_ERROR,
  1969. "error %d creating control socket.", WSAGetLastError() ));
  1970. // failure
  1971. return FALSE;
  1972. }
  1973. // initialize ioctl parameters
  1974. memset( (PVOID)&CalleeSockAddr,0,sizeof(SOCKADDR));
  1975. memset( (PVOID)&CallerSockAddr,0,sizeof(SOCKADDR));
  1976. // initialize address family
  1977. CalleeSockAddr.sa_family = AF_INET;
  1978. // transfer callee information
  1979. ((SOCKADDR_IN*)&CalleeSockAddr)->sin_addr.s_addr =
  1980. htonl(m_CalleeAddr.Addr.IP_Binary.dwAddr);
  1981. // query stack
  1982. nStatus = WSAIoctl(
  1983. hCtrlSocket,
  1984. SIO_ROUTING_INTERFACE_QUERY,
  1985. &CalleeSockAddr,
  1986. sizeof(SOCKADDR),
  1987. &CallerSockAddr,
  1988. sizeof(SOCKADDR),
  1989. &dwNumBytesReturned,
  1990. NULL,
  1991. NULL
  1992. );
  1993. // release handle
  1994. closesocket(hCtrlSocket);
  1995. // validate return code
  1996. if (nStatus == SOCKET_ERROR)
  1997. {
  1998. H323DBG(( DEBUG_LEVEL_ERROR,
  1999. "error 0x%08lx calling SIO_ROUTING_INTERFACE_QUERY.",
  2000. WSAGetLastError() ));
  2001. // failure
  2002. return FALSE;
  2003. }
  2004. // save interface address of best route
  2005. m_CallerAddr.nAddrType = H323_IP_BINARY;
  2006. m_CallerAddr.Addr.IP_Binary.dwAddr =
  2007. ntohl(((SOCKADDR_IN*)&CallerSockAddr)->sin_addr.s_addr);
  2008. m_CallerAddr.Addr.IP_Binary.wPort =
  2009. LOWORD(g_RegistrySettings.dwQ931ListenPort);
  2010. m_CallerAddr.bMulticast =
  2011. IN_MULTICAST(m_CallerAddr.Addr.IP_Binary.dwAddr);
  2012. H323DBG(( DEBUG_LEVEL_TRACE,
  2013. "caller address resolved to %s.",
  2014. H323AddrToString(((SOCKADDR_IN*)&CallerSockAddr)->sin_addr.s_addr) ));
  2015. H323DBG(( DEBUG_LEVEL_ERROR, "ResolveCallerAddress exited:%p.",this ));
  2016. // success
  2017. return TRUE;
  2018. }
  2019. BOOL
  2020. CH323Call::ResolveE164Address(
  2021. IN LPCWSTR pwszDialableAddr
  2022. )
  2023. /*++
  2024. Routine Description:
  2025. Resolves E.164 address ("4259367111").
  2026. !!must be always called in a lock.
  2027. Arguments:
  2028. pwszDialableAddr - Specifies a pointer to the dialable address specified
  2029. by the TAPI application.
  2030. Return Values:
  2031. Returns true if successful.
  2032. --*/
  2033. {
  2034. WCHAR wszAddr[H323_MAXDESTNAMELEN+1];
  2035. DWORD dwE164AddrSize;
  2036. H323DBG(( DEBUG_LEVEL_ERROR, "ResolveE164Address entered:%p.",this ));
  2037. // make sure pstn gateway has been specified
  2038. if ((g_RegistrySettings.fIsGatewayEnabled == FALSE) ||
  2039. (g_RegistrySettings.gatewayAddr.nAddrType == 0))
  2040. {
  2041. H323DBG(( DEBUG_LEVEL_ERROR,
  2042. "pstn gateway not specified."
  2043. ));
  2044. // failure
  2045. return FALSE;
  2046. }
  2047. // save gateway address as callee address
  2048. m_CalleeAddr = g_RegistrySettings.gatewayAddr;
  2049. dwE164AddrSize = ValidateE164Address( pwszDialableAddr, wszAddr );
  2050. if( dwE164AddrSize == 0 )
  2051. {
  2052. H323DBG(( DEBUG_LEVEL_ERROR,
  2053. "invlid e164 callee alias ."));
  2054. return FALSE;
  2055. }
  2056. H323DBG(( DEBUG_LEVEL_TRACE,
  2057. "callee alias resolved to E.164 number." ));
  2058. H323DBG(( DEBUG_LEVEL_ERROR, "ResolveE164Address exited:%p.",this ));
  2059. //determine caller address
  2060. return ResolveCallerAddress();
  2061. }
  2062. DWORD
  2063. ValidateE164Address(
  2064. LPCWSTR pwszDialableAddr,
  2065. WCHAR* wszAddr
  2066. )
  2067. {
  2068. DWORD dwE164AddrSize = 0;
  2069. WCHAR * pwszValidE164Chars;
  2070. WCHAR wszValidE164Chars[] = { H323_ALIAS_H323_PHONE_CHARS L"\0" };
  2071. // process until termination char
  2072. while (*pwszDialableAddr != L'\0')
  2073. {
  2074. // reset pointer to valid characters
  2075. pwszValidE164Chars = wszValidE164Chars;
  2076. // process until termination char
  2077. while (*pwszValidE164Chars != L'\0')
  2078. {
  2079. // see if valid E.164 character specified
  2080. if (*pwszDialableAddr == *pwszValidE164Chars)
  2081. {
  2082. // save valid character in temp buffer
  2083. wszAddr[dwE164AddrSize++] = *pwszDialableAddr;
  2084. break;
  2085. }
  2086. // next valid char
  2087. ++pwszValidE164Chars;
  2088. }
  2089. // next input char
  2090. ++pwszDialableAddr;
  2091. }
  2092. // terminate string
  2093. wszAddr[dwE164AddrSize++] = L'\0';
  2094. // validate string
  2095. if (dwE164AddrSize == 0)
  2096. {
  2097. H323DBG(( DEBUG_LEVEL_TRACE,
  2098. "no valid E.164 characters in string." ));
  2099. }
  2100. return dwE164AddrSize;
  2101. }
  2102. /*++
  2103. Routine Description:
  2104. Resolves IP address ("172.31.255.231") or DNS entry ("NIKHILB1").
  2105. !!must be always called in a lock.
  2106. Arguments:
  2107. pszDialableAddr - Specifies a pointer to the dialable address specified
  2108. by the TAPI application.
  2109. Return Values:
  2110. Returns true if successful.
  2111. --*/
  2112. BOOL
  2113. CH323Call::ResolveIPAddress(
  2114. IN LPSTR pszDialableAddr
  2115. )
  2116. {
  2117. DWORD dwIPAddr;
  2118. struct hostent* pHost;
  2119. H323DBG(( DEBUG_LEVEL_ERROR, "ResolveIPAddress entered:%p.",this ));
  2120. // attempt to convert ip address
  2121. dwIPAddr = inet_addr(pszDialableAddr);
  2122. // see if address converted
  2123. if( dwIPAddr == INADDR_NONE )
  2124. {
  2125. // attempt to lookup hostname
  2126. pHost = gethostbyname(pszDialableAddr);
  2127. // validate pointer
  2128. if( pHost != NULL )
  2129. {
  2130. // retrieve host address from structure
  2131. dwIPAddr = *(unsigned long *)pHost->h_addr;
  2132. }
  2133. }
  2134. // see if address converted
  2135. if( dwIPAddr == INADDR_NONE )
  2136. {
  2137. H323DBG(( DEBUG_LEVEL_ERROR,
  2138. "error 0x%08lx resolving IP address.",
  2139. WSAGetLastError() ));
  2140. // failure
  2141. return FALSE;
  2142. }
  2143. // save converted address
  2144. m_CalleeAddr.nAddrType = H323_IP_BINARY;
  2145. m_CalleeAddr.Addr.IP_Binary.dwAddr = ntohl(dwIPAddr);
  2146. m_CalleeAddr.Addr.IP_Binary.wPort =
  2147. LOWORD(g_RegistrySettings.dwQ931ListenPort);
  2148. m_CalleeAddr.bMulticast =
  2149. IN_MULTICAST(m_CalleeAddr.Addr.IP_Binary.dwAddr);
  2150. H323DBG(( DEBUG_LEVEL_TRACE,
  2151. "callee address resolved to %s:%d.",
  2152. H323AddrToString(dwIPAddr),
  2153. m_CalleeAddr.Addr.IP_Binary.wPort ));
  2154. H323DBG(( DEBUG_LEVEL_ERROR, "ResolveIPAddress exited:%p.",this ));
  2155. // determine caller address
  2156. return ResolveCallerAddress();
  2157. }
  2158. BOOL
  2159. CH323Call::ResolveEmailAddress(
  2160. IN LPCWSTR pwszDialableAddr,
  2161. IN LPSTR pszUser,
  2162. IN LPSTR pszDomain
  2163. )
  2164. /*++
  2165. Routine Description:
  2166. Resolves e-mail address ("[email protected]").
  2167. !!must be always called in a lock.
  2168. Arguments:
  2169. pwszDialableAddr - Specifies a pointer to the dialable address specified
  2170. by the TAPI application.
  2171. pszUser - Specifies a pointer to the user component of e-mail name.
  2172. pszDomain - Specified a pointer to the domain component of e-mail name.
  2173. Return Values:
  2174. Returns true if successful.
  2175. --*/
  2176. {
  2177. DWORD dwAddrSize;
  2178. H323DBG(( DEBUG_LEVEL_ERROR, "ResolveEmailAddress entered:%p.",this ));
  2179. // size destination address string
  2180. dwAddrSize = wcslen(pwszDialableAddr) + 1;
  2181. // attempt to resolve domain locally
  2182. if( ResolveIPAddress( pszDomain) )
  2183. {
  2184. // success
  2185. return TRUE;
  2186. }
  2187. // make sure proxy has been specified
  2188. if( (g_RegistrySettings.fIsProxyEnabled == FALSE) ||
  2189. (g_RegistrySettings.proxyAddr.nAddrType == 0) )
  2190. {
  2191. H323DBG(( DEBUG_LEVEL_ERROR, "proxy not specified." ));
  2192. // failure
  2193. return FALSE;
  2194. }
  2195. // save proxy address as callee address
  2196. m_CalleeAddr = g_RegistrySettings.proxyAddr;
  2197. H323DBG(( DEBUG_LEVEL_TRACE,
  2198. "callee alias resolved to H.323 alias."));
  2199. H323DBG(( DEBUG_LEVEL_ERROR, "ResolveEmailAddress exited:%p.",this ));
  2200. // determine caller address
  2201. return ResolveCallerAddress();
  2202. }
  2203. /*++
  2204. Routine Description:
  2205. Resolves remote address and determines the correct local address
  2206. to use in order to reach remote address.
  2207. !!must be always called in a lock.
  2208. Arguments:
  2209. pwszDialableAddr - Specifies a pointer to the dialable address specified
  2210. by the TAPI application.
  2211. Return Values:
  2212. Returns true if successful.
  2213. --*/
  2214. BOOL
  2215. CH323Call::ResolveAddress(
  2216. IN LPCWSTR pwszDialableAddr
  2217. )
  2218. {
  2219. CHAR szDelimiters[] = "@ \t\n";
  2220. CHAR szAddr[H323_MAXDESTNAMELEN+1];
  2221. LPSTR pszUser = NULL;
  2222. LPSTR pszDomain = NULL;
  2223. H323DBG(( DEBUG_LEVEL_ERROR, "ResolveAddress entered:%p.",this ));
  2224. // validate pointerr
  2225. if (pwszDialableAddr == NULL)
  2226. {
  2227. H323DBG(( DEBUG_LEVEL_ERROR, "null destination address." ));
  2228. // failure
  2229. return FALSE;
  2230. }
  2231. H323DBG(( DEBUG_LEVEL_TRACE,
  2232. "resolving %s %S.",
  2233. H323AddressTypeToString( m_dwAddressType),
  2234. pwszDialableAddr ));
  2235. // check whether phone number has been specified
  2236. if( m_dwAddressType == LINEADDRESSTYPE_PHONENUMBER )
  2237. {
  2238. // need to direct call to pstn gateway
  2239. return ResolveE164Address( pwszDialableAddr);
  2240. }
  2241. // convert address from unicode
  2242. if (WideCharToMultiByte(
  2243. CP_ACP,
  2244. 0,
  2245. pwszDialableAddr,
  2246. -1,
  2247. szAddr,
  2248. sizeof(szAddr),
  2249. NULL,
  2250. NULL
  2251. ) == 0)
  2252. {
  2253. H323DBG(( DEBUG_LEVEL_ERROR,
  2254. "could not convert address from unicode." ));
  2255. // failure
  2256. return FALSE;
  2257. }
  2258. // parse user name
  2259. pszUser = strtok(szAddr, szDelimiters);
  2260. // parse domain name
  2261. pszDomain = strtok(NULL, szDelimiters);
  2262. // validate pointer
  2263. if (pszUser == NULL)
  2264. {
  2265. H323DBG(( DEBUG_LEVEL_ERROR, "could not parse destination address." ));
  2266. // failure
  2267. return FALSE;
  2268. }
  2269. // validate pointer
  2270. if (pszDomain == NULL)
  2271. {
  2272. // switch pointers
  2273. pszDomain = pszUser;
  2274. // re-initialize
  2275. pszUser = NULL;
  2276. }
  2277. H323DBG(( DEBUG_LEVEL_VERBOSE,
  2278. "resolving user %s domain %s.",
  2279. pszUser,
  2280. pszDomain
  2281. ));
  2282. H323DBG(( DEBUG_LEVEL_ERROR, "ResolveAddress exited:%p.",this ));
  2283. // process e-mail and domain names
  2284. return ResolveEmailAddress(
  2285. pwszDialableAddr,
  2286. pszUser,
  2287. pszDomain
  2288. );
  2289. }
  2290. BOOL
  2291. /*++
  2292. Routine Description:
  2293. Validate optional call parameters specified by user.
  2294. !!no need to call in a lock because not added to the call table yet
  2295. Arguments:
  2296. pCallParams - Pointer to specified call parameters to be
  2297. validated.
  2298. pwszDialableAddr - Pointer to the dialable address specified
  2299. by the TAPI application.
  2300. pdwStatus - Pointer to DWORD containing error code if this
  2301. routine fails for any reason.
  2302. Return Values:
  2303. Returns true if successful.
  2304. --*/
  2305. CH323Call::ValidateCallParams(
  2306. IN LPLINECALLPARAMS pCallParams,
  2307. IN LPCWSTR pwszDialableAddr,
  2308. IN PDWORD pdwStatus
  2309. )
  2310. {
  2311. DWORD dwMediaModes = H323_LINE_DEFMEDIAMODES;
  2312. DWORD dwAddrSize;
  2313. WCHAR wszAddr[H323_MAXDESTNAMELEN+1];
  2314. PH323_ALIASNAMES pAliasList;
  2315. WCHAR* wszMachineName;
  2316. H323DBG(( DEBUG_LEVEL_TRACE, "ValidateCallParams entered:%p.", this ));
  2317. H323DBG(( DEBUG_LEVEL_VERBOSE, "clearing unknown media mode." ));
  2318. // validate pointer
  2319. if( (pCallParams == NULL) || (pwszDialableAddr == NULL) )
  2320. {
  2321. return FALSE;
  2322. }
  2323. // retrieve media modes specified
  2324. dwMediaModes = pCallParams->dwMediaMode;
  2325. // retrieve address type specified
  2326. m_dwAddressType = pCallParams->dwAddressType;
  2327. // see if we support call parameters
  2328. if( pCallParams->dwCallParamFlags != 0 )
  2329. {
  2330. H323DBG(( DEBUG_LEVEL_ERROR,
  2331. "do not support call parameters 0x%08lx.",
  2332. pCallParams->dwCallParamFlags ));
  2333. // do not support param flags
  2334. *pdwStatus = LINEERR_INVALCALLPARAMS;
  2335. // failure
  2336. return FALSE;
  2337. }
  2338. // see if unknown bit is specified
  2339. if( dwMediaModes & LINEMEDIAMODE_UNKNOWN )
  2340. {
  2341. H323DBG(( DEBUG_LEVEL_VERBOSE,
  2342. "clearing unknown media mode." ));
  2343. // clear unknown bit from modes
  2344. dwMediaModes &= ~LINEMEDIAMODE_UNKNOWN;
  2345. }
  2346. // see if both audio bits are specified
  2347. if( (dwMediaModes & LINEMEDIAMODE_AUTOMATEDVOICE) &&
  2348. (dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE) )
  2349. {
  2350. H323DBG(( DEBUG_LEVEL_VERBOSE,
  2351. "clearing automated voice media mode." ));
  2352. // clear extra audio bit from modes
  2353. dwMediaModes &= ~LINEMEDIAMODE_INTERACTIVEVOICE;
  2354. }
  2355. // see if we support media modes specified
  2356. if( dwMediaModes & ~H323_LINE_MEDIAMODES )
  2357. {
  2358. H323DBG(( DEBUG_LEVEL_ERROR,
  2359. "do not support media modes 0x%08lx.",
  2360. pCallParams->dwMediaMode ));
  2361. // do not support media mode
  2362. *pdwStatus = LINEERR_INVALMEDIAMODE;
  2363. // failure
  2364. return FALSE;
  2365. }
  2366. // see if we support bearer modes
  2367. if( pCallParams->dwBearerMode & ~H323_LINE_BEARERMODES )
  2368. {
  2369. H323DBG(( DEBUG_LEVEL_ERROR,
  2370. "do not support bearer mode 0x%08lx.",
  2371. pCallParams->dwBearerMode ));
  2372. // do not support bearer mode
  2373. *pdwStatus = LINEERR_INVALBEARERMODE;
  2374. // failure
  2375. return FALSE;
  2376. }
  2377. // see if we support address modes
  2378. if( pCallParams->dwAddressMode & ~H323_LINE_ADDRESSMODES )
  2379. {
  2380. H323DBG(( DEBUG_LEVEL_ERROR,
  2381. "do not support address mode 0x%08lx.",
  2382. pCallParams->dwAddressMode ));
  2383. // do not support address mode
  2384. *pdwStatus = LINEERR_INVALADDRESSMODE;
  2385. // failure
  2386. return FALSE;
  2387. }
  2388. // validate address id specified
  2389. if (pCallParams->dwAddressID != 0 )
  2390. {
  2391. H323DBG(( DEBUG_LEVEL_ERROR, "address id 0x%08lx invalid.",
  2392. pCallParams->dwAddressID ));
  2393. // invalid address id
  2394. *pdwStatus = LINEERR_INVALADDRESSID;
  2395. // failure
  2396. return FALSE;
  2397. }
  2398. // validate destination address type specified
  2399. if( m_dwAddressType & ~H323_LINE_ADDRESSTYPES )
  2400. {
  2401. H323DBG(( DEBUG_LEVEL_ERROR, "address type 0x%08lx invalid.",
  2402. pCallParams->dwAddressType ));
  2403. // invalid address type
  2404. *pdwStatus = LINEERR_INVALADDRESSTYPE;
  2405. //failure
  2406. return FALSE;
  2407. }
  2408. if( m_dwAddressType == LINEADDRESSTYPE_PHONENUMBER )
  2409. {
  2410. dwAddrSize = ValidateE164Address( pwszDialableAddr, wszAddr );
  2411. //add the callee alias
  2412. if( dwAddrSize==0 )
  2413. {
  2414. H323DBG(( DEBUG_LEVEL_ERROR,
  2415. "invlid e164 callee alias ."));
  2416. return FALSE;
  2417. }
  2418. if( (dwAddrSize > MAX_E164_ADDR_LEN) || (dwAddrSize == 0) )
  2419. return FALSE;
  2420. if(!AddAliasItem( m_pCalleeAliasNames,
  2421. (BYTE*)wszAddr,
  2422. dwAddrSize * sizeof(WCHAR),
  2423. e164_chosen ))
  2424. {
  2425. H323DBG(( DEBUG_LEVEL_ERROR,
  2426. "could not allocate for callee alias ."));
  2427. // invalid destination addr
  2428. *pdwStatus = LINEERR_INVALADDRESS;
  2429. return FALSE;
  2430. }
  2431. H323DBG(( DEBUG_LEVEL_ERROR, "callee alias added:%S.", wszAddr ));
  2432. }
  2433. else
  2434. {
  2435. dwAddrSize = (wcslen(pwszDialableAddr)+1);
  2436. if( (dwAddrSize > MAX_H323_ADDR_LEN) || (dwAddrSize == 0) )
  2437. return FALSE;
  2438. if(!AddAliasItem( m_pCalleeAliasNames,
  2439. (BYTE*)pwszDialableAddr,
  2440. dwAddrSize * sizeof(WCHAR),
  2441. h323_ID_chosen ))
  2442. {
  2443. H323DBG(( DEBUG_LEVEL_ERROR,
  2444. "could not allocate for callee alias ."));
  2445. // invalid destination addr
  2446. *pdwStatus = LINEERR_INVALADDRESS;
  2447. return FALSE;
  2448. }
  2449. H323DBG(( DEBUG_LEVEL_ERROR, "callee alias added:%S.", pwszDialableAddr ));
  2450. }
  2451. // see if callee alias specified
  2452. if( pCallParams->dwCalledPartySize > 0 )
  2453. {
  2454. //avoid duplicate aliases
  2455. dwAddrSize *= sizeof(WCHAR);
  2456. if( ( (m_dwAddressType != LINEADDRESSTYPE_PHONENUMBER) ||
  2457. (memcmp(
  2458. (PVOID)((BYTE*)pCallParams + pCallParams->dwCalledPartyOffset),
  2459. wszAddr,
  2460. pCallParams->dwCalledPartySize ) != 0 )
  2461. ) &&
  2462. ( memcmp(
  2463. (PVOID)((BYTE*)pCallParams + pCallParams->dwCalledPartyOffset),
  2464. pwszDialableAddr,
  2465. pCallParams->dwCalledPartySize ) != 0
  2466. )
  2467. )
  2468. {
  2469. // allocate memory for callee string
  2470. if( !AddAliasItem( m_pCalleeAliasNames,
  2471. (BYTE*)pCallParams + pCallParams->dwCalledPartyOffset,
  2472. pCallParams->dwCalledPartySize,
  2473. (m_dwAddressType != LINEADDRESSTYPE_PHONENUMBER)?
  2474. h323_ID_chosen : e164_chosen) )
  2475. {
  2476. H323DBG(( DEBUG_LEVEL_ERROR,
  2477. "could not allocate caller name." ));
  2478. // invalid address id
  2479. *pdwStatus = LINEERR_NOMEM;
  2480. // failure
  2481. return FALSE;
  2482. }
  2483. H323DBG(( DEBUG_LEVEL_ERROR, "callee alias added:%S.",
  2484. ((BYTE*)pCallParams + pCallParams->dwCalledPartyOffset) ));
  2485. }
  2486. }
  2487. // see if caller name specified
  2488. if( pCallParams->dwCallingPartyIDSize > 0 )
  2489. {
  2490. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  2491. // allocate memory for callee string
  2492. if(!AddAliasItem( m_pCallerAliasNames,
  2493. (BYTE*)pCallParams + pCallParams->dwCallingPartyIDOffset,
  2494. pCallParams->dwCallingPartyIDSize,
  2495. h323_ID_chosen ) )
  2496. {
  2497. H323DBG(( DEBUG_LEVEL_ERROR,
  2498. "could not allocate caller name." ));
  2499. // invalid address id
  2500. *pdwStatus = LINEERR_NOMEM;
  2501. // failure
  2502. return FALSE;
  2503. }
  2504. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  2505. }
  2506. else if( RasIsRegistered() )
  2507. {
  2508. //ARQ message must have a caller alias
  2509. pAliasList = RASGetRegisteredAliasList();
  2510. wszMachineName = pAliasList -> pItems[0].pData;
  2511. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  2512. //set the value for m_pCallerAliasNames
  2513. if( !AddAliasItem( m_pCallerAliasNames,
  2514. (BYTE*)(wszMachineName),
  2515. sizeof(WCHAR) * (wcslen(wszMachineName) + 1 ),
  2516. pAliasList -> pItems[0].wType ) )
  2517. {
  2518. H323DBG(( DEBUG_LEVEL_ERROR,
  2519. "could not allocate caller name." ));
  2520. // invalid address id
  2521. *pdwStatus = LINEERR_NOMEM;
  2522. // failure
  2523. return FALSE;
  2524. }
  2525. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  2526. }
  2527. // check for user user information
  2528. if( pCallParams->dwUserUserInfoSize > 0 )
  2529. {
  2530. // save user user info
  2531. if (AddU2U( U2U_OUTBOUND, pCallParams->dwUserUserInfoSize,
  2532. (LPBYTE)pCallParams + pCallParams->dwUserUserInfoOffset ) == FALSE )
  2533. {
  2534. //no need to free above aloocated memory for m_CalleeAlias and
  2535. //m_CallerAlias
  2536. // invalid address id
  2537. *pdwStatus = LINEERR_NOMEM;
  2538. // failure
  2539. return FALSE;
  2540. }
  2541. }
  2542. // save call data buffer.
  2543. if( SetCallData( (LPBYTE)pCallParams + pCallParams->dwCallDataOffset,
  2544. pCallParams->dwCallDataSize ) == FALSE )
  2545. {
  2546. //no need to free above aloocated memory for m_CalleeAlias and
  2547. //m_CallerAlias
  2548. // invalid address id
  2549. *pdwStatus = LINEERR_NOMEM;
  2550. // failure
  2551. return FALSE;
  2552. }
  2553. // clear incoming modes
  2554. m_dwIncomingModes = 0;
  2555. // outgoing modes will be finalized after H.245 stage
  2556. m_dwOutgoingModes = dwMediaModes | LINEMEDIAMODE_UNKNOWN;
  2557. // save media modes specified
  2558. m_dwRequestedModes = dwMediaModes;
  2559. H323DBG(( DEBUG_LEVEL_TRACE, "ValidateCallParams exited:%p.", this ));
  2560. // success
  2561. return TRUE;
  2562. }
  2563. /*++
  2564. Routine Description:
  2565. Associates call object with the specified conference id.
  2566. Arguments:
  2567. Return Values:
  2568. Returns true if successful.
  2569. --*/
  2570. PH323_CONFERENCE
  2571. CH323Call::CreateConference (
  2572. IN GUID* pConferenceId OPTIONAL)
  2573. {
  2574. int iresult;
  2575. H323DBG(( DEBUG_LEVEL_TRACE, "CreateConference entered:%p.", this ));
  2576. Lock();
  2577. _ASSERTE( m_hdConf == NULL );
  2578. // create conference
  2579. m_hdConf = new H323_CONFERENCE( this );
  2580. // validate
  2581. if ( m_hdConf == NULL )
  2582. {
  2583. H323DBG(( DEBUG_LEVEL_ERROR,
  2584. "could no allocate the conference object."));
  2585. Unlock();
  2586. return NULL;
  2587. }
  2588. if (pConferenceId)
  2589. {
  2590. m_ConferenceID = *pConferenceId;
  2591. }
  2592. else
  2593. {
  2594. iresult = UuidCreate (&m_ConferenceID);
  2595. if ((iresult == RPC_S_OK) || (iresult ==RPC_S_UUID_LOCAL_ONLY))
  2596. {
  2597. H323DBG ((DEBUG_LEVEL_INFO, "generated new conference id (GUID)."));
  2598. }
  2599. else
  2600. {
  2601. H323DBG(( DEBUG_LEVEL_ERROR,
  2602. "failed to generate GUID for conference id: %d.", iresult ));
  2603. ZeroMemory (&m_ConferenceID, sizeof m_ConferenceID);
  2604. }
  2605. }
  2606. Unlock();
  2607. H323DBG(( DEBUG_LEVEL_TRACE, "CreateConference exited:%p.", this ));
  2608. return m_hdConf;
  2609. }
  2610. /*++
  2611. Routine Description:
  2612. Initiates outbound call to specified destination.
  2613. !!always called in a lock
  2614. Arguments:
  2615. none
  2616. Return Values:
  2617. Returns true if successful.
  2618. --*/
  2619. BOOL
  2620. CH323Call::PlaceCall(void)
  2621. {
  2622. H323DBG(( DEBUG_LEVEL_TRACE, "PlaceCall entered:%p.", this ));
  2623. if( m_dwFlags & CALLOBJECT_SHUTDOWN )
  2624. {
  2625. return FALSE;
  2626. }
  2627. // see if user user information specified
  2628. CopyU2UAsNonStandard( U2U_OUTBOUND );
  2629. if( m_pwszDisplay == NULL )
  2630. {
  2631. // see if caller alias specified
  2632. if( m_pCallerAliasNames && m_pCallerAliasNames -> wCount )
  2633. {
  2634. if((m_pCallerAliasNames ->pItems[0].wType == h323_ID_chosen) ||
  2635. (m_pCallerAliasNames ->pItems[0].wType == e164_chosen) )
  2636. {
  2637. // send caller name as display
  2638. m_pwszDisplay = m_pCallerAliasNames -> pItems[0].pData;
  2639. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  2640. }
  2641. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  2642. }
  2643. }
  2644. // validate
  2645. if( !SetupCall() )
  2646. {
  2647. H323DBG(( DEBUG_LEVEL_VERBOSE, "Q931 call: failed." ));
  2648. return FALSE;
  2649. }
  2650. H323DBG(( DEBUG_LEVEL_TRACE, "PlaceCall exited:%p.", this ));
  2651. // return status
  2652. return TRUE;
  2653. }
  2654. void
  2655. CH323Call::DropUserInitiated(
  2656. IN DWORD dwDisconnectMode
  2657. )
  2658. {
  2659. //since this is a user initiated drop, the transfered call should also
  2660. //be dropped for a primary call and vice versa
  2661. if( IsTransferredCall( m_dwCallType ) && m_hdRelatedCall )
  2662. {
  2663. QueueTAPILineRequest(
  2664. TSPI_CLOSE_CALL,
  2665. m_hdRelatedCall,
  2666. NULL,
  2667. dwDisconnectMode,
  2668. m_wCallReference );
  2669. }
  2670. DropCall(dwDisconnectMode);
  2671. }
  2672. //always called in lock
  2673. BOOL
  2674. /*++
  2675. Routine Description:
  2676. Hangs up call (if necessary) and changes state to idle.
  2677. Arguments:
  2678. dwDisconnectMode - Status code for disconnect.
  2679. Return Values:
  2680. Returns true if successful.
  2681. --*/
  2682. CH323Call::DropCall(
  2683. IN DWORD dwDisconnectMode
  2684. )
  2685. {
  2686. PUserToUserLE pU2ULE = NULL;
  2687. if( m_dwFlags & CALLOBJECT_SHUTDOWN )
  2688. {
  2689. return FALSE;
  2690. }
  2691. H323DBG(( DEBUG_LEVEL_TRACE, "DropCall entered:%p.", this ));
  2692. if( (m_dwRASCallState == RASCALL_STATE_REGISTERED ) ||
  2693. (m_dwRASCallState == RASCALL_STATE_ARQSENT ) )
  2694. {
  2695. //disengage from the GK
  2696. SendDRQ( forcedDrop_chosen, NOT_RESEND_SEQ_NUM, TRUE );
  2697. }
  2698. // determine call state
  2699. switch (m_dwCallState)
  2700. {
  2701. case LINECALLSTATE_CONNECTED:
  2702. // hangup call (this will invoke async indication)
  2703. // validate
  2704. //encode ASN.1 and send Q931release message to the peer
  2705. if(!SendQ931Message( NO_INVOKEID,
  2706. 0,
  2707. 0,
  2708. RELEASECOMPLMESSAGETYPE,
  2709. NO_H450_APDU ))
  2710. {
  2711. //post a message to the callback thread to shutdown the H323 call
  2712. H323DBG(( DEBUG_LEVEL_ERROR,
  2713. "error hanging up call 0x%08lx.", this ));
  2714. }
  2715. else
  2716. {
  2717. m_dwStateMachine = Q931_RELEASE_SENT;
  2718. H323DBG(( DEBUG_LEVEL_VERBOSE, "call 0x%08lx hung up.", this ));
  2719. }
  2720. // change call state to disconnected
  2721. ChangeCallState(LINECALLSTATE_DISCONNECTED, dwDisconnectMode);
  2722. break;
  2723. case LINECALLSTATE_OFFERING:
  2724. // see if user user information specified
  2725. CopyU2UAsNonStandard( U2U_OUTBOUND );
  2726. // reject call
  2727. //encode ASN.1 and send Q931Setup message to the peer
  2728. if( SendQ931Message( NO_INVOKEID,
  2729. 0,
  2730. 0,
  2731. RELEASECOMPLMESSAGETYPE,
  2732. NO_H450_APDU ))
  2733. {
  2734. m_dwStateMachine = Q931_RELEASE_SENT;
  2735. H323DBG(( DEBUG_LEVEL_VERBOSE, "call 0x%08lx rejected.", this ));
  2736. }
  2737. else
  2738. {
  2739. H323DBG(( DEBUG_LEVEL_ERROR, "error reject call 0x%08lx.",this));
  2740. }
  2741. // change call state to disconnected
  2742. ChangeCallState(LINECALLSTATE_DISCONNECTED, dwDisconnectMode);
  2743. break;
  2744. case LINECALLSTATE_RINGBACK:
  2745. case LINECALLSTATE_ACCEPTED:
  2746. // cancel outbound call
  2747. if( SendQ931Message( NO_INVOKEID,
  2748. 0,
  2749. 0,
  2750. RELEASECOMPLMESSAGETYPE,
  2751. NO_H450_APDU ))
  2752. {
  2753. H323DBG(( DEBUG_LEVEL_ERROR,
  2754. "error cancelling call 0x%08lx.", this ));
  2755. }
  2756. else
  2757. {
  2758. H323DBG(( DEBUG_LEVEL_ERROR,
  2759. "error reject call 0x%08lx.", this ));
  2760. }
  2761. // change call state to disconnected
  2762. ChangeCallState(LINECALLSTATE_DISCONNECTED, dwDisconnectMode);
  2763. break;
  2764. case LINECALLSTATE_DIALING:
  2765. // change call state to disconnected
  2766. ChangeCallState(LINECALLSTATE_DISCONNECTED, dwDisconnectMode);
  2767. break;
  2768. case LINECALLSTATE_DISCONNECTED:
  2769. //
  2770. // disconnected but still need to clean up
  2771. //
  2772. break;
  2773. case LINECALLSTATE_IDLE:
  2774. //
  2775. // call object already idle
  2776. //
  2777. if( (m_dwCallType == CALLTYPE_NORMAL) &&
  2778. (m_dwStateMachine == Q931_SETUP_RECVD) )
  2779. {
  2780. if( SendQ931Message( NO_INVOKEID,
  2781. 0,
  2782. 0,
  2783. RELEASECOMPLMESSAGETYPE,
  2784. NO_H450_APDU ))
  2785. {
  2786. H323DBG(( DEBUG_LEVEL_ERROR,
  2787. "error cancelling call 0x%08lx.", this ));
  2788. }
  2789. else
  2790. {
  2791. H323DBG(( DEBUG_LEVEL_ERROR,
  2792. "error reject call 0x%08lx.", this ));
  2793. }
  2794. }
  2795. DropSupplementaryServicesCalls();
  2796. return TRUE;
  2797. }
  2798. if( ( (m_dwCallType & CALLTYPE_TRANSFEREDDEST) && m_hdRelatedCall ) ||
  2799. ( (m_dwCallType & CALLTYPE_TRANSFEREDSRC ) && m_hdRelatedCall ) )
  2800. {
  2801. m_dwCallState = LINECALLSTATE_IDLE;
  2802. }
  2803. else
  2804. {
  2805. // Tell the MSP to stop streaming.
  2806. SendMSPMessage( SP_MSG_CallShutdown, 0, 0, NULL );
  2807. // change call state to idle
  2808. ChangeCallState( LINECALLSTATE_IDLE, 0 );
  2809. }
  2810. if( (m_dwCallType & CALLTYPE_TRANSFEREDSRC ) && m_hdRelatedCall )
  2811. {
  2812. //drop the primary call
  2813. if( !QueueTAPILineRequest(
  2814. TSPI_CLOSE_CALL,
  2815. m_hdRelatedCall,
  2816. NULL,
  2817. LINEDISCONNECTMODE_NORMAL,
  2818. NULL ) )
  2819. {
  2820. H323DBG((DEBUG_LEVEL_ERROR, "could not post H323 close event"));
  2821. }
  2822. }
  2823. H323DBG(( DEBUG_LEVEL_TRACE, "DropCall exited:%p.", this ));
  2824. // success
  2825. return TRUE;
  2826. }
  2827. void
  2828. CH323Call::DropSupplementaryServicesCalls()
  2829. {
  2830. if( (m_dwCallType & CALLTYPE_FORWARDCONSULT) ||
  2831. (m_dwCallType & CALLTYPE_DIVERTED_SERVED) ||
  2832. (m_dwCallType & CALLTYPE_DIVERTEDSRC) ||
  2833. (m_dwCallType & CALLTYPE_DIVERTEDSRC_NOROUTING) )
  2834. {
  2835. if( m_dwQ931Flags & Q931_CALL_CONNECTED )
  2836. {
  2837. if( SendQ931Message( NO_INVOKEID,
  2838. 0,
  2839. 0,
  2840. RELEASECOMPLMESSAGETYPE,
  2841. NO_H450_APDU ))
  2842. {
  2843. m_dwStateMachine = Q931_RELEASE_SENT;
  2844. H323DBG(( DEBUG_LEVEL_VERBOSE, "call 0x%08lx rejected.", this ));
  2845. }
  2846. }
  2847. g_pH323Line->m_fForwardConsultInProgress = FALSE;
  2848. }
  2849. if( (m_dwCallType & CALLTYPE_FORWARDCONSULT) &&
  2850. (m_dwOrigin == LINECALLORIGIN_OUTBOUND ) )
  2851. {
  2852. //inform the user about failure of line forward operation
  2853. if( m_dwCallDiversionState != H4503_CHECKRESTRICTION_SUCC )
  2854. {
  2855. (*g_pfnLineEventProc)(
  2856. g_pH323Line->m_htLine,
  2857. (HTAPICALL)NULL,
  2858. (DWORD)LINE_ADDRESSSTATE,
  2859. (DWORD)LINEADDRESSSTATE_FORWARD,
  2860. (DWORD)LINEADDRESSSTATE_FORWARD,
  2861. (DWORD)0
  2862. );
  2863. }
  2864. }
  2865. if( m_dwCallType & CALLTYPE_DIVERTEDSRC )
  2866. {
  2867. ChangeCallState( LINECALLSTATE_IDLE, 0 );
  2868. }
  2869. }
  2870. //!!always called in a lock
  2871. BOOL
  2872. CH323Call::HandleConnectMessage(
  2873. IN Q931_CONNECT_ASN *pConnectASN
  2874. )
  2875. {
  2876. PH323_CALL pPrimaryCall = NULL;
  2877. H323DBG(( DEBUG_LEVEL_TRACE, "HandleConnectMessage entered:%p.", this ));
  2878. if( pConnectASN->fNonStandardDataPresent )
  2879. {
  2880. //add user user info
  2881. if( AddU2UNoAlloc( U2U_INBOUND,
  2882. pConnectASN->nonStandardData.sData.wOctetStringLength,
  2883. pConnectASN->nonStandardData.sData.pOctetString ) == TRUE )
  2884. {
  2885. H323DBG(( DEBUG_LEVEL_VERBOSE,
  2886. "user user info available in CONNECT PDU." ));
  2887. if( !(m_dwCallType & CALLTYPE_TRANSFEREDSRC) )
  2888. {
  2889. // signal incoming
  2890. PostLineEvent (
  2891. LINE_CALLINFO,
  2892. LINECALLINFOSTATE_USERUSERINFO, 0, 0 );
  2893. }
  2894. //don't release the data buffer
  2895. pConnectASN->fNonStandardDataPresent = FALSE;
  2896. }
  2897. else
  2898. {
  2899. H323DBG(( DEBUG_LEVEL_WARNING,
  2900. "could not save incoming user user info." ));
  2901. //memory failure : shutdown the H323 call
  2902. CloseCall( 0 );
  2903. goto cleanup;
  2904. }
  2905. }
  2906. //get the vendor info
  2907. if( pConnectASN->EndpointType.pVendorInfo )
  2908. {
  2909. FreeVendorInfo( &m_peerVendorInfo );
  2910. m_peerVendorInfo = pConnectASN->VendorInfo;
  2911. pConnectASN->EndpointType.pVendorInfo = NULL;
  2912. }
  2913. if( pConnectASN->h245AddrPresent )
  2914. {
  2915. m_peerH245Addr = pConnectASN->h245Addr;
  2916. }
  2917. //copy the fast start proposal
  2918. if( pConnectASN->fFastStartPresent &&
  2919. (m_dwFastStart!=FAST_START_NOTAVAIL) )
  2920. {
  2921. if( m_pPeerFastStart )
  2922. {
  2923. //we had received fast start params in previous proceeding
  2924. //or alerting message
  2925. FreeFastStart( m_pPeerFastStart );
  2926. }
  2927. m_pPeerFastStart = pConnectASN->pFastStart;
  2928. m_dwFastStart = FAST_START_AVAIL;
  2929. //we are keeping a reference to the fast start list so don't release it
  2930. pConnectASN->pFastStart = NULL;
  2931. }
  2932. else
  2933. {
  2934. m_dwFastStart = FAST_START_NOTAVAIL;
  2935. }
  2936. if( ( (m_dwCallType & CALLTYPE_TRANSFEREDSRC)||
  2937. (m_dwCallType & CALLTYPE_DIVERTEDTRANSFERED) ) && m_hdRelatedCall )
  2938. {
  2939. QueueSuppServiceWorkItem( SWAP_REPLACEMENT_CALL,
  2940. m_hdCall, (ULONG_PTR)m_hdRelatedCall );
  2941. }
  2942. else
  2943. {
  2944. //start H245
  2945. SendMSPStartH245( NULL, NULL );
  2946. SendMSPMessage( SP_MSG_ConnectComplete, 0, 0, NULL );
  2947. }
  2948. //If we join MCU we get the conference ID of the conference we
  2949. //joined and not the one that we sent in Setup message.
  2950. if( IsEqualConferenceID( &pConnectASN->ConferenceID ) == FALSE )
  2951. {
  2952. H323DBG ((DEBUG_LEVEL_ERROR,
  2953. "OnReceiveConnect: We received different conference id." ));
  2954. m_ConferenceID = pConnectASN->ConferenceID;
  2955. }
  2956. //tell TAPI about state change
  2957. ChangeCallState( LINECALLSTATE_CONNECTED, 0 );
  2958. FreeConnectASN( pConnectASN );
  2959. H323DBG(( DEBUG_LEVEL_TRACE, "HandleConnectMessage exited:%p.", this ));
  2960. return TRUE;
  2961. cleanup:
  2962. FreeConnectASN( pConnectASN );
  2963. return FALSE;
  2964. }
  2965. //!!always called in a lock
  2966. void
  2967. CH323Call::HandleAlertingMessage(
  2968. IN Q931_ALERTING_ASN * pAlertingASN
  2969. )
  2970. {
  2971. H323DBG(( DEBUG_LEVEL_TRACE, "HandleAlertingMessage entered:%p.", this ));
  2972. if( pAlertingASN->fNonStandardDataPresent )
  2973. {
  2974. // add user user info
  2975. if( AddU2UNoAlloc( U2U_INBOUND,
  2976. pAlertingASN->nonStandardData.sData.wOctetStringLength,
  2977. pAlertingASN->nonStandardData.sData.pOctetString ) == TRUE )
  2978. {
  2979. H323DBG(( DEBUG_LEVEL_VERBOSE,
  2980. "user user info available in ALERT PDU." ));
  2981. // signal incoming
  2982. if( !(m_dwCallType & CALLTYPE_TRANSFEREDSRC) )
  2983. {
  2984. PostLineEvent (
  2985. LINE_CALLINFO,
  2986. LINECALLINFOSTATE_USERUSERINFO, 0, 0 );
  2987. }
  2988. //don't release the data buffer
  2989. pAlertingASN->fNonStandardDataPresent = FALSE;
  2990. }
  2991. else
  2992. {
  2993. H323DBG(( DEBUG_LEVEL_WARNING,
  2994. "could not save incoming user user info." ));
  2995. //memory failure : shutdown the H323 call
  2996. CloseCall( 0 );
  2997. return;
  2998. }
  2999. }
  3000. if( pAlertingASN->fH245AddrPresent )
  3001. {
  3002. m_peerH245Addr = pAlertingASN->h245Addr;
  3003. }
  3004. if( pAlertingASN->fFastStartPresent &&
  3005. (m_dwFastStart!=FAST_START_NOTAVAIL) )
  3006. {
  3007. if( m_pPeerFastStart )
  3008. {
  3009. //we had received fast start params in previous proceeding
  3010. //or alerting message
  3011. FreeFastStart( m_pPeerFastStart );
  3012. }
  3013. m_pPeerFastStart = pAlertingASN->pFastStart;
  3014. m_dwFastStart = FAST_START_AVAIL;
  3015. //we are keeping a reference to the fast start list so don't release it
  3016. pAlertingASN->pFastStart = NULL;
  3017. pAlertingASN->fFastStartPresent = FALSE;
  3018. }
  3019. //for DIVERTEDSRC, call its ok to tell TAPI about this state
  3020. ChangeCallState( LINECALLSTATE_RINGBACK, 0 );
  3021. /*if( pAlertingASN->fH245AddrPresent && !(m_dwFlags & H245_START_MSG_SENT) )
  3022. {
  3023. //start early H245
  3024. SendMSPStartH245( NULL, NULL);
  3025. }*/
  3026. FreeAlertingASN( pAlertingASN );
  3027. H323DBG(( DEBUG_LEVEL_TRACE, "HandleAlertingMessage exited:%p.", this ));
  3028. return;
  3029. }
  3030. //!!must be always called in a lock
  3031. BOOL
  3032. CH323Call::HandleSetupMessage(
  3033. IN Q931MESSAGE* pMessage
  3034. )
  3035. {
  3036. PH323_ALIASITEM pwszDivertedToAlias = NULL;
  3037. WCHAR * pwszAliasName = NULL;
  3038. WORD wAliasLength = 0;
  3039. H323DBG(( DEBUG_LEVEL_TRACE, "HandleSetupMessage entered:%p.", this ));
  3040. if( m_pCallerAliasNames && (m_pCallerAliasNames -> wCount > 0) )
  3041. {
  3042. pwszAliasName = m_pCallerAliasNames->pItems[0].pData;
  3043. wAliasLength = (m_pCallerAliasNames->pItems[0].wDataLength+1)
  3044. * sizeof(WCHAR);
  3045. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  3046. }
  3047. pwszDivertedToAlias = g_pH323Line->CallToBeDiverted(
  3048. pwszAliasName,
  3049. wAliasLength,
  3050. LINEFORWARDMODE_UNCOND | LINEFORWARDMODE_UNCONDSPECIFIC );
  3051. if( pwszDivertedToAlias )
  3052. {
  3053. if( !InitiateCallDiversion( pwszDivertedToAlias, DiversionReason_cfu ) )
  3054. {
  3055. return FALSE;
  3056. }
  3057. return TRUE;
  3058. }
  3059. //send the proceeding message to the peer if not already sent by the GK
  3060. //SendProceeding();
  3061. if(RasIsRegistered())
  3062. {
  3063. if( !SendARQ( NOT_RESEND_SEQ_NUM ) )
  3064. {
  3065. return FALSE;
  3066. }
  3067. //copy the data to be sent in preparetoanswer message
  3068. if( m_prepareToAnswerMsgData.pbBuffer )
  3069. delete m_prepareToAnswerMsgData.pbBuffer;
  3070. ZeroMemory( (PVOID)&m_prepareToAnswerMsgData, sizeof(BUFFERDESCR) );
  3071. m_prepareToAnswerMsgData.pbBuffer =
  3072. (BYTE*)new char[pMessage->UserToUser.wUserInfoLen];
  3073. if( m_prepareToAnswerMsgData.pbBuffer == NULL )
  3074. {
  3075. return FALSE;
  3076. }
  3077. CopyMemory( (PVOID)m_prepareToAnswerMsgData.pbBuffer,
  3078. (PVOID)pMessage->UserToUser.pbUserInfo,
  3079. pMessage->UserToUser.wUserInfoLen );
  3080. m_prepareToAnswerMsgData.dwLength = pMessage->UserToUser.wUserInfoLen;
  3081. }
  3082. else
  3083. {
  3084. if( (m_dwCallType & CALLTYPE_TRANSFEREDDEST) && m_hdRelatedCall )
  3085. {
  3086. MSPMessageData* pMSPMessageData = new MSPMessageData;
  3087. if( pMSPMessageData == NULL )
  3088. {
  3089. return FALSE;
  3090. }
  3091. pMSPMessageData->hdCall = m_hdRelatedCall;
  3092. pMSPMessageData->messageType = SP_MSG_PrepareToAnswer;
  3093. pMSPMessageData->pbEncodedBuf =
  3094. new BYTE[pMessage->UserToUser.wUserInfoLen];
  3095. if( pMSPMessageData->pbEncodedBuf == NULL )
  3096. {
  3097. delete pMSPMessageData;
  3098. return FALSE;
  3099. }
  3100. CopyMemory( pMSPMessageData->pbEncodedBuf,
  3101. (PVOID)pMessage->UserToUser.pbUserInfo,
  3102. pMessage->UserToUser.wUserInfoLen );
  3103. pMSPMessageData->wLength = pMessage->UserToUser.wUserInfoLen;
  3104. pMSPMessageData->hReplacementCall = m_hdCall;
  3105. if( !QueueUserWorkItem( SendMSPMessageOnRelatedCall,
  3106. pMSPMessageData, WT_EXECUTEDEFAULT ) )
  3107. {
  3108. delete pMSPMessageData->pbEncodedBuf;
  3109. delete pMSPMessageData;
  3110. return FALSE;
  3111. }
  3112. }
  3113. else
  3114. {
  3115. // signal incoming call
  3116. _ASSERTE(!m_htCall);
  3117. PostLineEvent (
  3118. LINE_NEWCALL,
  3119. (DWORD_PTR)m_hdCall,
  3120. (DWORD_PTR)&m_htCall, 0);
  3121. _ASSERTE( m_htCall );
  3122. if( m_htCall == NULL )
  3123. return FALSE;
  3124. if( IsListEmpty(&m_IncomingU2U) == FALSE )
  3125. {
  3126. // signal incoming
  3127. PostLineEvent (
  3128. LINE_CALLINFO,
  3129. LINECALLINFOSTATE_USERUSERINFO, 0, 0);
  3130. }
  3131. ChangeCallState( LINECALLSTATE_OFFERING, 0 );
  3132. //Send the new call message to the unspecified MSP
  3133. SendMSPMessage( SP_MSG_PrepareToAnswer,
  3134. pMessage->UserToUser.pbUserInfo,
  3135. pMessage->UserToUser.wUserInfoLen, NULL );
  3136. }
  3137. }
  3138. H323DBG(( DEBUG_LEVEL_TRACE, "HandleSetupMessage exited:%p.", this ));
  3139. return TRUE;
  3140. }
  3141. BOOL
  3142. CH323Call::HandleCallDiversionFacility(
  3143. PH323_ADDR pAlternateAddress )
  3144. {
  3145. PSTR pszAlias;
  3146. WCHAR pwszAliasName[H323_MAXDESTNAMELEN];
  3147. in_addr addr;
  3148. if( m_pCallReroutingInfo == NULL )
  3149. {
  3150. m_pCallReroutingInfo = new CALLREROUTINGINFO;
  3151. if( m_pCallReroutingInfo == NULL )
  3152. {
  3153. return FALSE;
  3154. }
  3155. ZeroMemory( (PVOID)m_pCallReroutingInfo, sizeof(CALLREROUTINGINFO) );
  3156. }
  3157. m_pCallReroutingInfo->diversionCounter = 1;
  3158. m_pCallReroutingInfo->diversionReason = DiversionReason_cfu;
  3159. //free any previous divertedTo alias
  3160. if( m_pCallReroutingInfo->divertedToNrAlias )
  3161. {
  3162. FreeAliasNames( m_pCallReroutingInfo->divertedToNrAlias );
  3163. m_pCallReroutingInfo->divertedToNrAlias = NULL;
  3164. }
  3165. addr.S_un.S_addr = htonl( pAlternateAddress->Addr.IP_Binary.dwAddr );
  3166. pszAlias = inet_ntoa( addr );
  3167. if( pszAlias == NULL )
  3168. return FALSE;
  3169. m_pCallReroutingInfo->divertedToNrAlias = new H323_ALIASNAMES;
  3170. if( m_pCallReroutingInfo->divertedToNrAlias == NULL )
  3171. {
  3172. return FALSE;
  3173. }
  3174. ZeroMemory( m_pCallReroutingInfo->divertedToNrAlias,
  3175. sizeof(H323_ALIASNAMES) );
  3176. MultiByteToWideChar(
  3177. GetACP(),
  3178. MB_PRECOMPOSED,
  3179. pszAlias,
  3180. strlen(pszAlias)+1,
  3181. pwszAliasName,
  3182. H323_MAXDESTNAMELEN
  3183. );
  3184. if( !AddAliasItem( m_pCallReroutingInfo->divertedToNrAlias,
  3185. pwszAliasName, h323_ID_chosen ) )
  3186. {
  3187. delete m_pCallReroutingInfo->divertedToNrAlias;
  3188. m_pCallReroutingInfo->divertedToNrAlias = NULL;
  3189. return FALSE;
  3190. }
  3191. m_CalleeAddr = *pAlternateAddress;
  3192. if( m_pCalleeAliasNames && m_pCalleeAliasNames->wCount )
  3193. {
  3194. m_pCallReroutingInfo->divertingNrAlias = new H323_ALIASNAMES;
  3195. if( m_pCallReroutingInfo->divertingNrAlias != NULL )
  3196. {
  3197. ZeroMemory( (PVOID)m_pCallReroutingInfo->divertingNrAlias,
  3198. sizeof(H323_ALIASNAMES) );
  3199. if( !AddAliasItem( m_pCallReroutingInfo->divertingNrAlias,
  3200. m_pCalleeAliasNames->pItems[0].pData,
  3201. m_pCalleeAliasNames->pItems[0].wType ) )
  3202. {
  3203. delete m_pCallReroutingInfo->divertingNrAlias;
  3204. m_pCallReroutingInfo->divertingNrAlias = NULL;
  3205. }
  3206. }
  3207. }
  3208. m_dwCallType |= CALLTYPE_DIVERTEDSRC;
  3209. m_dwCallDiversionState = H4503_CALLREROUTING_RECVD;
  3210. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCallDiversionFacility exited:%p.",
  3211. this ));
  3212. return TRUE;
  3213. }
  3214. BOOL
  3215. CH323Call::HandleCallDiversionFacility(
  3216. PH323_ALIASNAMES pAliasList )
  3217. {
  3218. if( !m_pCallReroutingInfo )
  3219. {
  3220. m_pCallReroutingInfo = new CALLREROUTINGINFO;
  3221. if( m_pCallReroutingInfo == NULL )
  3222. {
  3223. return FALSE;
  3224. }
  3225. ZeroMemory( (PVOID)m_pCallReroutingInfo, sizeof(CALLREROUTINGINFO) );
  3226. }
  3227. m_pCallReroutingInfo->diversionCounter = 1;
  3228. m_pCallReroutingInfo->diversionReason = DiversionReason_cfu;
  3229. if( m_pCallReroutingInfo->divertedToNrAlias )
  3230. {
  3231. FreeAliasNames( m_pCallReroutingInfo->divertedToNrAlias );
  3232. m_pCallReroutingInfo->divertedToNrAlias = NULL;
  3233. }
  3234. m_pCallReroutingInfo->divertedToNrAlias = pAliasList;
  3235. if( m_pCalleeAliasNames && m_pCalleeAliasNames->wCount )
  3236. {
  3237. m_pCallReroutingInfo->divertingNrAlias = new H323_ALIASNAMES;
  3238. if( m_pCallReroutingInfo->divertingNrAlias != NULL )
  3239. {
  3240. ZeroMemory( (PVOID)m_pCallReroutingInfo->divertingNrAlias,
  3241. sizeof(H323_ALIASNAMES) );
  3242. if( !AddAliasItem( m_pCallReroutingInfo->divertingNrAlias,
  3243. m_pCalleeAliasNames->pItems[0].pData,
  3244. m_pCalleeAliasNames->pItems[0].wType ) )
  3245. {
  3246. delete m_pCallReroutingInfo->divertingNrAlias;
  3247. m_pCallReroutingInfo->divertingNrAlias = NULL;
  3248. }
  3249. }
  3250. }
  3251. m_dwCallType |= CALLTYPE_DIVERTEDSRC;
  3252. m_dwCallDiversionState = H4503_CALLREROUTING_RECVD;
  3253. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCallDiversionFacility exited:%p.",
  3254. this ));
  3255. return TRUE;
  3256. }
  3257. BOOL
  3258. CH323Call::HandleTransferFacility(
  3259. PH323_ALIASNAMES pAliasList )
  3260. {
  3261. H323DBG(( DEBUG_LEVEL_TRACE, "HandleTransferFacility entered:%p.", this ));
  3262. //argument.callIdentity
  3263. ZeroMemory( (PVOID)m_pCTCallIdentity, sizeof(m_pCTCallIdentity) );
  3264. //argument.reroutingNumber
  3265. FreeAliasNames( m_pTransferedToAlias );
  3266. m_pTransferedToAlias = pAliasList;
  3267. m_dwCallType |= CALLTYPE_TRANSFERED_PRIMARY;
  3268. m_dwCallDiversionState = H4502_CTINITIATE_RECV;
  3269. //queue an event for creating a new call
  3270. if( !QueueSuppServiceWorkItem( TSPI_DIAL_TRNASFEREDCALL, m_hdCall,
  3271. (ULONG_PTR)m_pTransferedToAlias ))
  3272. {
  3273. H323DBG(( DEBUG_LEVEL_TRACE, "could not post dial transfer event." ));
  3274. }
  3275. H323DBG(( DEBUG_LEVEL_TRACE, "HandleTransferFacility entered:%p.", this ));
  3276. return TRUE;
  3277. }
  3278. BOOL
  3279. CH323Call::HandleTransferFacility(
  3280. PH323_ADDR pAlternateAddress )
  3281. {
  3282. PSTR pszAlias;
  3283. WCHAR pwszAliasName[H323_MAXDESTNAMELEN];
  3284. in_addr addr;
  3285. H323DBG(( DEBUG_LEVEL_TRACE, "HandleTransferFacility entered:%p.", this ));
  3286. //argument.callIdentity
  3287. ZeroMemory( (PVOID)m_pCTCallIdentity, sizeof(m_pCTCallIdentity) );
  3288. //argument.reroutingNumber
  3289. //free any previous divertedTo alias
  3290. FreeAliasNames( m_pTransferedToAlias );
  3291. addr.S_un.S_addr = htonl( pAlternateAddress->Addr.IP_Binary.dwAddr );
  3292. pszAlias = inet_ntoa( addr );
  3293. if( pszAlias == NULL )
  3294. {
  3295. return FALSE;
  3296. }
  3297. m_pTransferedToAlias = new H323_ALIASNAMES;
  3298. if( m_pTransferedToAlias == NULL )
  3299. {
  3300. return FALSE;
  3301. }
  3302. ZeroMemory( m_pTransferedToAlias, sizeof(H323_ALIASNAMES) );
  3303. MultiByteToWideChar(
  3304. GetACP(),
  3305. MB_PRECOMPOSED,
  3306. pszAlias,
  3307. strlen(pszAlias)+1,
  3308. pwszAliasName,
  3309. H323_MAXDESTNAMELEN
  3310. );
  3311. if( !AddAliasItem( m_pTransferedToAlias, pwszAliasName, h323_ID_chosen ) )
  3312. {
  3313. delete m_pTransferedToAlias;
  3314. m_pTransferedToAlias = NULL;
  3315. return FALSE;
  3316. }
  3317. m_CalleeAddr = *pAlternateAddress;
  3318. m_dwCallType |= CALLTYPE_TRANSFERED_PRIMARY;
  3319. m_dwCallDiversionState = H4502_CTINITIATE_RECV;
  3320. //queue an event for creating a new call
  3321. if( !QueueSuppServiceWorkItem( TSPI_DIAL_TRNASFEREDCALL, m_hdCall,
  3322. (ULONG_PTR)m_pTransferedToAlias ))
  3323. {
  3324. H323DBG(( DEBUG_LEVEL_TRACE, "could not post dial transfer event." ));
  3325. }
  3326. H323DBG(( DEBUG_LEVEL_TRACE, "HandleTransferFacility entered:%p.", this ));
  3327. return TRUE;
  3328. }
  3329. //!!always called in a lock
  3330. void
  3331. CH323Call::HandleFacilityMessage(
  3332. IN DWORD dwInvokeID,
  3333. IN Q931_FACILITY_ASN * pFacilityASN
  3334. )
  3335. {
  3336. H323DBG(( DEBUG_LEVEL_TRACE, "HandleFacilityMessage entered:%p.", this ));
  3337. if( pFacilityASN->fNonStandardDataPresent )
  3338. {
  3339. // add user user info
  3340. if( AddU2UNoAlloc( U2U_INBOUND,
  3341. pFacilityASN->nonStandardData.sData.wOctetStringLength,
  3342. pFacilityASN->nonStandardData.sData.pOctetString ) == TRUE )
  3343. {
  3344. H323DBG(( DEBUG_LEVEL_VERBOSE,
  3345. "user user info available in ALERT PDU." ));
  3346. // signal incoming
  3347. if( !(m_dwCallType & CALLTYPE_TRANSFEREDSRC) )
  3348. {
  3349. PostLineEvent (
  3350. LINE_CALLINFO,
  3351. LINECALLINFOSTATE_USERUSERINFO, 0, 0);
  3352. }
  3353. //don't release the data buffer
  3354. pFacilityASN->fNonStandardDataPresent = FALSE;
  3355. }
  3356. else
  3357. {
  3358. H323DBG(( DEBUG_LEVEL_WARNING,
  3359. "could not save incoming user user info." ));
  3360. //memory failure : shutdown the H323 call
  3361. CloseCall( 0 );
  3362. return;
  3363. }
  3364. }
  3365. if( (pFacilityASN->bReason == callForwarded_chosen) ||
  3366. (pFacilityASN->bReason == FacilityReason_routeCallToGatekeeper_chosen) ||
  3367. (pFacilityASN->bReason == routeCallToMC_chosen) )
  3368. {
  3369. if( pFacilityASN->pAlternativeAliasList != NULL )
  3370. {
  3371. if( m_dwCallState == LINECALLSTATE_CONNECTED )
  3372. {
  3373. HandleTransferFacility( pFacilityASN->pAlternativeAliasList );
  3374. //don't free the alias list
  3375. pFacilityASN->pAlternativeAliasList = NULL;
  3376. }
  3377. else if( m_dwCallState != LINECALLSTATE_DISCONNECTED )
  3378. {
  3379. //redirect the call if not yet connected
  3380. if( HandleCallDiversionFacility(
  3381. pFacilityASN->pAlternativeAliasList ) )
  3382. {
  3383. OnCallReroutingReceive( NO_INVOKEID );
  3384. //don't free the alias list
  3385. pFacilityASN->pAlternativeAliasList = NULL;
  3386. }
  3387. }
  3388. }
  3389. else if( pFacilityASN->fAlternativeAddressPresent )
  3390. {
  3391. if( m_dwCallState == LINECALLSTATE_CONNECTED )
  3392. {
  3393. HandleTransferFacility( &pFacilityASN->AlternativeAddr );
  3394. }
  3395. else if( m_dwCallState != LINECALLSTATE_DISCONNECTED )
  3396. {
  3397. //redirect the call if not yet connected
  3398. if( HandleCallDiversionFacility( &pFacilityASN->AlternativeAddr ) )
  3399. {
  3400. OnCallReroutingReceive( NO_INVOKEID );
  3401. }
  3402. }
  3403. }
  3404. }
  3405. //Handle H.450 APDU
  3406. if( pFacilityASN->dwH450APDUType == DIVERTINGLEGINFO1_OPCODE )
  3407. {
  3408. if( m_dwOrigin != LINECALLORIGIN_OUTBOUND )
  3409. {
  3410. return;
  3411. }
  3412. if( m_pCallReroutingInfo && m_pCallReroutingInfo->fPresentAllow )
  3413. {
  3414. PostLineEvent (
  3415. LINE_CALLINFO,
  3416. LINECALLINFOSTATE_REDIRECTINGID, 0, 0);
  3417. }
  3418. }
  3419. else if( pFacilityASN->dwH450APDUType == CALLREROUTING_OPCODE )
  3420. {
  3421. OnCallReroutingReceive( dwInvokeID );
  3422. }
  3423. else if( pFacilityASN->dwH450APDUType == REMOTEHOLD_OPCODE )
  3424. {
  3425. if( m_fRemoteHoldInitiated )
  3426. {
  3427. //Hold();
  3428. m_fRemoteHoldInitiated = FALSE;
  3429. }
  3430. }
  3431. else if( pFacilityASN->dwH450APDUType == REMOTERETRIEVE_OPCODE )
  3432. {
  3433. if( m_fRemoteRetrieveInitiated )
  3434. {
  3435. //UnHold();
  3436. m_fRemoteRetrieveInitiated = FALSE;
  3437. }
  3438. }
  3439. else if( pFacilityASN->fH245AddrPresent )
  3440. {
  3441. m_peerH245Addr = pFacilityASN->h245Addr;
  3442. H323DBG(( DEBUG_LEVEL_TRACE, "H245 address received in facility." ));
  3443. //If Q931 call already connected then send another StartH245.
  3444. if( m_dwCallState == LINECALLSTATE_CONNECTED )
  3445. {
  3446. SendMSPStartH245( NULL, NULL );
  3447. }
  3448. }
  3449. H323DBG(( DEBUG_LEVEL_TRACE, "HandleFacilityMessage exited:%p.", this ));
  3450. return;
  3451. }
  3452. void
  3453. CH323Call::SetNewCallInfo(
  3454. HANDLE hConnWait,
  3455. HANDLE hWSAEvent,
  3456. DWORD dwState
  3457. )
  3458. {
  3459. H323DBG(( DEBUG_LEVEL_TRACE, "SetNewCallInfo entered." ));
  3460. Lock();
  3461. m_hTransportWait = hConnWait;
  3462. m_hTransport = hWSAEvent;
  3463. SetQ931CallState( dwState );
  3464. Unlock();
  3465. H323DBG(( DEBUG_LEVEL_TRACE, "SetNewCallInfo exited." ));
  3466. }
  3467. //!!no need to call in a lock
  3468. void
  3469. CH323Call::SetQ931CallState( DWORD dwState )
  3470. {
  3471. H323DBG(( DEBUG_LEVEL_TRACE, "SetQ931CallState entered." ));
  3472. //turn off the current state
  3473. m_dwQ931Flags &= ~(Q931_CALL_CONNECTING |
  3474. Q931_CALL_CONNECTED |
  3475. Q931_CALL_DISCONNECTED );
  3476. //set the new state
  3477. m_dwQ931Flags |= dwState;
  3478. H323DBG(( DEBUG_LEVEL_TRACE, "SetQ931CallState exited." ));
  3479. }
  3480. void
  3481. CH323Call::DialCall()
  3482. {
  3483. H323DBG(( DEBUG_LEVEL_TRACE, "DialCall entered:%p.", this ));
  3484. Lock();
  3485. ChangeCallState( LINECALLSTATE_DIALING, 0);
  3486. if( RasIsRegistered() )
  3487. {
  3488. if( !SendARQ( NOT_RESEND_SEQ_NUM ) )
  3489. {
  3490. //If a forward consult call then enable theforwarding anyway.
  3491. if( (m_dwCallType & CALLTYPE_FORWARDCONSULT )&&
  3492. (m_dwOrigin == LINECALLORIGIN_OUTBOUND ) )
  3493. {
  3494. //Success of forwarding
  3495. EnableCallForwarding();
  3496. }
  3497. CloseCall( 0 );
  3498. }
  3499. }
  3500. else
  3501. {
  3502. if( !PlaceCall() )
  3503. {
  3504. //If a forward consult call then enable theforwarding anyway.
  3505. if( (m_dwCallType & CALLTYPE_FORWARDCONSULT )&&
  3506. (m_dwOrigin == LINECALLORIGIN_OUTBOUND ) )
  3507. {
  3508. //Success of forwarding
  3509. EnableCallForwarding();
  3510. }
  3511. CloseCall( LINEDISCONNECTMODE_UNREACHABLE );
  3512. }
  3513. }
  3514. Unlock();
  3515. H323DBG(( DEBUG_LEVEL_TRACE, "DialCall exited:%p.", this ));
  3516. }
  3517. //!!always called in a lock
  3518. void
  3519. CH323Call::MakeCall()
  3520. {
  3521. H323DBG(( DEBUG_LEVEL_TRACE, "MakeCall entered:%p.", this ));
  3522. ChangeCallState( LINECALLSTATE_DIALING, 0 );
  3523. // resolve dialable into local and remote address
  3524. if( !RasIsRegistered() &&
  3525. !ResolveAddress( GetDialableAddress() ) )
  3526. {
  3527. CloseCall( LINEDISCONNECTMODE_BADADDRESS );
  3528. }
  3529. else
  3530. {
  3531. if( RasIsRegistered() )
  3532. {
  3533. if( !SendARQ( NOT_RESEND_SEQ_NUM ) )
  3534. {
  3535. //If a forward consult call then enable theforwarding anyway.
  3536. if( (m_dwCallType & CALLTYPE_FORWARDCONSULT )&&
  3537. (m_dwOrigin == LINECALLORIGIN_OUTBOUND ) )
  3538. {
  3539. //Success of forwarding
  3540. EnableCallForwarding();
  3541. }
  3542. CloseCall( 0 );
  3543. }
  3544. }
  3545. else
  3546. {
  3547. if( !PlaceCall() )
  3548. {
  3549. //If a forward consult call then enable theforwarding anyway.
  3550. if( (m_dwCallType & CALLTYPE_FORWARDCONSULT )&&
  3551. (m_dwOrigin == LINECALLORIGIN_OUTBOUND ) )
  3552. {
  3553. //Success of forwarding
  3554. EnableCallForwarding();
  3555. }
  3556. CloseCall( LINEDISCONNECTMODE_UNREACHABLE );
  3557. }
  3558. }
  3559. }
  3560. H323DBG(( DEBUG_LEVEL_TRACE, "MakeCall exited:%p.", this ));
  3561. }
  3562. //!!always called in a lock
  3563. void
  3564. CH323Call::HandleProceedingMessage(
  3565. IN Q931_ALERTING_ASN * pProceedingASN
  3566. )
  3567. {
  3568. H323DBG(( DEBUG_LEVEL_TRACE, "HandleProceedingMessage entered:%p.", this ));
  3569. if( pProceedingASN->fNonStandardDataPresent )
  3570. {
  3571. // add user user info
  3572. if( AddU2UNoAlloc( U2U_INBOUND,
  3573. pProceedingASN->nonStandardData.sData.wOctetStringLength,
  3574. pProceedingASN->nonStandardData.sData.pOctetString ) == TRUE )
  3575. {
  3576. H323DBG(( DEBUG_LEVEL_VERBOSE,
  3577. "user user info available in ALERT PDU." ));
  3578. // signal incoming
  3579. if( !(m_dwCallType & CALLTYPE_TRANSFEREDSRC) )
  3580. {
  3581. PostLineEvent (
  3582. LINE_CALLINFO,
  3583. LINECALLINFOSTATE_USERUSERINFO, 0, 0);
  3584. }
  3585. //don't release the data buffer
  3586. pProceedingASN->fNonStandardDataPresent = FALSE;
  3587. }
  3588. else
  3589. {
  3590. H323DBG(( DEBUG_LEVEL_WARNING,
  3591. "could not save incoming user user info." ));
  3592. //memory failure : shutdown the H323 call
  3593. CloseCall( 0 );
  3594. return;
  3595. }
  3596. }
  3597. if( pProceedingASN->fH245AddrPresent )
  3598. {
  3599. m_peerH245Addr = pProceedingASN->h245Addr;
  3600. }
  3601. if( pProceedingASN->fFastStartPresent &&
  3602. (m_dwFastStart!=FAST_START_NOTAVAIL) )
  3603. {
  3604. if( m_pPeerFastStart )
  3605. {
  3606. //we had received fast start params in previous proceeding
  3607. //or alerting message
  3608. FreeFastStart( m_pPeerFastStart );
  3609. }
  3610. m_pPeerFastStart = pProceedingASN->pFastStart;
  3611. m_dwFastStart = FAST_START_AVAIL;
  3612. //we are keeping a reference to the fast start list so don't release it
  3613. pProceedingASN->pFastStart = NULL;
  3614. pProceedingASN->fFastStartPresent = FALSE;
  3615. }
  3616. /*
  3617. if( pProceedingASN->fH245AddrPresent && !(m_dwFlags & H245_START_MSG_SENT) )
  3618. {
  3619. //start early H245
  3620. SendMSPStartH245( NULL, NULL );
  3621. }*/
  3622. FreeProceedingASN( pProceedingASN );
  3623. H323DBG(( DEBUG_LEVEL_TRACE, "HandleProceedingMessage exited:%p.", this ));
  3624. return;
  3625. }
  3626. //!!always called in a lock
  3627. BOOL
  3628. CH323Call::HandleReleaseMessage(
  3629. IN Q931_RELEASE_COMPLETE_ASN *pReleaseASN
  3630. )
  3631. {
  3632. DWORD dwDisconnectMode = LINEDISCONNECTMODE_NORMAL;
  3633. H323DBG(( DEBUG_LEVEL_TRACE, "HandleReleaseMessage entered:%p.", this ));
  3634. if( (m_dwCallType & CALLTYPE_TRANSFERED_PRIMARY) &&
  3635. (m_hdRelatedCall != NULL) )
  3636. {
  3637. return QueueSuppServiceWorkItem( DROP_PRIMARY_CALL,
  3638. m_hdRelatedCall, (ULONG_PTR)m_hdCall );
  3639. }
  3640. //change the state to disconnected before callong drop call.
  3641. //This will ensure that release message is not sent to the peer
  3642. ChangeCallState( LINECALLSTATE_DISCONNECTED, 0 );
  3643. //release non standard data
  3644. if( pReleaseASN->fNonStandardDataPresent )
  3645. {
  3646. delete pReleaseASN->nonStandardData.sData.pOctetString;
  3647. pReleaseASN->nonStandardData.sData.pOctetString = NULL;
  3648. }
  3649. //Should we drop the primary call if the transfered call in rejected?
  3650. if( (m_dwCallType == CALLTYPE_TRANSFEREDSRC) && m_hdRelatedCall )
  3651. {
  3652. if( !QueueTAPILineRequest(
  3653. TSPI_CLOSE_CALL,
  3654. m_hdRelatedCall,
  3655. NULL,
  3656. LINEDISCONNECTMODE_NORMAL,
  3657. NULL ) )
  3658. {
  3659. H323DBG((DEBUG_LEVEL_ERROR, "could not post H323 close event"));
  3660. }
  3661. }
  3662. //close call
  3663. if( m_dwCallState != LINECALLSTATE_CONNECTED )
  3664. {
  3665. dwDisconnectMode = LINEDISCONNECTMODE_REJECT;
  3666. }
  3667. CloseCall( dwDisconnectMode );
  3668. H323DBG(( DEBUG_LEVEL_TRACE, "HandleReleaseMessage exited:%p.", this ));
  3669. return TRUE;
  3670. }
  3671. //never call in lock
  3672. BOOL
  3673. CH323Call::InitializeIncomingCall(
  3674. IN Q931_SETUP_ASN* pSetupASN,
  3675. IN DWORD dwCallType,
  3676. IN WORD wCallRef
  3677. )
  3678. {
  3679. PH323_CONFERENCE pConf;
  3680. WCHAR* wszMachineName;
  3681. H323DBG((DEBUG_LEVEL_TRACE, "InitializeIncomingCall entered:%p.",this));
  3682. //bind outgoing call
  3683. pConf = CreateConference( &(pSetupASN->ConferenceID) );
  3684. if( pConf == NULL )
  3685. {
  3686. H323DBG(( DEBUG_LEVEL_ERROR, "could not create conference." ));
  3687. goto cleanup;
  3688. }
  3689. if( !g_pH323Line -> GetH323ConfTable() -> Add( pConf ) )
  3690. {
  3691. H323DBG(( DEBUG_LEVEL_ERROR,
  3692. "could not add conf to conf table." ));
  3693. // failure
  3694. goto cleanup;
  3695. }
  3696. // save caller transport address
  3697. if( !GetPeerAddress(&m_CallerAddr) )
  3698. {
  3699. goto cleanup;
  3700. }
  3701. if( !GetHostAddress(&m_CalleeAddr) )
  3702. {
  3703. goto cleanup;
  3704. }
  3705. //get endpoint info
  3706. m_peerEndPointType = pSetupASN->EndpointType;
  3707. //get the vendor info
  3708. if( pSetupASN->EndpointType.pVendorInfo )
  3709. {
  3710. m_peerVendorInfo = pSetupASN->VendorInfo;
  3711. //we have copied the vendor info pointers. So dont release
  3712. //the pointers in the ASN's vendor info struct
  3713. pSetupASN->EndpointType.pVendorInfo = NULL;
  3714. }
  3715. if( pSetupASN -> fCallIdentifierPresent )
  3716. {
  3717. m_callIdentifier = pSetupASN->callIdentifier;
  3718. }
  3719. else
  3720. {
  3721. int iresult = UuidCreate( &m_callIdentifier );
  3722. if( (iresult != RPC_S_OK) && (iresult !=RPC_S_UUID_LOCAL_ONLY) )
  3723. {
  3724. goto cleanup;
  3725. }
  3726. }
  3727. _ASSERTE( !m_pPeerFastStart );
  3728. if( pSetupASN->fFastStartPresent &&
  3729. (m_dwFastStart!=FAST_START_NOTAVAIL) )
  3730. {
  3731. m_pPeerFastStart = pSetupASN->pFastStart;
  3732. m_dwFastStart = FAST_START_PEER_AVAIL;
  3733. //we are keeping a reference to the fast start list so don't release it
  3734. pSetupASN->pFastStart = NULL;
  3735. pSetupASN->fFastStartPresent = FALSE;
  3736. }
  3737. else
  3738. {
  3739. m_dwFastStart = FAST_START_NOTAVAIL;
  3740. }
  3741. //get the alias names
  3742. if( pSetupASN->pCalleeAliasList )
  3743. {
  3744. _ASSERTE( m_pCalleeAliasNames );
  3745. delete m_pCalleeAliasNames;
  3746. m_pCalleeAliasNames = pSetupASN->pCalleeAliasList;
  3747. pSetupASN->pCalleeAliasList = NULL;
  3748. }
  3749. else
  3750. {
  3751. if( RasIsRegistered() )
  3752. {
  3753. PH323_ALIASNAMES pAliasList = RASGetRegisteredAliasList();
  3754. AddAliasItem( m_pCalleeAliasNames,
  3755. pAliasList->pItems[0].pData,
  3756. pAliasList->pItems[0].wType );
  3757. }
  3758. else
  3759. {
  3760. wszMachineName = g_pH323Line->GetMachineName();
  3761. //set the value for m_pCalleeAliasNames
  3762. AddAliasItem( m_pCalleeAliasNames,
  3763. (BYTE*)(wszMachineName),
  3764. sizeof(WCHAR) * (wcslen(wszMachineName) + 1 ),
  3765. h323_ID_chosen );
  3766. }
  3767. }
  3768. _ASSERTE( m_pCallerAliasNames );
  3769. delete m_pCallerAliasNames;
  3770. m_pCallerAliasNames = NULL;
  3771. if( pSetupASN->pCallerAliasList )
  3772. {
  3773. m_pCallerAliasNames = pSetupASN->pCallerAliasList;
  3774. pSetupASN->pCallerAliasList = NULL;
  3775. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  3776. }
  3777. if( pSetupASN->pExtraAliasList )
  3778. {
  3779. m_pPeerExtraAliasNames = pSetupASN->pExtraAliasList;
  3780. pSetupASN->pExtraAliasList = NULL;
  3781. }
  3782. //non -standard info
  3783. if( pSetupASN->fNonStandardDataPresent )
  3784. {
  3785. // add user user info
  3786. if( AddU2UNoAlloc( U2U_INBOUND,
  3787. pSetupASN->nonStandardData.sData.wOctetStringLength,
  3788. pSetupASN->nonStandardData.sData.pOctetString ) == TRUE )
  3789. {
  3790. H323DBG(( DEBUG_LEVEL_VERBOSE,
  3791. "user user info available in Setup PDU." ));
  3792. //don't release the data buffer
  3793. pSetupASN->fNonStandardDataPresent = FALSE;
  3794. }
  3795. else
  3796. {
  3797. H323DBG(( DEBUG_LEVEL_WARNING,
  3798. "could not save incoming user user info." ));
  3799. goto cleanup;
  3800. }
  3801. }
  3802. if( pSetupASN->fSourceAddrPresent )
  3803. {
  3804. m_CallerAddr = pSetupASN->sourceAddr;
  3805. }
  3806. m_dwCallType = dwCallType;
  3807. if( wCallRef )
  3808. {
  3809. m_wQ931CallRef = (wCallRef | 0x8000);
  3810. }
  3811. //clear incoming modes
  3812. m_dwIncomingModes = 0;
  3813. //outgoing modes will be finalized during H.245 phase
  3814. m_dwOutgoingModes = g_pH323Line->GetMediaModes() | LINEMEDIAMODE_UNKNOWN;
  3815. //save media modes specified
  3816. m_dwRequestedModes = g_pH323Line->GetMediaModes();
  3817. H323DBG(( DEBUG_LEVEL_TRACE, "InitializeIncomingCall exited:%p.", this ));
  3818. return TRUE;
  3819. cleanup:
  3820. return FALSE;
  3821. }
  3822. //!!always called in a lock
  3823. BOOL
  3824. CH323Call::ChangeCallState(
  3825. IN DWORD dwCallState,
  3826. IN DWORD dwCallStateMode
  3827. )
  3828. /*++
  3829. Routine Description:
  3830. Reports call state of specified call object.
  3831. Arguments:
  3832. dwCallState - Specifies new state of call object.
  3833. dwCallStateMode - Specifies new state mode of call object.
  3834. Return Values:
  3835. Returns true if successful.
  3836. --*/
  3837. {
  3838. H323DBG(( DEBUG_LEVEL_VERBOSE, "call 0x%08lx %s. state mode: 0x%08lx.",
  3839. this, H323CallStateToString(dwCallState), dwCallStateMode ));
  3840. // save new call state
  3841. m_dwCallState = dwCallState;
  3842. m_dwCallStateMode = dwCallStateMode;
  3843. if(
  3844. ((m_dwCallType & CALLTYPE_TRANSFEREDDEST) && m_hdRelatedCall ) ||
  3845. ((m_dwCallType & CALLTYPE_TRANSFEREDSRC ) && m_hdRelatedCall ) ||
  3846. (m_dwCallType & CALLTYPE_FORWARDCONSULT )
  3847. )
  3848. {
  3849. return TRUE;
  3850. }
  3851. // report call status
  3852. PostLineEvent (
  3853. LINE_CALLSTATE,
  3854. m_dwCallState,
  3855. m_dwCallStateMode,
  3856. m_dwIncomingModes | m_dwOutgoingModes);
  3857. // success
  3858. return TRUE;
  3859. }
  3860. //always called in a lock
  3861. void
  3862. CH323Call::CopyU2UAsNonStandard(
  3863. IN DWORD dwDirection
  3864. )
  3865. {
  3866. PUserToUserLE pU2ULE = NULL;
  3867. H323DBG(( DEBUG_LEVEL_TRACE, "CopyU2UAsNonStandard entered:%p.", this ));
  3868. if( RemoveU2U( dwDirection, &pU2ULE ) )
  3869. {
  3870. // transfer header information
  3871. m_NonStandardData.bCountryCode = H221_COUNTRY_CODE_USA;
  3872. m_NonStandardData.bExtension = H221_COUNTRY_EXT_USA;
  3873. m_NonStandardData.wManufacturerCode = H221_MFG_CODE_MICROSOFT;
  3874. // initialize octet string containing data
  3875. m_NonStandardData.sData.wOctetStringLength = LOWORD(pU2ULE->dwU2USize);
  3876. if( m_NonStandardData.sData.pOctetString )
  3877. {
  3878. delete m_NonStandardData.sData.pOctetString;
  3879. m_NonStandardData.sData.pOctetString = NULL;
  3880. }
  3881. //We are assigning here part of the structure and then may be the structure is deleted or not??
  3882. m_NonStandardData.sData.pOctetString = pU2ULE->pU2U;
  3883. delete pU2ULE;
  3884. }
  3885. else
  3886. {
  3887. //reset non standard data
  3888. memset( (PVOID)&m_NonStandardData,0,sizeof(H323NonStandardData ));
  3889. }
  3890. H323DBG(( DEBUG_LEVEL_TRACE, "CopyU2UAsNonStandard exited:%p.", this ));
  3891. }
  3892. void
  3893. CH323Call::AcceptCall(void)
  3894. /*++
  3895. Routine Description:
  3896. Accepts incoming call.
  3897. !!always called in lock
  3898. Arguments:
  3899. Return Values:
  3900. Returns true if successful.
  3901. --*/
  3902. {
  3903. PH323_CALL pCall = NULL;
  3904. H323DBG(( DEBUG_LEVEL_TRACE, "AcceptCall entered:%p.", this ));
  3905. if( m_dwFlags & CALLOBJECT_SHUTDOWN )
  3906. {
  3907. return;
  3908. }
  3909. // see if user user information specified
  3910. CopyU2UAsNonStandard( U2U_OUTBOUND );
  3911. if( m_pwszDisplay == NULL )
  3912. {
  3913. // see if callee alias specified
  3914. if( m_pCalleeAliasNames && m_pCalleeAliasNames -> wCount )
  3915. {
  3916. if((m_pCalleeAliasNames->pItems[0].wType == h323_ID_chosen) ||
  3917. (m_pCalleeAliasNames ->pItems[0].wType == e164_chosen) )
  3918. {
  3919. // send callee name as display
  3920. m_pwszDisplay = m_pCalleeAliasNames -> pItems[0].pData;
  3921. }
  3922. }
  3923. }
  3924. //send answer call message to the MSP instance
  3925. if( (m_dwCallType & CALLTYPE_TRANSFEREDDEST) && m_hdRelatedCall )
  3926. {
  3927. MSPMessageData* pMSPMessageData = new MSPMessageData;
  3928. if( pMSPMessageData == NULL )
  3929. {
  3930. CloseCall( 0 );
  3931. return;
  3932. }
  3933. pMSPMessageData->hdCall = m_hdRelatedCall;
  3934. pMSPMessageData->messageType = SP_MSG_AnswerCall;
  3935. pMSPMessageData->pbEncodedBuf = NULL;
  3936. pMSPMessageData->wLength = 0;
  3937. pMSPMessageData->hReplacementCall = m_hdCall;
  3938. if( !QueueUserWorkItem( SendMSPMessageOnRelatedCall, pMSPMessageData,
  3939. WT_EXECUTEDEFAULT ) )
  3940. {
  3941. delete pMSPMessageData;
  3942. CloseCall( 0 );
  3943. return;
  3944. }
  3945. }
  3946. else
  3947. {
  3948. SendMSPMessage( SP_MSG_AnswerCall, 0, 0, NULL );
  3949. }
  3950. m_fCallAccepted = TRUE;
  3951. if( m_fReadyToAnswer )
  3952. {
  3953. // validate status
  3954. if( !AcceptH323Call() )
  3955. {
  3956. H323DBG(( DEBUG_LEVEL_ERROR, "error answering call 0x%08lx.",
  3957. this ));
  3958. // drop call using disconnect mode
  3959. DropCall( LINEDISCONNECTMODE_TEMPFAILURE );
  3960. // failure
  3961. return;
  3962. }
  3963. if( !(m_dwFlags & H245_START_MSG_SENT) )
  3964. {
  3965. //start H245
  3966. SendMSPStartH245( NULL, NULL );
  3967. }
  3968. //tell MSP about connect state
  3969. SendMSPMessage( SP_MSG_ConnectComplete, 0, 0, NULL );
  3970. //change call state to accepted from offering
  3971. ChangeCallState( LINECALLSTATE_CONNECTED, 0 );
  3972. }
  3973. H323DBG(( DEBUG_LEVEL_TRACE, "AcceptCall exited:%p.", this ));
  3974. // success
  3975. return;
  3976. }
  3977. //always called in lock
  3978. void
  3979. CH323Call::ReleaseU2U(void)
  3980. {
  3981. PUserToUserLE pU2ULE = NULL;
  3982. PLIST_ENTRY pLE;
  3983. H323DBG(( DEBUG_LEVEL_TRACE, "ReleaseU2U entered:%p.", this ));
  3984. if( m_dwFlags & CALLOBJECT_SHUTDOWN )
  3985. {
  3986. return;
  3987. }
  3988. // see if list is empty
  3989. if( IsListEmpty( &m_IncomingU2U ) == FALSE )
  3990. {
  3991. // remove first entry from list
  3992. pLE = RemoveHeadList( &m_IncomingU2U );
  3993. // convert to user user structure
  3994. pU2ULE = CONTAINING_RECORD(pLE, UserToUserLE, Link);
  3995. // release memory
  3996. if(pU2ULE)
  3997. {
  3998. delete pU2ULE;
  3999. pU2ULE = NULL;
  4000. }
  4001. }
  4002. // see if list contains pending data
  4003. if( IsListEmpty( &m_IncomingU2U ) == FALSE )
  4004. {
  4005. H323DBG(( DEBUG_LEVEL_VERBOSE,
  4006. "more user user info available." ));
  4007. // signal incoming
  4008. PostLineEvent (
  4009. LINE_CALLINFO,
  4010. LINECALLINFOSTATE_USERUSERINFO, 0, 0);
  4011. }
  4012. H323DBG(( DEBUG_LEVEL_TRACE, "ReleaseU2U exited:%p.", this ));
  4013. }
  4014. //always called in lock
  4015. void
  4016. CH323Call::SendU2U(
  4017. IN BYTE* pUserUserInfo,
  4018. IN DWORD dwSize
  4019. )
  4020. {
  4021. H323DBG(( DEBUG_LEVEL_TRACE, "SendU2U entered:%p.", this ));
  4022. if( m_dwFlags & CALLOBJECT_SHUTDOWN )
  4023. {
  4024. return;
  4025. }
  4026. // check for user user info
  4027. if( pUserUserInfo != NULL )
  4028. {
  4029. // transfer header information
  4030. m_NonStandardData.bCountryCode = H221_COUNTRY_CODE_USA;
  4031. m_NonStandardData.bExtension = H221_COUNTRY_EXT_USA;
  4032. m_NonStandardData.wManufacturerCode = H221_MFG_CODE_MICROSOFT;
  4033. // initialize octet string containing data
  4034. m_NonStandardData.sData.wOctetStringLength = (WORD)dwSize;
  4035. if( m_NonStandardData.sData.pOctetString != NULL )
  4036. {
  4037. delete m_NonStandardData.sData.pOctetString;
  4038. m_NonStandardData.sData.pOctetString = NULL;
  4039. }
  4040. m_NonStandardData.sData.pOctetString = pUserUserInfo;
  4041. }
  4042. // send user user data
  4043. if( !SendQ931Message( 0, 0, 0, FACILITYMESSAGETYPE, NO_H450_APDU ) )
  4044. {
  4045. H323DBG(( DEBUG_LEVEL_ERROR,
  4046. "error sending non-standard message."));
  4047. }
  4048. H323DBG(( DEBUG_LEVEL_TRACE, "SendU2U exited:%p.", this ));
  4049. return;
  4050. }
  4051. BOOL
  4052. CH323Call::InitializeQ931(
  4053. IN SOCKET callSocket
  4054. )
  4055. {
  4056. BOOL fSuccess;
  4057. H323DBG((DEBUG_LEVEL_ERROR, "q931 call initialize entered:%p.", this ));
  4058. if( !BindIoCompletionCallback(
  4059. (HANDLE)callSocket,
  4060. CH323Call::IoCompletionCallback,
  4061. 0) )
  4062. {
  4063. H323DBG(( DEBUG_LEVEL_ERROR,
  4064. "couldn't bind i/o completion callabck:%d:%p.",
  4065. GetLastError(), this ));
  4066. return FALSE;
  4067. }
  4068. //initilize the member variables
  4069. m_callSocket = callSocket;
  4070. H323DBG((DEBUG_LEVEL_ERROR, "q931 call initialize exited:%lx, %p.",
  4071. m_callSocket, this ));
  4072. return TRUE;
  4073. }
  4074. //no need to lock
  4075. BOOL
  4076. CH323Call::GetPeerAddress(
  4077. IN H323_ADDR *pAddr
  4078. )
  4079. {
  4080. SOCKADDR_IN sockaddr;
  4081. int len = sizeof(sockaddr);
  4082. H323DBG((DEBUG_LEVEL_ERROR, "GetPeerAddress entered:%p.", this ));
  4083. if( getpeername( m_callSocket, (SOCKADDR*)&sockaddr, &len)
  4084. == SOCKET_ERROR )
  4085. {
  4086. H323DBG(( DEBUG_LEVEL_ERROR,
  4087. "error 0x%08lx calling getpeername.", WSAGetLastError() ));
  4088. return FALSE;
  4089. }
  4090. pAddr->nAddrType = H323_IP_BINARY;
  4091. pAddr->bMulticast = FALSE;
  4092. pAddr->Addr.IP_Binary.wPort = ntohs(sockaddr.sin_port);
  4093. pAddr->Addr.IP_Binary.dwAddr = ntohl(sockaddr.sin_addr.S_un.S_addr);
  4094. H323DBG(( DEBUG_LEVEL_ERROR, "GetPeerAddress exited:%p.", this ));
  4095. return TRUE;
  4096. }
  4097. //no need to lock
  4098. BOOL CH323Call::GetHostAddress(
  4099. IN H323_ADDR *pAddr
  4100. )
  4101. {
  4102. int len = sizeof(m_LocalAddr);
  4103. H323DBG((DEBUG_LEVEL_ERROR, "GetHostAddress entered:%p.", this ));
  4104. if( getsockname( m_callSocket, (SOCKADDR *)&m_LocalAddr, &len) ==
  4105. SOCKET_ERROR)
  4106. {
  4107. H323DBG(( DEBUG_LEVEL_ERROR,
  4108. "error 0x%08lx calling getockname.", WSAGetLastError() ));
  4109. return FALSE;
  4110. }
  4111. pAddr->nAddrType = H323_IP_BINARY;
  4112. pAddr->bMulticast = FALSE;
  4113. pAddr->Addr.IP_Binary.wPort = ntohs(m_LocalAddr.sin_port);
  4114. pAddr->Addr.IP_Binary.dwAddr = ntohl(m_LocalAddr.sin_addr.S_un.S_addr);
  4115. H323DBG((DEBUG_LEVEL_ERROR, "GetHostAddress exited:%p.", this ));
  4116. return TRUE;
  4117. }
  4118. //!!always called in a lock
  4119. BOOL
  4120. CH323Call::OnReceiveFacility(
  4121. IN Q931MESSAGE* pMessage
  4122. )
  4123. {
  4124. Q931_FACILITY_ASN facilityASN;
  4125. H323DBG((DEBUG_LEVEL_TRACE, "OnReceiveFacility entered: %p.", this ));
  4126. //decode the U2U information
  4127. if( !pMessage ->UserToUser.fPresent ||
  4128. pMessage ->UserToUser.wUserInfoLen == 0 )
  4129. {
  4130. //Ignore this message. Don't shutdown the call.
  4131. return FALSE;
  4132. }
  4133. if( !ParseFacilityASN( pMessage->UserToUser.pbUserInfo,
  4134. pMessage->UserToUser.wUserInfoLen, &facilityASN ))
  4135. {
  4136. //memory failure : shutdown the H323 call
  4137. CloseCall( 0 );
  4138. return FALSE;
  4139. }
  4140. if( (facilityASN.pH245PDU.length != 0) && facilityASN.pH245PDU.value )
  4141. {
  4142. SendMSPMessage( SP_MSG_H245PDU, facilityASN.pH245PDU.value,
  4143. facilityASN.pH245PDU.length, NULL );
  4144. delete facilityASN.pH245PDU.value;
  4145. }
  4146. HandleFacilityMessage( facilityASN.dwInvokeID, &facilityASN );
  4147. H323DBG((DEBUG_LEVEL_TRACE, "OnReceiveFacility exited: %p.", this ));
  4148. return TRUE;
  4149. }
  4150. //!!always called in a lock
  4151. BOOL
  4152. CH323Call::OnReceiveProceeding(
  4153. IN Q931MESSAGE* pMessage
  4154. )
  4155. {
  4156. Q931_CALL_PROCEEDING_ASN proceedingASN;
  4157. DWORD dwAPDUType = 0;
  4158. H323DBG((DEBUG_LEVEL_TRACE, "OnReceiveProceeding entered: %p.", this ));
  4159. //decode the U2U information
  4160. if( (pMessage ->UserToUser.fPresent == FALSE) ||
  4161. (pMessage ->UserToUser.wUserInfoLen == 0) )
  4162. {
  4163. //ignore this message. don't shutdown the call.
  4164. return FALSE;
  4165. }
  4166. if( (m_dwOrigin!=LINECALLORIGIN_OUTBOUND) ||
  4167. ( (m_dwStateMachine != Q931_SETUP_SENT) &&
  4168. (m_dwStateMachine != Q931_PROCEED_RECVD) )
  4169. )
  4170. {
  4171. //ignore this message. don't shutdown the Q931 call.
  4172. return FALSE;
  4173. }
  4174. if( !ParseProceedingASN(
  4175. pMessage->UserToUser.pbUserInfo,
  4176. pMessage->UserToUser.wUserInfoLen,
  4177. &proceedingASN,
  4178. &dwAPDUType ))
  4179. {
  4180. //Ignore the wrong proceeding message.
  4181. H323DBG(( DEBUG_LEVEL_ERROR, "wrong proceeding PDU:%p.", this ));
  4182. H323DUMPBUFFER( pMessage->UserToUser.pbUserInfo,
  4183. (DWORD)pMessage->UserToUser.wUserInfoLen );
  4184. return TRUE;
  4185. }
  4186. if( (m_dwCallType & CALLTYPE_FORWARDCONSULT )&&
  4187. (m_dwOrigin == LINECALLORIGIN_OUTBOUND ) )
  4188. {
  4189. //success of forwarding
  4190. EnableCallForwarding();
  4191. CloseCall( 0 );
  4192. return TRUE;
  4193. }
  4194. HandleProceedingMessage( &proceedingASN );
  4195. //reset the timeout for setup sent
  4196. if( m_hSetupSentTimer != NULL )
  4197. {
  4198. DeleteTimerQueueTimer( H323TimerQueue, m_hSetupSentTimer, NULL );
  4199. m_hSetupSentTimer = NULL;
  4200. }
  4201. H323DBG((DEBUG_LEVEL_TRACE, "OnReceiveProceeding exited: %p.", this ));
  4202. m_dwStateMachine = Q931_PROCEED_RECVD;
  4203. return TRUE;
  4204. }
  4205. //!!always called in a lock
  4206. BOOL
  4207. CH323Call::OnReceiveAlerting(
  4208. IN Q931MESSAGE* pMessage
  4209. )
  4210. {
  4211. Q931_ALERTING_ASN alertingASN;
  4212. DWORD dwAPDUType = 0;
  4213. H323DBG((DEBUG_LEVEL_TRACE, "OnReceiveAlerting entered: %p.", this ));
  4214. //decode the U2U information
  4215. if( (pMessage ->UserToUser.fPresent == FALSE) ||
  4216. (pMessage ->UserToUser.wUserInfoLen == 0) )
  4217. {
  4218. //ignore this message. don't shutdown the call.
  4219. return FALSE;
  4220. }
  4221. if( (m_dwOrigin!=LINECALLORIGIN_OUTBOUND) ||
  4222. !( (m_dwStateMachine==Q931_SETUP_SENT) ||
  4223. (m_dwStateMachine==Q931_PROCEED_RECVD)
  4224. )
  4225. )
  4226. {
  4227. //ignore this message. don't shutdown the Q931 call.
  4228. return FALSE;
  4229. }
  4230. if( !ParseAlertingASN( pMessage->UserToUser.pbUserInfo,
  4231. pMessage->UserToUser.wUserInfoLen,
  4232. &alertingASN,
  4233. &dwAPDUType ))
  4234. {
  4235. //memory failure : shutdown the H323 call
  4236. CloseCall( 0 );
  4237. return FALSE;
  4238. }
  4239. if( (m_dwCallType & CALLTYPE_FORWARDCONSULT )&&
  4240. (m_dwOrigin == LINECALLORIGIN_OUTBOUND ) )
  4241. {
  4242. //success of forwarding
  4243. EnableCallForwarding();
  4244. CloseCall( 0 );
  4245. return FALSE;
  4246. }
  4247. //reset the timeout for setup sent
  4248. if( m_hSetupSentTimer != NULL )
  4249. {
  4250. DeleteTimerQueueTimer( H323TimerQueue, m_hSetupSentTimer, NULL );
  4251. m_hSetupSentTimer = NULL;
  4252. }
  4253. if( !CreateTimerQueueTimer(
  4254. &m_hCallEstablishmentTimer,
  4255. H323TimerQueue,
  4256. CH323Call::CallEstablishmentExpiredCallback,
  4257. (PVOID)m_hdCall,
  4258. g_RegistrySettings.dwQ931AlertingTimeout, 0,
  4259. WT_EXECUTEINIOTHREAD | WT_EXECUTEONLYONCE ))
  4260. {
  4261. CloseCall( 0 );
  4262. return FALSE;
  4263. }
  4264. HandleAlertingMessage( &alertingASN );
  4265. m_dwStateMachine = Q931_ALERT_RECVD;
  4266. H323DBG((DEBUG_LEVEL_TRACE, "OnReceiveAlerting exited: %p.", this ));
  4267. return TRUE;
  4268. }
  4269. //!!always called in lock
  4270. void
  4271. CH323Call::SetupSentTimerExpired(void)
  4272. {
  4273. DWORD dwState;
  4274. H323DBG((DEBUG_LEVEL_TRACE, "SetupSentTimerExpired entered."));
  4275. dwState = m_dwStateMachine;
  4276. if( m_hSetupSentTimer != NULL )
  4277. {
  4278. DeleteTimerQueueTimer( H323TimerQueue, m_hSetupSentTimer, NULL );
  4279. m_hSetupSentTimer = NULL;
  4280. }
  4281. if( (dwState!= Q931_CONNECT_RECVD) &&
  4282. (dwState != Q931_ALERT_RECVD) &&
  4283. (dwState != Q931_PROCEED_RECVD) &&
  4284. (dwState != Q931_RELEASE_RECVD)
  4285. )
  4286. {
  4287. //time out has occured
  4288. CloseCall( 0 );
  4289. }
  4290. H323DBG((DEBUG_LEVEL_TRACE, "SetupSentTimerExpired exited." ));
  4291. }
  4292. //!!always called in a lock
  4293. BOOL
  4294. CH323Call::OnReceiveRelease(
  4295. IN Q931MESSAGE* pMessage
  4296. )
  4297. {
  4298. DWORD dwAPDUType = 0;
  4299. Q931_RELEASE_COMPLETE_ASN releaseASN;
  4300. //decode the U2U information
  4301. if( (pMessage ->UserToUser.fPresent == FALSE) ||
  4302. (pMessage ->UserToUser.wUserInfoLen == 0) )
  4303. {
  4304. H323DBG(( DEBUG_LEVEL_ERROR, "ReleaseComplete PDU did not contain "
  4305. "user-to-user information, ignoring message." ));
  4306. //ignore this message. don't shutdown the call.
  4307. return FALSE;
  4308. }
  4309. if( !ParseReleaseCompleteASN(
  4310. pMessage->UserToUser.pbUserInfo,
  4311. pMessage->UserToUser.wUserInfoLen,
  4312. &releaseASN,
  4313. &dwAPDUType ))
  4314. {
  4315. H323DBG(( DEBUG_LEVEL_ERROR,
  4316. "ReleaseComplete PDU could not be parsed, terminating call." ));
  4317. //memory failure : shutdown the H323 call
  4318. CloseCall( 0 );
  4319. return FALSE;
  4320. }
  4321. H323DBG ((DEBUG_LEVEL_INFO, "Received ReleaseComplete PDU."));
  4322. HandleReleaseMessage( &releaseASN );
  4323. m_dwStateMachine = Q931_RELEASE_RECVD;
  4324. return TRUE;
  4325. }
  4326. //!!always called in a lock
  4327. BOOL
  4328. CH323Call::OnReceiveConnect(
  4329. IN Q931MESSAGE* pMessage
  4330. )
  4331. {
  4332. Q931_CONNECT_ASN connectASN;
  4333. DWORD dwH450APDUType = 0;
  4334. H323DBG((DEBUG_LEVEL_TRACE, "OnReceiveConnect entered: %p.", this ));
  4335. //decode the U2U information
  4336. if( (pMessage ->UserToUser.fPresent == FALSE) ||
  4337. (pMessage ->UserToUser.wUserInfoLen == 0) )
  4338. {
  4339. //ignore this message. don't shutdown the call.
  4340. return FALSE;
  4341. }
  4342. if( m_dwOrigin!=LINECALLORIGIN_OUTBOUND )
  4343. {
  4344. //ignore this message. don't shutdown the Q931 call.
  4345. return FALSE;
  4346. }
  4347. if( (m_dwStateMachine != Q931_SETUP_SENT) &&
  4348. (m_dwStateMachine != Q931_ALERT_RECVD) &&
  4349. (m_dwStateMachine != Q931_PROCEED_RECVD)
  4350. )
  4351. {
  4352. //ignore this message. don't shutdown the Q931 call.
  4353. return FALSE;
  4354. }
  4355. if( ParseConnectASN( pMessage->UserToUser.pbUserInfo,
  4356. pMessage->UserToUser.wUserInfoLen,
  4357. &connectASN,
  4358. &dwH450APDUType) == FALSE )
  4359. {
  4360. //memory failure : shutdown the H323 call
  4361. CloseCall( 0 );
  4362. return FALSE;
  4363. }
  4364. if( m_dwCallType & CALLTYPE_FORWARDCONSULT )
  4365. {
  4366. FreeConnectASN( &connectASN );
  4367. if( dwH450APDUType == H4503_DUMMYTYPERETURNRESULT_APDU)
  4368. {
  4369. //assuming this return result is for check restriction operation
  4370. return TRUE;
  4371. }
  4372. else
  4373. {
  4374. //success of forwarding
  4375. EnableCallForwarding();
  4376. CloseCall( 0 );
  4377. return FALSE;
  4378. }
  4379. }
  4380. if( !HandleConnectMessage( &connectASN ) )
  4381. {
  4382. return FALSE;
  4383. }
  4384. //reset the timeout for setup sent
  4385. if( m_hSetupSentTimer != NULL )
  4386. {
  4387. DeleteTimerQueueTimer( H323TimerQueue, m_hSetupSentTimer, NULL );
  4388. m_hSetupSentTimer = NULL;
  4389. }
  4390. if( m_hCallEstablishmentTimer )
  4391. {
  4392. DeleteTimerQueueTimer(H323TimerQueue, m_hCallEstablishmentTimer, NULL);
  4393. m_hCallEstablishmentTimer = NULL;
  4394. }
  4395. m_dwStateMachine = Q931_CONNECT_RECVD;
  4396. H323DBG((DEBUG_LEVEL_TRACE, "OnReceiveConnect exited: %p.", this ));
  4397. return TRUE;
  4398. }
  4399. //!!always called in a lock
  4400. BOOL
  4401. CH323Call::OnReceiveSetup(
  4402. IN Q931MESSAGE* pMessage
  4403. )
  4404. {
  4405. Q931_SETUP_ASN setupASN;
  4406. DWORD dwH450APDUType = 0;
  4407. PH323_CALL pCall = NULL;
  4408. WCHAR pwszCallingPartyNr[H323_MAXPATHNAMELEN];
  4409. WCHAR pwszCalledPartyNr[H323_MAXPATHNAMELEN];
  4410. BYTE* pstrTemp;
  4411. //decode the U2U information
  4412. if( (pMessage ->UserToUser.fPresent == FALSE) ||
  4413. (pMessage ->UserToUser.wUserInfoLen == 0) )
  4414. {
  4415. H323DBG(( DEBUG_LEVEL_ERROR,
  4416. "Setup message did not contain H.323 UUIE, ignoring."));
  4417. //ignore this message. don't shutdown the call.
  4418. return FALSE;
  4419. }
  4420. if( m_dwOrigin != LINECALLORIGIN_INBOUND )
  4421. {
  4422. H323DBG(( DEBUG_LEVEL_ERROR,
  4423. "Received Setup message on outbound call, ignoring."));
  4424. //ignore this message. don't shutdown the call.
  4425. return FALSE;
  4426. }
  4427. if( m_dwStateMachine != Q931_CALL_STATE_NONE )
  4428. {
  4429. H323DBG( (DEBUG_LEVEL_ERROR,
  4430. "Received Setup message on a call that is already in progress." ));
  4431. //This Q931 call has already received a setup!!!!
  4432. CloseCall( 0 );
  4433. return FALSE;
  4434. }
  4435. if( !ParseSetupASN( pMessage->UserToUser.pbUserInfo,
  4436. pMessage->UserToUser.wUserInfoLen,
  4437. &setupASN,
  4438. &dwH450APDUType ))
  4439. {
  4440. H323DBG(( DEBUG_LEVEL_ERROR,
  4441. "Failed to parse Setup UUIE, closing call." ));
  4442. //shutdown the Q931 call
  4443. CloseCall( 0 );
  4444. return FALSE;
  4445. }
  4446. if( dwH450APDUType )
  4447. {
  4448. if( m_dwCallType & CALLTYPE_FORWARDCONSULT )
  4449. {
  4450. return TRUE;
  4451. }
  4452. }
  4453. if( (pMessage->CallingPartyNumber.fPresent == TRUE) &&
  4454. (pMessage->CallingPartyNumber.dwLength > 1) &&
  4455. (setupASN.pCallerAliasList == NULL ) )
  4456. {
  4457. // Always skip 1st byte in the contents.
  4458. // Skip the 2nd byte if its not an e.164 char (could be the screening indicator byte)
  4459. pstrTemp = pMessage->CallingPartyNumber.pbContents +
  4460. ((pMessage->CallingPartyNumber.pbContents[1] & 0x80)? 2 : 1);
  4461. MultiByteToWideChar( CP_ACP,
  4462. 0,
  4463. (const char *)(pstrTemp),
  4464. -1,
  4465. pwszCallingPartyNr,
  4466. sizeof(pwszCallingPartyNr)/sizeof(WCHAR));
  4467. setupASN.pCallerAliasList = new H323_ALIASNAMES;
  4468. if( setupASN.pCallerAliasList != NULL )
  4469. {
  4470. ZeroMemory( setupASN.pCallerAliasList, sizeof(H323_ALIASNAMES) );
  4471. AddAliasItem( setupASN.pCallerAliasList,
  4472. pwszCallingPartyNr,
  4473. e164_chosen );
  4474. }
  4475. }
  4476. if( (pMessage->CalledPartyNumber.fPresent == TRUE) &&
  4477. (pMessage->CalledPartyNumber.PartyNumberLength > 0) &&
  4478. (setupASN.pCalleeAliasList == NULL ) )
  4479. {
  4480. // Always skip 1st byte in the contents.
  4481. // Skip the 2nd byte if its not an e.164 char (could be the screening indicator byte)
  4482. MultiByteToWideChar(CP_ACP,
  4483. 0,
  4484. (const char *)(pMessage->CalledPartyNumber.PartyNumbers),
  4485. -1,
  4486. pwszCalledPartyNr,
  4487. sizeof(pwszCalledPartyNr) / sizeof(WCHAR) );
  4488. setupASN.pCalleeAliasList = new H323_ALIASNAMES;
  4489. if( setupASN.pCalleeAliasList != NULL )
  4490. {
  4491. ZeroMemory( setupASN.pCalleeAliasList, sizeof(H323_ALIASNAMES) );
  4492. AddAliasItem( setupASN.pCalleeAliasList,
  4493. pwszCalledPartyNr,
  4494. e164_chosen );
  4495. }
  4496. }
  4497. //don't change the call type here
  4498. if( !InitializeIncomingCall( &setupASN, m_dwCallType, pMessage->wCallRef ) )
  4499. {
  4500. H323DBG ((DEBUG_LEVEL_ERROR,
  4501. "Failed to initialize incoming call, closing call."));
  4502. //shutdown the Q931 call
  4503. FreeSetupASN( &setupASN );
  4504. CloseCall( 0 );
  4505. return FALSE;
  4506. }
  4507. FreeSetupASN( &setupASN );
  4508. m_dwStateMachine = Q931_SETUP_RECVD;
  4509. if( !HandleSetupMessage( pMessage ) )
  4510. {
  4511. H323DBG ((DEBUG_LEVEL_ERROR,
  4512. "Failed to process Setup message, closing call."));
  4513. CloseCall( 0 );
  4514. return FALSE;
  4515. }
  4516. return TRUE;
  4517. }
  4518. //!!always called in a lock
  4519. void
  4520. CH323Call::CloseCall(
  4521. IN DWORD dwDisconnectMode )
  4522. {
  4523. H323DBG((DEBUG_LEVEL_INFO, "[%08XH] Terminating call.", this ));
  4524. if (!QueueTAPILineRequest(
  4525. TSPI_CLOSE_CALL,
  4526. m_hdCall,
  4527. NULL,
  4528. dwDisconnectMode,
  4529. m_wCallReference ))
  4530. {
  4531. H323DBG(( DEBUG_LEVEL_ERROR, "could not post H323 close event." ));
  4532. }
  4533. }
  4534. //!!always called in a lock
  4535. void
  4536. CH323Call::ReadEvent(
  4537. IN DWORD cbTransfer
  4538. )
  4539. {
  4540. H323DBG((DEBUG_LEVEL_TRACE, "ReadEvent entered: %p.", this ));
  4541. H323DBG((DEBUG_LEVEL_TRACE, "bytes received: %d.", cbTransfer));
  4542. m_RecvBuf.dwBytesCopied += cbTransfer;
  4543. //update the recv buffer
  4544. if( m_bStartOfPDU )
  4545. {
  4546. if( m_RecvBuf.dwBytesCopied < sizeof(TPKT_HEADER_SIZE) )
  4547. {
  4548. //set the buffer to get the remainig TPKT_HEADER
  4549. m_RecvBuf.WSABuf.buf =
  4550. m_RecvBuf.arBuf + m_RecvBuf.dwBytesCopied;
  4551. m_RecvBuf.WSABuf.len =
  4552. TPKT_HEADER_SIZE - m_RecvBuf.dwBytesCopied;
  4553. }
  4554. else
  4555. {
  4556. m_RecvBuf.dwPDULen = GetTpktLength( m_RecvBuf.arBuf );
  4557. if( (m_RecvBuf.dwPDULen < TPKT_HEADER_SIZE) ||
  4558. (m_RecvBuf.dwPDULen > Q931_RECV_BUFFER_LENGTH) )
  4559. {
  4560. //messed up peer. close the call.
  4561. H323DBG(( DEBUG_LEVEL_ERROR, "error:PDULen:%d.",
  4562. m_RecvBuf.dwPDULen ));
  4563. //close the call
  4564. CloseCall( 0 );
  4565. return;
  4566. }
  4567. else if( m_RecvBuf.dwPDULen == TPKT_HEADER_SIZE )
  4568. {
  4569. InitializeRecvBuf();
  4570. }
  4571. else
  4572. {
  4573. //set the buffer to get the remaining PDU
  4574. m_bStartOfPDU = FALSE;
  4575. m_RecvBuf.WSABuf.buf = m_RecvBuf.arBuf +
  4576. m_RecvBuf.dwBytesCopied;
  4577. m_RecvBuf.WSABuf.len = m_RecvBuf.dwPDULen -
  4578. m_RecvBuf.dwBytesCopied;
  4579. }
  4580. }
  4581. }
  4582. else
  4583. {
  4584. _ASSERTE( m_RecvBuf.dwBytesCopied <= m_RecvBuf.dwPDULen );
  4585. if( m_RecvBuf.dwBytesCopied == m_RecvBuf.dwPDULen )
  4586. {
  4587. //we got the whole PDU
  4588. if( !ProcessQ931PDU( &m_RecvBuf ) )
  4589. {
  4590. H323DBG(( DEBUG_LEVEL_ERROR,
  4591. "error in processing PDU:%p.", this ));
  4592. H323DUMPBUFFER( (BYTE*)m_RecvBuf.arBuf, m_RecvBuf.dwPDULen );
  4593. }
  4594. //if the call has been already shutdown due to
  4595. //a fatal error while processing the PDU or because of receiveing
  4596. //release complete message then dont post any more read buffers
  4597. if( (m_dwFlags & CALLOBJECT_SHUTDOWN) ||
  4598. (m_dwQ931Flags & Q931_CALL_DISCONNECTED) )
  4599. {
  4600. return;
  4601. }
  4602. InitializeRecvBuf();
  4603. }
  4604. else
  4605. {
  4606. //set the buffer to get the remainig PDU
  4607. m_RecvBuf.WSABuf. buf =
  4608. m_RecvBuf.arBuf + m_RecvBuf.dwBytesCopied;
  4609. m_RecvBuf.WSABuf. len =
  4610. m_RecvBuf.dwPDULen - m_RecvBuf.dwBytesCopied;
  4611. }
  4612. }
  4613. //post a read for the remaining PDU
  4614. if(!PostReadBuffer())
  4615. {
  4616. //post a message to the callback thread to shutdown the H323 call
  4617. CloseCall( 0 );
  4618. }
  4619. H323DBG((DEBUG_LEVEL_TRACE, "ReadEvent exited: %p.", this ));
  4620. }
  4621. /*
  4622. Parse a generic Q931 message and place the fields of the buffer
  4623. into the appropriate structure fields.
  4624. Parameters:
  4625. pBuf Pointer to buffer descriptor of an
  4626. input packet containing the 931 message.
  4627. pMessage Pointer to space for parsed output information.
  4628. */
  4629. //!!always called in a lock
  4630. HRESULT
  4631. CH323Call::Q931ParseMessage(
  4632. IN BYTE * pbCodedBuffer,
  4633. IN DWORD dwCodedBufferLength,
  4634. OUT PQ931MESSAGE pMessage
  4635. )
  4636. {
  4637. HRESULT hr;
  4638. BUFFERDESCR pBuf;
  4639. pBuf.dwLength = dwCodedBufferLength;
  4640. pBuf.pbBuffer = pbCodedBuffer;
  4641. H323DBG((DEBUG_LEVEL_TRACE, "Q931ParseMessage entered: %p.", this ));
  4642. memset( (PVOID)pMessage, 0, sizeof(Q931MESSAGE));
  4643. hr = ParseProtocolDiscriminator(&pBuf, &pMessage->ProtocolDiscriminator);
  4644. if( hr != S_OK )
  4645. {
  4646. return hr;
  4647. }
  4648. hr = ParseCallReference( &pBuf, &pMessage->wCallRef);
  4649. if( hr != S_OK )
  4650. {
  4651. return hr;
  4652. }
  4653. hr = ParseMessageType( &pBuf, &pMessage->MessageType );
  4654. if( hr != S_OK )
  4655. {
  4656. return hr;
  4657. }
  4658. while (pBuf.dwLength)
  4659. {
  4660. hr = ParseQ931Field(&pBuf, pMessage);
  4661. if (hr != S_OK)
  4662. {
  4663. return hr;
  4664. }
  4665. }
  4666. H323DBG((DEBUG_LEVEL_TRACE, "Q931ParseMessage exited: %p.", this ));
  4667. return S_OK;
  4668. }
  4669. //decode the PDU and release the buffer
  4670. //!!always called in a lock
  4671. BOOL
  4672. CH323Call::ProcessQ931PDU(
  4673. IN CALL_RECV_CONTEXT* pRecvBuf
  4674. )
  4675. {
  4676. PQ931MESSAGE pMessage;
  4677. BOOL retVal;
  4678. HRESULT hr;
  4679. H323DBG((DEBUG_LEVEL_TRACE, "ProcessQ931PDU entered: %p.", this ));
  4680. pMessage = new Q931MESSAGE;
  4681. if( pMessage == NULL )
  4682. {
  4683. return FALSE;
  4684. }
  4685. hr = Q931ParseMessage( (BYTE*)(pRecvBuf->arBuf + sizeof(TPKT_HEADER_SIZE)),
  4686. pRecvBuf->dwPDULen - 4,
  4687. pMessage );
  4688. if( !SUCCEEDED( hr) )
  4689. {
  4690. delete pMessage;
  4691. return FALSE;
  4692. }
  4693. if( (m_dwCallType & CALLTYPE_TRANSFERED_PRIMARY ) &&
  4694. (m_dwCallDiversionState == H4502_CTINITIATE_RECV) &&
  4695. (pMessage->MessageType != RELEASECOMPLMESSAGETYPE) )
  4696. {
  4697. // If this endpoint has already been transferred then
  4698. // ignore any further messages on the primary call.
  4699. delete pMessage;
  4700. return FALSE;
  4701. }
  4702. switch( pMessage->MessageType )
  4703. {
  4704. case ALERTINGMESSAGETYPE:
  4705. retVal = OnReceiveAlerting( pMessage );
  4706. break;
  4707. case PROCEEDINGMESSAGETYPE:
  4708. retVal = OnReceiveProceeding( pMessage );
  4709. break;
  4710. case CONNECTMESSAGETYPE:
  4711. retVal = OnReceiveConnect( pMessage );
  4712. break;
  4713. case RELEASECOMPLMESSAGETYPE:
  4714. retVal = OnReceiveRelease( pMessage );
  4715. break;
  4716. case SETUPMESSAGETYPE:
  4717. retVal = OnReceiveSetup( pMessage );
  4718. break;
  4719. case FACILITYMESSAGETYPE:
  4720. retVal = OnReceiveFacility( pMessage );
  4721. break;
  4722. default:
  4723. H323DBG(( DEBUG_LEVEL_TRACE, "unrecognised PDU recvd:%d,%p.",
  4724. pMessage->MessageType, this ));
  4725. retVal = FALSE;
  4726. }
  4727. delete pMessage;
  4728. H323DBG((DEBUG_LEVEL_TRACE, "ProcessQ931PDU exited: %p.", this ));
  4729. return retVal;
  4730. }
  4731. //!!always called in a lock
  4732. void
  4733. CH323Call::OnConnectComplete(void)
  4734. {
  4735. BOOL fSuccess = TRUE;
  4736. PH323_CALL pCall = NULL;
  4737. H323DBG((DEBUG_LEVEL_TRACE, "OnConnectComplete entered: %p.", this ));
  4738. _ASSERTE( m_dwOrigin==LINECALLORIGIN_OUTBOUND );
  4739. if( !GetHostAddress( &m_CallerAddr) )
  4740. {
  4741. //memory failure : shutdown the H323 call
  4742. CloseCall( 0 );
  4743. return;
  4744. }
  4745. InitializeRecvBuf();
  4746. //post a buffer to winsock to accept messages from the peer
  4747. if( !PostReadBuffer() )
  4748. {
  4749. //memory failure : shutdown the H323 call
  4750. CloseCall( 0 );
  4751. return;
  4752. }
  4753. //set the state to connected
  4754. SetQ931CallState( Q931_CALL_CONNECTED );
  4755. if( (m_dwCallType == CALLTYPE_NORMAL) ||
  4756. (m_dwCallType & CALLTYPE_TRANSFERING_CONSULT) )
  4757. {
  4758. SendMSPMessage( SP_MSG_InitiateCall, 0, 0, NULL );
  4759. }
  4760. else if( m_dwCallType & CALLTYPE_TRANSFEREDSRC )
  4761. {
  4762. _ASSERTE( m_hdRelatedCall );
  4763. MSPMessageData* pMSPMessageData = new MSPMessageData;
  4764. if( pMSPMessageData == NULL )
  4765. {
  4766. CloseCall( 0 );
  4767. return;
  4768. }
  4769. pMSPMessageData->hdCall = m_hdRelatedCall;
  4770. pMSPMessageData->messageType = SP_MSG_InitiateCall;
  4771. pMSPMessageData->pbEncodedBuf = NULL;
  4772. pMSPMessageData->wLength = 0;
  4773. pMSPMessageData->hReplacementCall = m_hdCall;
  4774. if( !QueueUserWorkItem( SendMSPMessageOnRelatedCall, pMSPMessageData,
  4775. WT_EXECUTEDEFAULT ) )
  4776. {
  4777. delete pMSPMessageData;
  4778. CloseCall( 0 );
  4779. return;
  4780. }
  4781. }
  4782. else
  4783. {
  4784. //send the setup message
  4785. if( !SendSetupMessage() )
  4786. {
  4787. DropCall( 0 );
  4788. }
  4789. }
  4790. H323DBG((DEBUG_LEVEL_TRACE, "OnConnectComplete exited: %p.", this ));
  4791. }
  4792. //!!aleways called in a lock
  4793. BOOL
  4794. CH323Call::SendSetupMessage(void)
  4795. {
  4796. BOOL retVal = TRUE;
  4797. DWORD dwAPDUType = NO_H450_APDU;
  4798. H323DBG((DEBUG_LEVEL_TRACE, "SendSetupMessage entered: %p.", this ));
  4799. //encode ASN.1 and send Q931Setup message to the peer
  4800. if( m_dwCallType & CALLTYPE_FORWARDCONSULT )
  4801. {
  4802. //send the callRerouitng.invoke APDU if this is a forwardconsult call
  4803. retVal = SendQ931Message( NO_INVOKEID,
  4804. (DWORD)create_chosen,
  4805. (DWORD)pointToPoint_chosen,
  4806. SETUPMESSAGETYPE,
  4807. CHECKRESTRICTION_OPCODE| H450_INVOKE );
  4808. if( retVal )
  4809. {
  4810. m_dwStateMachine = Q931_SETUP_SENT;
  4811. m_dwCallDiversionState = H4503_CHECKRESTRICTION_SENT;
  4812. retVal = CreateTimerQueueTimer(
  4813. &m_hCheckRestrictionTimer,
  4814. H323TimerQueue,
  4815. CH323Call::CheckRestrictionTimerCallback,
  4816. (PVOID)m_hdCall,
  4817. CHECKRESTRICTION_EXPIRE_TIME, 0,
  4818. WT_EXECUTEINIOTHREAD | WT_EXECUTEONLYONCE );
  4819. }
  4820. }
  4821. else
  4822. {
  4823. if( ( m_dwCallType & CALLTYPE_DIVERTEDSRC ) ||
  4824. ( m_dwCallType & CALLTYPE_DIVERTEDSRC_NOROUTING ) )
  4825. {
  4826. dwAPDUType = DIVERTINGLEGINFO2_OPCODE | H450_INVOKE;
  4827. }
  4828. else if( m_dwCallType & CALLTYPE_TRANSFEREDSRC )
  4829. {
  4830. dwAPDUType = CTSETUP_OPCODE | H450_INVOKE;
  4831. }
  4832. retVal = SendQ931Message( NO_INVOKEID,
  4833. (DWORD)create_chosen,
  4834. (DWORD)pointToPoint_chosen,
  4835. SETUPMESSAGETYPE,
  4836. dwAPDUType );
  4837. if( retVal )
  4838. {
  4839. m_dwStateMachine = Q931_SETUP_SENT;
  4840. retVal = CreateTimerQueueTimer(
  4841. &m_hSetupSentTimer,
  4842. H323TimerQueue,
  4843. CH323Call::SetupSentTimerCallback,
  4844. (PVOID)m_hdCall,
  4845. SETUP_SENT_TIMEOUT, 0,
  4846. WT_EXECUTEINIOTHREAD | WT_EXECUTEONLYONCE );
  4847. }
  4848. }
  4849. if( retVal == FALSE )
  4850. {
  4851. CloseCall( 0 );
  4852. return FALSE;
  4853. }
  4854. H323DBG((DEBUG_LEVEL_TRACE, "SendSetupMessage exited: %p.", this ));
  4855. return TRUE;
  4856. }
  4857. //!!always called in a lock
  4858. BOOL
  4859. CH323Call::SendProceeding(void)
  4860. {
  4861. H323DBG((DEBUG_LEVEL_TRACE, "SendProceeding entered: %p.", this ));
  4862. _ASSERTE( m_dwOrigin == LINECALLORIGIN_INBOUND );
  4863. //encode ASN.1 and send Q931Setup message to the peer
  4864. if(!SendQ931Message( NO_INVOKEID, 0, 0, PROCEEDINGMESSAGETYPE, NO_H450_APDU ))
  4865. {
  4866. return FALSE;
  4867. }
  4868. m_dwStateMachine = Q931_PROCEED_SENT;
  4869. H323DBG((DEBUG_LEVEL_TRACE, "SendProceeding exited: %p.", this ));
  4870. return TRUE;
  4871. }
  4872. //!!always called in a lock
  4873. BOOL
  4874. CH323Call::PostReadBuffer(void)
  4875. {
  4876. int iError;
  4877. DWORD dwByteReceived = 0;
  4878. BOOL fDelete = FALSE;
  4879. H323DBG((DEBUG_LEVEL_TRACE, "PostReadBuffer entered: %p.", this ));
  4880. m_RecvBuf.Type = OVERLAPPED_TYPE_RECV;
  4881. m_RecvBuf.pCall = this;
  4882. m_RecvBuf.dwFlags = 0;
  4883. m_RecvBuf.BytesTransferred = 0;
  4884. ZeroMemory( (PVOID)&m_RecvBuf.Overlapped, sizeof(OVERLAPPED) );
  4885. //register with winsock for overlappped I/O
  4886. if( WSARecv( m_callSocket,
  4887. &(m_RecvBuf.WSABuf),
  4888. 1,
  4889. &(m_RecvBuf.BytesTransferred),
  4890. &(m_RecvBuf.dwFlags),
  4891. &(m_RecvBuf.Overlapped),
  4892. NULL ) == SOCKET_ERROR )
  4893. {
  4894. iError = WSAGetLastError();
  4895. if( iError != WSA_IO_PENDING )
  4896. {
  4897. //take care of error conditions here
  4898. H323DBG((DEBUG_LEVEL_ERROR, "error while recving buf: %d.",
  4899. iError ));
  4900. return FALSE;
  4901. }
  4902. }
  4903. else
  4904. {
  4905. //There is some data to read!!!!!
  4906. H323DBG(( DEBUG_LEVEL_TRACE, "bytes received immediately: %d.",
  4907. m_RecvBuf.BytesTransferred ));
  4908. }
  4909. m_IoRefCount++;
  4910. H323DBG((DEBUG_LEVEL_TRACE,
  4911. "PostReadBuffer:m_IoRefCount: %d:%p.", m_IoRefCount, this ));
  4912. H323DBG((DEBUG_LEVEL_TRACE, "PostReadBuffer exited: %p.", this ));
  4913. return TRUE;
  4914. }
  4915. //!!always called in a lock
  4916. BOOL
  4917. CH323Call::SendBuffer(
  4918. IN BYTE* pbBuffer,
  4919. IN DWORD dwLength
  4920. )
  4921. {
  4922. int iError;
  4923. CALL_SEND_CONTEXT* pSendBuf = NULL;
  4924. DWORD cbTransfer;
  4925. BOOL fDelete = FALSE;
  4926. H323DBG((DEBUG_LEVEL_TRACE, "SendBuffer entered: %p.", this ));
  4927. if( !(m_dwQ931Flags & Q931_CALL_CONNECTED) )
  4928. {
  4929. goto cleanup;
  4930. }
  4931. pSendBuf = new CALL_SEND_CONTEXT;
  4932. if( pSendBuf == NULL )
  4933. {
  4934. goto cleanup;
  4935. }
  4936. ZeroMemory( (PVOID)pSendBuf, sizeof(CALL_SEND_CONTEXT) );
  4937. pSendBuf->WSABuf.buf = (char*)pbBuffer;
  4938. pSendBuf->WSABuf.len = dwLength;
  4939. pSendBuf->BytesTransferred = 0;
  4940. pSendBuf->pCall = this;
  4941. pSendBuf->Type = OVERLAPPED_TYPE_SEND;
  4942. InsertTailList( &m_sendBufList, &(pSendBuf ->ListEntry) );
  4943. if( WSASend(m_callSocket,
  4944. &(pSendBuf->WSABuf),
  4945. 1,
  4946. &(pSendBuf->BytesTransferred),
  4947. 0,
  4948. &(pSendBuf->Overlapped),
  4949. NULL) == SOCKET_ERROR )
  4950. {
  4951. iError = WSAGetLastError();
  4952. if( iError != WSA_IO_PENDING )
  4953. {
  4954. H323DBG((DEBUG_LEVEL_TRACE, "error sending the buf: %lx.", iError));
  4955. RemoveEntryList( &pSendBuf->ListEntry );
  4956. goto cleanup;
  4957. }
  4958. }
  4959. else
  4960. {
  4961. //data was sent immediately!!!
  4962. H323DBG((DEBUG_LEVEL_TRACE, "data sent immediately!!." ));
  4963. }
  4964. m_IoRefCount++;
  4965. H323DBG((DEBUG_LEVEL_TRACE, "SendBuffer:m_IoRefCount11: %d:%p.",
  4966. m_IoRefCount, this ));
  4967. H323DBG((DEBUG_LEVEL_TRACE, "SendBuffer exited: %p.", this ));
  4968. return TRUE;
  4969. cleanup:
  4970. if(pSendBuf)
  4971. {
  4972. delete pSendBuf;
  4973. }
  4974. delete pbBuffer;
  4975. return FALSE;
  4976. }
  4977. //!!aleways called in a lock
  4978. BOOL
  4979. CH323Call::SetupCall(void)
  4980. {
  4981. SOCKET Q931CallSocket = INVALID_SOCKET;
  4982. SOCKADDR_IN sin;
  4983. HANDLE hWSAEvent;
  4984. HANDLE hConnWait;
  4985. BOOL fSuccess = TRUE;
  4986. int iError;
  4987. BOOL fDelete;
  4988. DWORD dwEnable = 1;
  4989. TCHAR ptstrEventName[100];
  4990. H323DBG((DEBUG_LEVEL_TRACE, "SetupCall entered."));
  4991. //create a socket
  4992. Q931CallSocket = WSASocket(
  4993. AF_INET,
  4994. SOCK_STREAM,
  4995. IPPROTO_IP,
  4996. NULL,
  4997. NULL,
  4998. WSA_FLAG_OVERLAPPED );
  4999. if( Q931CallSocket == INVALID_SOCKET )
  5000. {
  5001. H323DBG((DEBUG_LEVEL_ERROR, "error while creating socket: %lx.",
  5002. WSAGetLastError() ));
  5003. goto error1;
  5004. }
  5005. //create a new Q931 call object
  5006. if( InitializeQ931(Q931CallSocket) == NULL )
  5007. {
  5008. goto error2;
  5009. }
  5010. _stprintf( ptstrEventName, _T("%s-%p") ,
  5011. _T( "H323TSP_OutgoingCall_TransportHandlerEvent" ), this );
  5012. //create the wait event
  5013. hWSAEvent = H323CreateEvent( NULL, FALSE,
  5014. FALSE, ptstrEventName );
  5015. if( hWSAEvent == NULL )
  5016. {
  5017. H323DBG((DEBUG_LEVEL_ERROR, "couldn't create wsaevent" ));
  5018. goto error3;
  5019. }
  5020. //register with thread pool the event handle and handler proc
  5021. fSuccess = RegisterWaitForSingleObject(
  5022. &hConnWait, // pointer to the returned handle
  5023. hWSAEvent, // the event handle to wait for.
  5024. Q931TransportEventHandler, // the callback function.
  5025. (PVOID)m_hdCall, // the context for the callback.
  5026. INFINITE, // wait forever.
  5027. // probably don't need this flag set
  5028. WT_EXECUTEDEFAULT // use the wait thread to call the callback.
  5029. );
  5030. if ( ( !fSuccess ) || (hConnWait== NULL) )
  5031. {
  5032. GetLastError();
  5033. if( !CloseHandle( hWSAEvent ) )
  5034. {
  5035. H323DBG((DEBUG_LEVEL_ERROR, "couldn't close wsaevent" ));
  5036. }
  5037. goto error3;
  5038. }
  5039. //store this in the call context
  5040. SetNewCallInfo( hConnWait, hWSAEvent, Q931_CALL_CONNECTING );
  5041. //register with Winsock the event handle and the events
  5042. if( WSAEventSelect( Q931CallSocket,
  5043. hWSAEvent,
  5044. FD_CONNECT | FD_CLOSE
  5045. ) == SOCKET_ERROR )
  5046. {
  5047. H323DBG((DEBUG_LEVEL_ERROR,
  5048. "error selecting event outgoing call: %lx.", WSAGetLastError()));
  5049. goto error3;
  5050. }
  5051. if( setsockopt( Q931CallSocket,
  5052. IPPROTO_TCP,
  5053. TCP_NODELAY,
  5054. (char*)&dwEnable,
  5055. sizeof(DWORD)
  5056. ) == SOCKET_ERROR )
  5057. {
  5058. H323DBG(( DEBUG_LEVEL_WARNING,
  5059. "Couldn't set NODELAY option on outgoing call socket:%d, %p",
  5060. WSAGetLastError(), this ));
  5061. }
  5062. //set the address structure
  5063. memset( (PVOID)&sin, 0, sizeof(SOCKADDR_IN) );
  5064. sin.sin_family = AF_INET;
  5065. sin.sin_addr.s_addr = htonl( m_CalleeAddr.Addr.IP_Binary.dwAddr );
  5066. sin.sin_port = htons( m_CalleeAddr.Addr.IP_Binary.wPort );
  5067. //make the winsock connection
  5068. if( WSAConnect( Q931CallSocket,
  5069. (sockaddr*)&sin,
  5070. sizeof(SOCKADDR_IN),
  5071. NULL, NULL, NULL, NULL
  5072. )
  5073. == SOCKET_ERROR )
  5074. {
  5075. iError = WSAGetLastError();
  5076. if(iError != WSAEWOULDBLOCK )
  5077. {
  5078. H323DBG(( DEBUG_LEVEL_ERROR,
  5079. "error while connecting socket: %lx.", iError ));
  5080. goto error3;
  5081. }
  5082. }
  5083. else
  5084. { //connection went through immediately!!!
  5085. OnConnectComplete();
  5086. }
  5087. //success
  5088. H323DBG((DEBUG_LEVEL_TRACE, "SetupCall exited."));
  5089. return TRUE;
  5090. error3:
  5091. Unlock();
  5092. Shutdown( &fDelete );
  5093. Lock();
  5094. error2:
  5095. closesocket( Q931CallSocket );
  5096. error1:
  5097. return FALSE;
  5098. }
  5099. //!!aleways called in a lock
  5100. BOOL
  5101. CH323Call::AcceptH323Call(void)
  5102. {
  5103. DWORD dwAPDUType = NO_H450_APDU;
  5104. DWORD dwInvokeID = NO_INVOKEID;
  5105. H323DBG((DEBUG_LEVEL_TRACE, "AcceptH323Call entered: %p.", this ));
  5106. if( m_dwCallType & CALLTYPE_DIVERTEDDEST )
  5107. {
  5108. dwAPDUType = (DIVERTINGLEGINFO3_OPCODE | H450_INVOKE);
  5109. }
  5110. else if( m_dwCallType & CALLTYPE_TRANSFEREDDEST )
  5111. {
  5112. dwAPDUType = (CTSETUP_OPCODE | H450_RETURNRESULT);
  5113. dwInvokeID = m_dwInvokeID;
  5114. }
  5115. ChangeCallState( LINECALLSTATE_ACCEPTED, 0 );
  5116. //if pCall Divert On No Answer is enabled, then stop the timer
  5117. if( m_hCallDivertOnNATimer )
  5118. {
  5119. DeleteTimerQueueTimer( H323TimerQueue, m_hCallDivertOnNATimer, NULL );
  5120. m_hCallDivertOnNATimer = NULL;
  5121. }
  5122. //encode and send Q931Connect message to the peer
  5123. if( !SendQ931Message( dwInvokeID, 0, 0, CONNECTMESSAGETYPE, dwAPDUType ) )
  5124. {
  5125. //post a message to the callback thread to shutdown the H323 call
  5126. CloseCall( 0 );
  5127. return FALSE;
  5128. }
  5129. m_dwStateMachine = Q931_CONNECT_SENT;
  5130. H323DBG((DEBUG_LEVEL_TRACE, "AcceptH323Call exited: %p.", this ));
  5131. return TRUE;
  5132. }
  5133. //!!always called in a lock
  5134. BOOL
  5135. CH323Call::SendQ931Message(
  5136. IN DWORD dwInvokeID,
  5137. IN ULONG_PTR dwParam1,
  5138. IN ULONG_PTR dwParam2,
  5139. IN DWORD dwMessageType,
  5140. IN DWORD dwAPDUType
  5141. )
  5142. {
  5143. BINARY_STRING userUserData;
  5144. DWORD dwCodedLengthPDU;
  5145. BYTE *pbCodedPDU;
  5146. BOOL retVal = FALSE;
  5147. WCHAR * pwszCalledPartyNumber = NULL;
  5148. H323DBG((DEBUG_LEVEL_TRACE, "SendQ931Message entered: %p.", this ));
  5149. //check if socket is connected
  5150. if( !(m_dwQ931Flags & Q931_CALL_CONNECTED) )
  5151. {
  5152. return FALSE;
  5153. }
  5154. switch ( dwMessageType )
  5155. {
  5156. //encode the UU message
  5157. case SETUPMESSAGETYPE:
  5158. retVal = EncodeSetupMessage( dwInvokeID, (WORD)dwParam1, //dwGoal
  5159. (WORD)dwParam2, //dwCalType
  5160. &userUserData.pbBuffer,
  5161. &userUserData.length,
  5162. dwAPDUType );
  5163. break;
  5164. case ALERTINGMESSAGETYPE:
  5165. retVal = EncodeAlertMessage( dwInvokeID,
  5166. &userUserData.pbBuffer,
  5167. &userUserData.length,
  5168. dwAPDUType );
  5169. break;
  5170. case PROCEEDINGMESSAGETYPE:
  5171. retVal = EncodeProceedingMessage( dwInvokeID,
  5172. &userUserData.pbBuffer,
  5173. &userUserData.length,
  5174. dwAPDUType );
  5175. break;
  5176. case RELEASECOMPLMESSAGETYPE:
  5177. retVal = EncodeReleaseCompleteMessage( dwInvokeID,
  5178. (BYTE*)dwParam1, //pbReason
  5179. &userUserData.pbBuffer,
  5180. &userUserData.length,
  5181. dwAPDUType );
  5182. break;
  5183. case CONNECTMESSAGETYPE:
  5184. retVal = EncodeConnectMessage( dwInvokeID,
  5185. &userUserData.pbBuffer,
  5186. &userUserData.length,
  5187. dwAPDUType );
  5188. break;
  5189. case FACILITYMESSAGETYPE:
  5190. retVal = EncodeFacilityMessage( dwInvokeID,
  5191. (BYTE)dwParam1,
  5192. (ASN1octetstring_t*)dwParam2,
  5193. &userUserData.pbBuffer,
  5194. &userUserData.length,
  5195. dwAPDUType );
  5196. break;
  5197. }
  5198. if( retVal == FALSE )
  5199. {
  5200. H323DBG(( DEBUG_LEVEL_ERROR,
  5201. "could not encode message:%d.", dwMessageType));
  5202. if( userUserData.pbBuffer )
  5203. {
  5204. ASN1_FreeEncoded(m_ASNCoderInfo.pEncInfo, userUserData.pbBuffer );
  5205. }
  5206. return FALSE;
  5207. }
  5208. if (m_dwAddressType == LINEADDRESSTYPE_PHONENUMBER)
  5209. {
  5210. _ASSERTE( m_pCalleeAliasNames->pItems[0].wType == e164_chosen );
  5211. pwszCalledPartyNumber = m_pCalleeAliasNames ->pItems[0].pData;
  5212. }
  5213. //encode the PDU
  5214. retVal = EncodePDU( &userUserData,
  5215. &pbCodedPDU,
  5216. &dwCodedLengthPDU,
  5217. dwMessageType,
  5218. pwszCalledPartyNumber );
  5219. if( retVal == FALSE )
  5220. {
  5221. H323DBG(( DEBUG_LEVEL_ERROR,
  5222. "could not encode PDU: %d.", dwMessageType ));
  5223. }
  5224. else if(!SendBuffer( pbCodedPDU, dwCodedLengthPDU ))
  5225. {
  5226. retVal = FALSE;
  5227. }
  5228. if( userUserData.pbBuffer )
  5229. {
  5230. ASN1_FreeEncoded(m_ASNCoderInfo.pEncInfo, userUserData.pbBuffer );
  5231. }
  5232. H323DBG((DEBUG_LEVEL_TRACE, "SendQ931Message exited: %p.", this ));
  5233. return retVal;
  5234. }
  5235. //!!always called in a lock
  5236. BOOL
  5237. CH323Call::EncodeFastStartProposal(
  5238. PH323_FASTSTART pFastStart,
  5239. BYTE** ppEncodedBuf,
  5240. WORD* pwEncodedLength
  5241. )
  5242. {
  5243. int rc;
  5244. H323_UserInformation UserInfo;
  5245. H323DBG((DEBUG_LEVEL_TRACE, "EncodeFastStartProposal entered: %p.", this ));
  5246. CallProceeding_UUIE & proceedingMessage =
  5247. UserInfo.h323_uu_pdu.h323_message_body.u.callProceeding;
  5248. *ppEncodedBuf = NULL;
  5249. *pwEncodedLength = 0;
  5250. memset( (PVOID)&UserInfo, 0, sizeof(H323_UserInformation));
  5251. UserInfo.bit_mask = 0;
  5252. //copy the call identifier
  5253. proceedingMessage.bit_mask |= CallProceeding_UUIE_callIdentifier_present;
  5254. CopyMemory( (PVOID)&proceedingMessage.callIdentifier.guid.value,
  5255. (PVOID)&m_callIdentifier,
  5256. sizeof(GUID) );
  5257. proceedingMessage.callIdentifier.guid.length = sizeof(GUID);
  5258. // make sure the user_data_present flag is turned off.
  5259. UserInfo.bit_mask &= (~user_data_present);
  5260. UserInfo.h323_uu_pdu.bit_mask = 0;
  5261. UserInfo.h323_uu_pdu.h323_message_body.choice = callProceeding_chosen;
  5262. proceedingMessage.protocolIdentifier = OID_H225ProtocolIdentifierV2;
  5263. proceedingMessage.bit_mask |= CallProceeding_UUIE_fastStart_present;
  5264. proceedingMessage.fastStart = (PCallProceeding_UUIE_fastStart)pFastStart;
  5265. rc = EncodeASN( (void *) &UserInfo,
  5266. H323_UserInformation_PDU,
  5267. ppEncodedBuf,
  5268. pwEncodedLength);
  5269. if (ASN1_FAILED(rc) || (*ppEncodedBuf == NULL) || (pwEncodedLength == 0) )
  5270. {
  5271. return FALSE;
  5272. }
  5273. H323DBG((DEBUG_LEVEL_TRACE, "EncodeFastStartProposal exited: %p.", this ));
  5274. //success
  5275. return TRUE;
  5276. }
  5277. //!!always called in a lock
  5278. BOOL
  5279. CH323Call::EncodeFacilityMessage(
  5280. IN DWORD dwInvokeID,
  5281. IN BYTE bReason,
  5282. IN ASN1octetstring_t* pH245PDU,
  5283. OUT BYTE **ppEncodedBuf,
  5284. OUT WORD *pdwEncodedLength,
  5285. IN DWORD dwAPDUType
  5286. )
  5287. {
  5288. H323_UU_PDU_h4501SupplementaryService h4501APDU;
  5289. int rc;
  5290. H323_UserInformation UserInfo;
  5291. DWORD dwAPDULen = 0;
  5292. BYTE* pEncodedAPDU = NULL;
  5293. H323DBG((DEBUG_LEVEL_TRACE, "EncodeFacilityMessage entered: %p.", this ));
  5294. Facility_UUIE & facilityMessage =
  5295. UserInfo.h323_uu_pdu.h323_message_body.u.facility;
  5296. *ppEncodedBuf = NULL;
  5297. *pdwEncodedLength = 0;
  5298. memset( (PVOID)&UserInfo, 0, sizeof(H323_UserInformation));
  5299. UserInfo.bit_mask = 0;
  5300. // make sure the user_data_present flag is turned off.
  5301. UserInfo.bit_mask &= (~user_data_present);
  5302. UserInfo.h323_uu_pdu.bit_mask = 0;
  5303. //send the appropriate ADPDUS
  5304. if( dwAPDUType != NO_H450_APDU )
  5305. {
  5306. if( !EncodeH450APDU(dwInvokeID, dwAPDUType,
  5307. &pEncodedAPDU, &dwAPDULen ) )
  5308. {
  5309. return FALSE;
  5310. }
  5311. UserInfo.h323_uu_pdu.h4501SupplementaryService = &h4501APDU;
  5312. UserInfo.h323_uu_pdu.h4501SupplementaryService -> next = NULL;
  5313. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.value = pEncodedAPDU;
  5314. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.length = dwAPDULen;
  5315. UserInfo.h323_uu_pdu.bit_mask |= h4501SupplementaryService_present;
  5316. }
  5317. UserInfo.h323_uu_pdu.h245Tunneling = FALSE;//(m_fh245Tunneling & LOCAL_H245_TUNNELING);
  5318. UserInfo.h323_uu_pdu.bit_mask |= h245Tunneling_present;
  5319. SetNonStandardData( UserInfo );
  5320. UserInfo.h323_uu_pdu.h323_message_body.choice = facility_chosen;
  5321. facilityMessage.protocolIdentifier = OID_H225ProtocolIdentifierV2;
  5322. facilityMessage.bit_mask = 0;
  5323. TransportAddress& transportAddress = facilityMessage.alternativeAddress;
  5324. if( IsGuidSet( &m_ConferenceID ) )
  5325. {
  5326. CopyConferenceID(&facilityMessage.conferenceID, &m_ConferenceID);
  5327. facilityMessage.bit_mask |= Facility_UUIE_conferenceID_present;
  5328. }
  5329. switch (bReason)
  5330. {
  5331. case H323_REJECT_ROUTE_TO_GATEKEEPER:
  5332. facilityMessage.reason.choice =
  5333. FacilityReason_routeCallToGatekeeper_chosen;
  5334. break;
  5335. case H323_REJECT_CALL_FORWARDED:
  5336. facilityMessage.reason.choice = callForwarded_chosen;
  5337. break;
  5338. case H323_REJECT_ROUTE_TO_MC:
  5339. facilityMessage.reason.choice = routeCallToMC_chosen;
  5340. break;
  5341. default:
  5342. facilityMessage.reason.choice = FacilityReason_undefinedReason_chosen;
  5343. }
  5344. facilityMessage.bit_mask |= Facility_UUIE_callIdentifier_present;
  5345. CopyMemory( (PVOID)&facilityMessage.callIdentifier.guid.value,
  5346. (PVOID)"abcdabcdabcdabcdabcd",
  5347. sizeof(GUID) );
  5348. facilityMessage.callIdentifier.guid.length = sizeof(GUID);
  5349. if( pH245PDU && (pH245PDU->value != NULL) )
  5350. {
  5351. //h245 PDU to be sent
  5352. UserInfo.h323_uu_pdu.h245Control->next = NULL;
  5353. UserInfo.h323_uu_pdu.h245Control->value.length = pH245PDU->length;
  5354. UserInfo.h323_uu_pdu.h245Control->value.value = pH245PDU->value;
  5355. }
  5356. rc = EncodeASN((void *) &UserInfo,
  5357. H323_UserInformation_PDU,
  5358. ppEncodedBuf,
  5359. pdwEncodedLength);
  5360. if( ASN1_FAILED(rc) || (*ppEncodedBuf == NULL) || (pdwEncodedLength == 0) )
  5361. {
  5362. if( pEncodedAPDU != NULL )
  5363. {
  5364. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5365. }
  5366. return FALSE;
  5367. }
  5368. if( pEncodedAPDU != NULL )
  5369. {
  5370. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5371. }
  5372. H323DBG((DEBUG_LEVEL_TRACE, "EncodeFacilityMessage exited: %p.", this ));
  5373. //success
  5374. return TRUE;
  5375. }
  5376. //!!always called in a lock
  5377. BOOL
  5378. CH323Call::EncodeAlertMessage(
  5379. IN DWORD dwInvokeID,
  5380. OUT BYTE **ppEncodedBuf,
  5381. OUT WORD *pdwEncodedLength,
  5382. IN DWORD dwAPDUType
  5383. )
  5384. {
  5385. H323_UU_PDU_h4501SupplementaryService h4501APDU;
  5386. int rc;
  5387. H323_UserInformation UserInfo;
  5388. DWORD dwAPDULen = 0;
  5389. BYTE* pEncodedAPDU = NULL;
  5390. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeAlertMessage entered: %p.", this ));
  5391. Alerting_UUIE & alertingMessage =
  5392. UserInfo.h323_uu_pdu.h323_message_body.u.alerting;
  5393. *ppEncodedBuf = NULL;
  5394. *pdwEncodedLength = 0;
  5395. memset( (PVOID)&UserInfo, 0, sizeof(H323_UserInformation));
  5396. UserInfo.bit_mask = 0;
  5397. // make sure the user_data_present flag is turned off.
  5398. UserInfo.bit_mask &= (~user_data_present);
  5399. UserInfo.h323_uu_pdu.bit_mask = 0;
  5400. if( dwAPDUType != NO_H450_APDU )
  5401. {
  5402. if( !EncodeH450APDU( dwInvokeID, dwAPDUType, &pEncodedAPDU, &dwAPDULen ) )
  5403. {
  5404. return FALSE;
  5405. }
  5406. UserInfo.h323_uu_pdu.h4501SupplementaryService = &h4501APDU;
  5407. UserInfo.h323_uu_pdu.h4501SupplementaryService -> next = NULL;
  5408. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.value = pEncodedAPDU;
  5409. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.length = dwAPDULen;
  5410. UserInfo.h323_uu_pdu.bit_mask |= h4501SupplementaryService_present;
  5411. }
  5412. UserInfo.h323_uu_pdu.h245Tunneling = FALSE;//(m_fh245Tunneling & LOCAL_H245_TUNNELING);
  5413. UserInfo.h323_uu_pdu.bit_mask |= h245Tunneling_present;
  5414. SetNonStandardData( UserInfo );
  5415. UserInfo.h323_uu_pdu.h323_message_body.choice = alerting_chosen;
  5416. alertingMessage.protocolIdentifier = OID_H225ProtocolIdentifierV2;
  5417. alertingMessage.destinationInfo.bit_mask = 0;
  5418. //copy the vendor info
  5419. alertingMessage.destinationInfo.bit_mask |= vendor_present;
  5420. CopyVendorInfo( &alertingMessage.destinationInfo.vendor );
  5421. //its a terminal
  5422. alertingMessage.destinationInfo.bit_mask = terminal_present;
  5423. alertingMessage.destinationInfo.terminal.bit_mask = 0;
  5424. //not na MC
  5425. alertingMessage.destinationInfo.mc = 0;
  5426. alertingMessage.destinationInfo.undefinedNode = 0;
  5427. TransportAddress& transportAddress = alertingMessage.h245Address;
  5428. //send H245 address only if the caller hasn't proposed FasrStart
  5429. //or the fast start proposal has been accepeted
  5430. if( (m_pPeerFastStart == NULL) || m_pFastStart )
  5431. {
  5432. if( m_selfH245Addr.Addr.IP_Binary.dwAddr != 0 )
  5433. {
  5434. CopyTransportAddress( transportAddress, &m_selfH245Addr );
  5435. alertingMessage.bit_mask |= (Alerting_UUIE_h245Address_present);
  5436. }
  5437. else
  5438. {
  5439. alertingMessage.bit_mask &= (~Alerting_UUIE_h245Address_present);
  5440. }
  5441. }
  5442. if( m_pFastStart != NULL )
  5443. {
  5444. _ASSERTE( m_pPeerFastStart );
  5445. alertingMessage.bit_mask |= Alerting_UUIE_fastStart_present;
  5446. alertingMessage.fastStart = (PAlerting_UUIE_fastStart)m_pFastStart;
  5447. }
  5448. else
  5449. {
  5450. alertingMessage.bit_mask &= ~Alerting_UUIE_fastStart_present;
  5451. }
  5452. //copy the call identifier
  5453. alertingMessage.bit_mask |= Alerting_UUIE_callIdentifier_present;
  5454. CopyMemory( (PVOID)&alertingMessage.callIdentifier.guid.value,
  5455. (PVOID)&m_callIdentifier,
  5456. sizeof(GUID) );
  5457. alertingMessage.callIdentifier.guid.length = sizeof(GUID);
  5458. rc = EncodeASN( (void *) &UserInfo,
  5459. H323_UserInformation_PDU,
  5460. ppEncodedBuf,
  5461. pdwEncodedLength);
  5462. if (ASN1_FAILED(rc) || (*ppEncodedBuf == NULL) || (pdwEncodedLength == 0) )
  5463. {
  5464. if( pEncodedAPDU != NULL )
  5465. {
  5466. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5467. }
  5468. return FALSE;
  5469. }
  5470. if( pEncodedAPDU != NULL )
  5471. {
  5472. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5473. }
  5474. H323DBG((DEBUG_LEVEL_TRACE, "EncodeAlertMessage exited: %p.", this ));
  5475. //success
  5476. return TRUE;
  5477. }
  5478. //!!always called in a lock
  5479. BOOL
  5480. CH323Call::EncodeProceedingMessage(
  5481. IN DWORD dwInvokeID,
  5482. OUT BYTE **ppEncodedBuf,
  5483. OUT WORD *pdwEncodedLength,
  5484. IN DWORD dwAPDUType
  5485. )
  5486. {
  5487. H323_UU_PDU_h4501SupplementaryService h4501APDU;
  5488. int rc;
  5489. H323_UserInformation UserInfo;
  5490. DWORD dwAPDULen = 0;
  5491. BYTE* pEncodedAPDU = NULL;
  5492. H323DBG((DEBUG_LEVEL_TRACE, "EncodeProceedingMessage entered: %p.", this ));
  5493. CallProceeding_UUIE & proceedingMessage =
  5494. UserInfo.h323_uu_pdu.h323_message_body.u.callProceeding;
  5495. *ppEncodedBuf = NULL;
  5496. *pdwEncodedLength = 0;
  5497. memset( (PVOID)&UserInfo, 0, sizeof(H323_UserInformation));
  5498. UserInfo.bit_mask = 0;
  5499. // make sure the user_data_present flag is turned off.
  5500. UserInfo.bit_mask &= (~user_data_present);
  5501. UserInfo.h323_uu_pdu.bit_mask = 0;
  5502. if( dwAPDUType != NO_H450_APDU )
  5503. {
  5504. if( !EncodeH450APDU( dwInvokeID, dwAPDUType, &pEncodedAPDU, &dwAPDULen ) )
  5505. {
  5506. return FALSE;
  5507. }
  5508. UserInfo.h323_uu_pdu.h4501SupplementaryService = &h4501APDU;
  5509. UserInfo.h323_uu_pdu.h4501SupplementaryService -> next = NULL;
  5510. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.value = pEncodedAPDU;
  5511. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.length = dwAPDULen;
  5512. UserInfo.h323_uu_pdu.bit_mask |= h4501SupplementaryService_present;
  5513. }
  5514. UserInfo.h323_uu_pdu.h245Tunneling = FALSE;//(m_fh245Tunneling & LOCAL_H245_TUNNELING);
  5515. UserInfo.h323_uu_pdu.bit_mask |= h245Tunneling_present;
  5516. SetNonStandardData( UserInfo );
  5517. UserInfo.h323_uu_pdu.h323_message_body.choice = callProceeding_chosen;
  5518. proceedingMessage.protocolIdentifier = OID_H225ProtocolIdentifierV2;
  5519. TransportAddress& transportAddress = proceedingMessage.h245Address;
  5520. //send H245 address only if the caller hasn't proposed FasrStart
  5521. //or the fast start proposal has been accepeted
  5522. if( (m_pPeerFastStart == NULL) || m_pFastStart )
  5523. {
  5524. if( m_selfH245Addr.Addr.IP_Binary.dwAddr != 0 )
  5525. {
  5526. CopyTransportAddress( transportAddress, &m_selfH245Addr );
  5527. proceedingMessage.bit_mask |= CallProceeding_UUIE_h245Address_present;
  5528. }
  5529. else
  5530. {
  5531. proceedingMessage.bit_mask &= ~CallProceeding_UUIE_h245Address_present;
  5532. }
  5533. }
  5534. proceedingMessage.destinationInfo.bit_mask = 0;
  5535. //copy the vendor info
  5536. proceedingMessage.destinationInfo.bit_mask |= vendor_present;
  5537. CopyVendorInfo( &proceedingMessage.destinationInfo.vendor );
  5538. proceedingMessage.destinationInfo.mc = 0;
  5539. proceedingMessage.destinationInfo.undefinedNode = 0;
  5540. if( m_pFastStart != NULL )
  5541. {
  5542. _ASSERTE( m_pPeerFastStart );
  5543. proceedingMessage.bit_mask |= Alerting_UUIE_fastStart_present;
  5544. proceedingMessage.fastStart =
  5545. (PCallProceeding_UUIE_fastStart)m_pFastStart;
  5546. }
  5547. else
  5548. {
  5549. proceedingMessage.bit_mask &= ~Alerting_UUIE_fastStart_present;
  5550. }
  5551. //copy the call identifier
  5552. proceedingMessage.bit_mask |= CallProceeding_UUIE_callIdentifier_present;
  5553. CopyMemory( (PVOID)&proceedingMessage.callIdentifier.guid.value,
  5554. (PVOID)&m_callIdentifier,
  5555. sizeof(GUID) );
  5556. proceedingMessage.callIdentifier.guid.length = sizeof(GUID);
  5557. rc = EncodeASN( (void *) &UserInfo,
  5558. H323_UserInformation_PDU,
  5559. ppEncodedBuf,
  5560. pdwEncodedLength);
  5561. if (ASN1_FAILED(rc) || (*ppEncodedBuf == NULL) || (pdwEncodedLength == 0) )
  5562. {
  5563. if( pEncodedAPDU != NULL )
  5564. {
  5565. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5566. }
  5567. return FALSE;
  5568. }
  5569. if( pEncodedAPDU != NULL )
  5570. {
  5571. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5572. }
  5573. H323DBG((DEBUG_LEVEL_TRACE, "EncodeProceedingMessage exited: %p.", this ));
  5574. //success
  5575. return TRUE;
  5576. }
  5577. //!!always called in a lock
  5578. BOOL
  5579. CH323Call::EncodeReleaseCompleteMessage(
  5580. IN DWORD dwInvokeID,
  5581. IN BYTE *pbReason,
  5582. OUT BYTE **ppEncodedBuf,
  5583. OUT WORD *pdwEncodedLength,
  5584. IN DWORD dwAPDUType
  5585. )
  5586. {
  5587. H323_UU_PDU_h4501SupplementaryService h4501APDU;
  5588. int rc;
  5589. H323_UserInformation UserInfo;
  5590. DWORD dwAPDULen = 0;
  5591. BYTE* pEncodedAPDU = NULL;
  5592. H323DBG((DEBUG_LEVEL_TRACE, "EncodeReleaseCompleteMessage entered: %p.", this ));
  5593. ReleaseComplete_UUIE & releaseMessage =
  5594. UserInfo.h323_uu_pdu.h323_message_body.u.releaseComplete;
  5595. *ppEncodedBuf = NULL;
  5596. *pdwEncodedLength = 0;
  5597. memset( (PVOID)&UserInfo, 0, sizeof(H323_UserInformation));
  5598. UserInfo.bit_mask = 0;
  5599. // make sure the user_data_present flag is turned off.
  5600. UserInfo.bit_mask &= (~user_data_present);
  5601. UserInfo.h323_uu_pdu.bit_mask = 0;
  5602. if( dwAPDUType != NO_H450_APDU )
  5603. {
  5604. if( !EncodeH450APDU( dwInvokeID, dwAPDUType, &pEncodedAPDU, &dwAPDULen ) )
  5605. {
  5606. return FALSE;
  5607. }
  5608. UserInfo.h323_uu_pdu.h4501SupplementaryService = &h4501APDU;
  5609. UserInfo.h323_uu_pdu.h4501SupplementaryService -> next = NULL;
  5610. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.value = pEncodedAPDU;
  5611. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.length = dwAPDULen;
  5612. UserInfo.h323_uu_pdu.bit_mask |= h4501SupplementaryService_present;
  5613. }
  5614. SetNonStandardData( UserInfo );
  5615. UserInfo.h323_uu_pdu.h323_message_body.choice = releaseComplete_chosen;
  5616. releaseMessage.protocolIdentifier = OID_H225ProtocolIdentifierV2;
  5617. if( pbReason )
  5618. {
  5619. releaseMessage.reason.choice = 0;
  5620. releaseMessage.bit_mask |= (ReleaseComplete_UUIE_reason_present);
  5621. switch (*pbReason)
  5622. {
  5623. case H323_REJECT_NO_BANDWIDTH:
  5624. releaseMessage.reason.choice = noBandwidth_chosen;
  5625. break;
  5626. case H323_REJECT_GATEKEEPER_RESOURCES:
  5627. releaseMessage.reason.choice = gatekeeperResources_chosen;
  5628. break;
  5629. case H323_REJECT_UNREACHABLE_DESTINATION:
  5630. releaseMessage.reason.choice = unreachableDestination_chosen;
  5631. break;
  5632. case H323_REJECT_DESTINATION_REJECTION:
  5633. releaseMessage.reason.choice = destinationRejection_chosen;
  5634. break;
  5635. case H323_REJECT_INVALID_REVISION:
  5636. releaseMessage.reason.choice
  5637. = ReleaseCompleteReason_invalidRevision_chosen;
  5638. break;
  5639. case H323_REJECT_NO_PERMISSION:
  5640. releaseMessage.reason.choice = noPermission_chosen;
  5641. break;
  5642. case H323_REJECT_UNREACHABLE_GATEKEEPER:
  5643. releaseMessage.reason.choice = unreachableGatekeeper_chosen;
  5644. break;
  5645. case H323_REJECT_GATEWAY_RESOURCES:
  5646. releaseMessage.reason.choice = gatewayResources_chosen;
  5647. break;
  5648. case H323_REJECT_BAD_FORMAT_ADDRESS:
  5649. releaseMessage.reason.choice = badFormatAddress_chosen;
  5650. break;
  5651. case H323_REJECT_ADAPTIVE_BUSY:
  5652. releaseMessage.reason.choice = adaptiveBusy_chosen;
  5653. break;
  5654. case H323_REJECT_IN_CONF:
  5655. releaseMessage.reason.choice = inConf_chosen;
  5656. break;
  5657. case H323_REJECT_CALL_DEFLECTION:
  5658. releaseMessage.reason.choice =
  5659. ReleaseCompleteReason_undefinedReason_chosen ;
  5660. break;
  5661. case H323_REJECT_UNDEFINED_REASON:
  5662. releaseMessage.reason.choice = ReleaseCompleteReason_undefinedReason_chosen ;
  5663. break;
  5664. case H323_REJECT_USER_BUSY:
  5665. releaseMessage.reason.choice = inConf_chosen;
  5666. break;
  5667. default:
  5668. //log
  5669. if( pEncodedAPDU != NULL )
  5670. {
  5671. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5672. }
  5673. return FALSE;
  5674. }
  5675. }
  5676. rc = EncodeASN( (void *) &UserInfo,
  5677. H323_UserInformation_PDU,
  5678. ppEncodedBuf,
  5679. pdwEncodedLength);
  5680. if (ASN1_FAILED(rc) || (*ppEncodedBuf == NULL) || (pdwEncodedLength == 0) )
  5681. {
  5682. if( pEncodedAPDU != NULL )
  5683. {
  5684. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5685. }
  5686. return FALSE;
  5687. }
  5688. if( pEncodedAPDU != NULL )
  5689. {
  5690. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5691. }
  5692. H323DBG((DEBUG_LEVEL_TRACE, "EncodeReleaseCompleteMessage exited: %p.", this ));
  5693. //success
  5694. return TRUE;
  5695. }
  5696. //!!always called in a lock
  5697. BOOL
  5698. CH323Call::EncodeConnectMessage(
  5699. IN DWORD dwInvokeID,
  5700. OUT BYTE **ppEncodedBuf,
  5701. OUT WORD *pdwEncodedLength,
  5702. IN DWORD dwAPDUType
  5703. )
  5704. {
  5705. H323_UU_PDU_h4501SupplementaryService h4501APDU;
  5706. int rc;
  5707. H323_UserInformation UserInfo;
  5708. DWORD dwAPDULen = 0;
  5709. BYTE* pEncodedAPDU = NULL;
  5710. H323DBG((DEBUG_LEVEL_TRACE, "EncodeConnectMessage entered: %p.", this ));
  5711. Connect_UUIE & connectMessage =
  5712. UserInfo.h323_uu_pdu.h323_message_body.u.connect;
  5713. *ppEncodedBuf = NULL;
  5714. *pdwEncodedLength = 0;
  5715. memset( (PVOID)&UserInfo, 0, sizeof(H323_UserInformation));
  5716. UserInfo.bit_mask = 0;
  5717. // make sure the user_data_present flag is turned off.
  5718. UserInfo.bit_mask &= (~user_data_present);
  5719. UserInfo.h323_uu_pdu.bit_mask = 0;
  5720. //send the appropriate ADPDUS
  5721. if( dwAPDUType != NO_H450_APDU )
  5722. {
  5723. if( !EncodeH450APDU( dwInvokeID, dwAPDUType,
  5724. &pEncodedAPDU, &dwAPDULen ) )
  5725. {
  5726. return FALSE;
  5727. }
  5728. UserInfo.h323_uu_pdu.h4501SupplementaryService = &h4501APDU;
  5729. UserInfo.h323_uu_pdu.h4501SupplementaryService -> next = NULL;
  5730. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.value = pEncodedAPDU;
  5731. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.length = dwAPDULen;
  5732. UserInfo.h323_uu_pdu.bit_mask |= h4501SupplementaryService_present;
  5733. }
  5734. UserInfo.h323_uu_pdu.h245Tunneling = FALSE;//(m_fh245Tunneling & LOCAL_H245_TUNNELING);
  5735. UserInfo.h323_uu_pdu.bit_mask |= h245Tunneling_present;
  5736. SetNonStandardData( UserInfo );
  5737. UserInfo.h323_uu_pdu.h323_message_body.choice = connect_chosen;
  5738. connectMessage.protocolIdentifier = OID_H225ProtocolIdentifierV2;
  5739. TransportAddress& transportAddress = connectMessage.h245Address;
  5740. CopyTransportAddress( transportAddress, &m_selfH245Addr );
  5741. connectMessage.bit_mask |= (Connect_UUIE_h245Address_present);
  5742. connectMessage.destinationInfo.bit_mask = 0;
  5743. //copy the vendor info
  5744. connectMessage.destinationInfo.bit_mask |= vendor_present;
  5745. CopyVendorInfo( &connectMessage.destinationInfo.vendor );
  5746. //terminal is present
  5747. connectMessage.destinationInfo.bit_mask |= terminal_present;
  5748. connectMessage.destinationInfo.terminal.bit_mask = 0;
  5749. connectMessage.destinationInfo.mc = 0;
  5750. connectMessage.destinationInfo.undefinedNode = 0;
  5751. //copy the 16 byte conference ID
  5752. CopyConferenceID (&connectMessage.conferenceID, &m_ConferenceID);
  5753. if( m_pFastStart != NULL )
  5754. {
  5755. _ASSERTE( m_pPeerFastStart );
  5756. connectMessage.bit_mask |= Connect_UUIE_fastStart_present;
  5757. connectMessage.fastStart = (PConnect_UUIE_fastStart)m_pFastStart;
  5758. }
  5759. else
  5760. {
  5761. connectMessage.bit_mask &= ~Alerting_UUIE_fastStart_present;
  5762. }
  5763. //copy the call identifier
  5764. connectMessage.bit_mask |= Connect_UUIE_callIdentifier_present;
  5765. CopyMemory( (PVOID)&connectMessage.callIdentifier.guid.value,
  5766. (PVOID)&m_callIdentifier,
  5767. sizeof(GUID) );
  5768. connectMessage.callIdentifier.guid.length = sizeof(GUID);
  5769. rc = EncodeASN( (void *) &UserInfo,
  5770. H323_UserInformation_PDU,
  5771. ppEncodedBuf,
  5772. pdwEncodedLength);
  5773. if (ASN1_FAILED(rc) || (*ppEncodedBuf == NULL) || (pdwEncodedLength == 0) )
  5774. {
  5775. if( pEncodedAPDU != NULL )
  5776. {
  5777. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5778. }
  5779. return FALSE;
  5780. }
  5781. if( pEncodedAPDU != NULL )
  5782. {
  5783. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5784. }
  5785. H323DBG((DEBUG_LEVEL_TRACE, "EncodeConnectMessage exited: %p.", this ));
  5786. //success
  5787. return TRUE;
  5788. }
  5789. //!!always called in a lock
  5790. void CH323Call::SetNonStandardData(
  5791. OUT H323_UserInformation & UserInfo
  5792. )
  5793. {
  5794. if( m_NonStandardData.sData.pOctetString )
  5795. {
  5796. H221NonStandard & nonStd =
  5797. UserInfo.h323_uu_pdu.nonStandardData.nonStandardIdentifier.u.h221NonStandard;
  5798. UserInfo.h323_uu_pdu.bit_mask |= H323_UU_PDU_nonStandardData_present;
  5799. UserInfo.h323_uu_pdu.nonStandardData.nonStandardIdentifier.choice
  5800. = H225NonStandardIdentifier_h221NonStandard_chosen;
  5801. nonStd.t35CountryCode = m_NonStandardData.bCountryCode;
  5802. nonStd.t35Extension = m_NonStandardData.bExtension;
  5803. nonStd.manufacturerCode = m_NonStandardData.wManufacturerCode;
  5804. UserInfo.h323_uu_pdu.nonStandardData.data.length =
  5805. m_NonStandardData.sData.wOctetStringLength;
  5806. UserInfo.h323_uu_pdu.nonStandardData.data.value =
  5807. m_NonStandardData.sData.pOctetString;
  5808. // Maintain only one reference to the buffer.
  5809. m_NonStandardData.sData.pOctetString = NULL;
  5810. }
  5811. else
  5812. {
  5813. UserInfo.h323_uu_pdu.bit_mask &= (~H323_UU_PDU_nonStandardData_present);
  5814. }
  5815. }
  5816. //!!always called in a lock
  5817. BOOL
  5818. CH323Call::EncodeSetupMessage(
  5819. IN DWORD dwInvokeID,
  5820. IN WORD wGoal,
  5821. IN WORD wCallType,
  5822. OUT BYTE **ppEncodedBuf,
  5823. OUT WORD *pdwEncodedLength,
  5824. IN DWORD dwAPDUType
  5825. )
  5826. {
  5827. H323_UU_PDU_h4501SupplementaryService h4501APDU;
  5828. H323_UserInformation UserInfo;
  5829. int rc = 0;
  5830. BOOL retVal = TRUE;
  5831. DWORD dwAPDULen = 0;
  5832. BYTE* pEncodedAPDU = NULL;
  5833. *ppEncodedBuf = NULL;
  5834. *pdwEncodedLength = 0;
  5835. H323DBG((DEBUG_LEVEL_TRACE, "EncodeSetupMessage entered: %p.", this ));
  5836. Setup_UUIE & setupMessage = UserInfo.h323_uu_pdu.h323_message_body.u.setup;
  5837. TransportAddress& calleeAddr = setupMessage.destCallSignalAddress;
  5838. TransportAddress& callerAddr = setupMessage.sourceCallSignalAddress;
  5839. memset( (PVOID)&UserInfo, 0, sizeof(H323_UserInformation));
  5840. UserInfo.bit_mask = 0;
  5841. // make sure the user_data_present flag is turned off.
  5842. UserInfo.bit_mask &= (~user_data_present);
  5843. UserInfo.h323_uu_pdu.bit_mask = 0;
  5844. //send the appropriate ADPDUS
  5845. if( dwAPDUType != NO_H450_APDU )
  5846. {
  5847. if( !EncodeH450APDU( dwInvokeID, dwAPDUType, &pEncodedAPDU, &dwAPDULen ) )
  5848. {
  5849. return FALSE;
  5850. }
  5851. UserInfo.h323_uu_pdu.h4501SupplementaryService = &h4501APDU;
  5852. UserInfo.h323_uu_pdu.h4501SupplementaryService -> next = NULL;
  5853. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.value = pEncodedAPDU;
  5854. UserInfo.h323_uu_pdu.h4501SupplementaryService -> value.length = dwAPDULen;
  5855. UserInfo.h323_uu_pdu.bit_mask |= h4501SupplementaryService_present;
  5856. }
  5857. UserInfo.h323_uu_pdu.h245Tunneling = FALSE;//(m_fh245Tunneling & LOCAL_H245_TUNNELING);
  5858. UserInfo.h323_uu_pdu.bit_mask |= h245Tunneling_present;
  5859. SetNonStandardData( UserInfo );
  5860. UserInfo.h323_uu_pdu.h323_message_body.choice = setup_chosen;
  5861. setupMessage.bit_mask = 0;
  5862. setupMessage.protocolIdentifier = OID_H225ProtocolIdentifierV2;
  5863. if( m_pCallerAliasNames && m_pCallerAliasNames -> wCount )
  5864. {
  5865. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  5866. setupMessage.sourceAddress = SetMsgAddressAlias(m_pCallerAliasNames);
  5867. if( setupMessage.sourceAddress != NULL )
  5868. {
  5869. setupMessage.bit_mask |= (sourceAddress_present);
  5870. }
  5871. else
  5872. {
  5873. setupMessage.bit_mask &= (~sourceAddress_present);
  5874. }
  5875. }
  5876. else
  5877. {
  5878. setupMessage.bit_mask &= (~sourceAddress_present);
  5879. }
  5880. setupMessage.sourceInfo.bit_mask = 0;
  5881. //pass the vendor info
  5882. setupMessage.sourceInfo.bit_mask |= vendor_present;
  5883. CopyVendorInfo( &setupMessage.sourceInfo.vendor );
  5884. //terminal is present
  5885. setupMessage.sourceInfo.bit_mask |= terminal_present;
  5886. setupMessage.sourceInfo.terminal.bit_mask = 0;
  5887. //not an MC
  5888. setupMessage.sourceInfo.mc = FALSE;
  5889. setupMessage.sourceInfo.undefinedNode = 0;
  5890. if( m_pCalleeAliasNames && m_pCalleeAliasNames -> wCount )
  5891. {
  5892. setupMessage.destinationAddress = (PSetup_UUIE_destinationAddress)
  5893. SetMsgAddressAlias( m_pCalleeAliasNames );
  5894. if( setupMessage.destinationAddress != NULL )
  5895. {
  5896. setupMessage.bit_mask |= (destinationAddress_present);
  5897. }
  5898. else
  5899. {
  5900. setupMessage.bit_mask &= (~destinationAddress_present);
  5901. }
  5902. }
  5903. else
  5904. {
  5905. setupMessage.bit_mask &= (~destinationAddress_present);
  5906. }
  5907. //extra alias not present
  5908. setupMessage.bit_mask &= (~Setup_UUIE_destExtraCallInfo_present );
  5909. //If talking to gateway then don't pass on destn call signal address
  5910. if( m_dwAddressType != LINEADDRESSTYPE_PHONENUMBER )
  5911. {
  5912. CopyTransportAddress( calleeAddr, &m_CalleeAddr );
  5913. setupMessage.bit_mask |= Setup_UUIE_destCallSignalAddress_present;
  5914. }
  5915. //not an MC
  5916. setupMessage.activeMC = m_fActiveMC;
  5917. //copy the 16 byte conference ID
  5918. CopyConferenceID (&setupMessage.conferenceID, &m_ConferenceID);
  5919. //copy the call identifier
  5920. setupMessage.bit_mask |= Setup_UUIE_callIdentifier_present;
  5921. CopyConferenceID (&setupMessage.callIdentifier.guid, &m_callIdentifier);
  5922. //fast start params
  5923. if( m_pFastStart != NULL )
  5924. {
  5925. setupMessage.bit_mask |= Setup_UUIE_fastStart_present;
  5926. setupMessage.fastStart = (PSetup_UUIE_fastStart)m_pFastStart;
  5927. }
  5928. else
  5929. {
  5930. setupMessage.bit_mask &= ~Setup_UUIE_fastStart_present;
  5931. }
  5932. //copy media wait for connect
  5933. setupMessage.mediaWaitForConnect = FALSE;
  5934. setupMessage.conferenceGoal.choice = (BYTE)wGoal;
  5935. setupMessage.callType.choice = (BYTE)wCallType;
  5936. CopyTransportAddress( callerAddr, &m_CallerAddr );
  5937. setupMessage.bit_mask |= sourceCallSignalAddress_present;
  5938. //no extension alias
  5939. setupMessage.bit_mask &= (~Setup_UUIE_remoteExtensionAddress_present);
  5940. rc = EncodeASN( (void *) &UserInfo,
  5941. H323_UserInformation_PDU,
  5942. ppEncodedBuf,
  5943. pdwEncodedLength);
  5944. if( ASN1_FAILED(rc) || (*ppEncodedBuf == NULL) || (pdwEncodedLength == 0) )
  5945. {
  5946. if( pEncodedAPDU != NULL )
  5947. {
  5948. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5949. }
  5950. retVal = FALSE;
  5951. }
  5952. // Free the alias name structures from the UserInfo area.
  5953. if( setupMessage.bit_mask & sourceAddress_present )
  5954. {
  5955. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  5956. setupMessage.sourceAddress );
  5957. }
  5958. if( setupMessage.bit_mask & destinationAddress_present )
  5959. {
  5960. FreeAddressAliases( setupMessage.destinationAddress );
  5961. }
  5962. if( pEncodedAPDU != NULL )
  5963. {
  5964. ASN1_FreeEncoded(m_H450ASNCoderInfo.pEncInfo, pEncodedAPDU );
  5965. }
  5966. H323DBG((DEBUG_LEVEL_TRACE, "EncodeSetupMessage exited: %p.", this ));
  5967. //success/failure
  5968. return retVal;
  5969. }
  5970. //!!always called in a lock
  5971. BOOL
  5972. CH323Call::EncodeH450APDU(
  5973. IN DWORD dwInvokeID,
  5974. IN DWORD dwAPDUType,
  5975. OUT BYTE** ppEncodedAPDU,
  5976. OUT DWORD* pdwAPDULen
  5977. )
  5978. {
  5979. H4501SupplementaryService SupplementaryServiceAPDU;
  5980. ServiceApdus_rosApdus rosAPDU;
  5981. DWORD dwErrorCode = 0;
  5982. DWORD dwOperationType = (dwAPDUType & 0x0000FF00);
  5983. dwAPDUType &= 0x000000FF;
  5984. H323DBG((DEBUG_LEVEL_TRACE, "EncodeH450APDU entered: %p.", this ));
  5985. ZeroMemory( (PVOID)&SupplementaryServiceAPDU,
  5986. sizeof(H4501SupplementaryService) );
  5987. //interpretationAPDU
  5988. SupplementaryServiceAPDU.interpretationApdu.choice =
  5989. rejectAnyUnrecognizedInvokePdu_chosen;
  5990. SupplementaryServiceAPDU.bit_mask |= interpretationApdu_present;
  5991. //NFE
  5992. SupplementaryServiceAPDU.networkFacilityExtension.bit_mask = 0;
  5993. SupplementaryServiceAPDU.networkFacilityExtension.destinationEntity.choice
  5994. = endpoint_chosen;
  5995. SupplementaryServiceAPDU.networkFacilityExtension.sourceEntity.choice
  5996. = endpoint_chosen;
  5997. SupplementaryServiceAPDU.bit_mask |= networkFacilityExtension_present;
  5998. //serviceAPDUS
  5999. SupplementaryServiceAPDU.serviceApdu.choice = rosApdus_chosen;
  6000. SupplementaryServiceAPDU.serviceApdu.u.rosApdus = &rosAPDU;
  6001. SupplementaryServiceAPDU.serviceApdu.u.rosApdus->next = NULL;
  6002. if( dwOperationType == H450_REJECT )
  6003. {
  6004. if( !EncodeRejectAPDU( &SupplementaryServiceAPDU, dwInvokeID,
  6005. ppEncodedAPDU, pdwAPDULen ) )
  6006. {
  6007. return FALSE;
  6008. }
  6009. }
  6010. else if( dwOperationType == H450_RETURNERROR )
  6011. {
  6012. EncodeReturnErrorAPDU( dwInvokeID, dwErrorCode,
  6013. &SupplementaryServiceAPDU, ppEncodedAPDU, pdwAPDULen );
  6014. }
  6015. else if( dwOperationType == H450_RETURNRESULT )
  6016. {
  6017. if( !EncodeDummyReturnResultAPDU( dwInvokeID,
  6018. dwAPDUType, &SupplementaryServiceAPDU,
  6019. ppEncodedAPDU, pdwAPDULen ) )
  6020. {
  6021. return FALSE;
  6022. }
  6023. }
  6024. else //H450_INVOKE
  6025. {
  6026. switch( dwAPDUType )
  6027. {
  6028. case CHECKRESTRICTION_OPCODE:
  6029. if( !EncodeCheckRestrictionAPDU( &SupplementaryServiceAPDU,
  6030. ppEncodedAPDU, pdwAPDULen ) )
  6031. {
  6032. return FALSE;
  6033. }
  6034. break;
  6035. case CALLREROUTING_OPCODE:
  6036. if( !EncodeCallReroutingAPDU( &SupplementaryServiceAPDU,
  6037. ppEncodedAPDU, pdwAPDULen ) )
  6038. {
  6039. return FALSE;
  6040. }
  6041. break;
  6042. case DIVERTINGLEGINFO2_OPCODE:
  6043. if( !EncodeDivertingLeg2APDU( &SupplementaryServiceAPDU,
  6044. ppEncodedAPDU, pdwAPDULen ) )
  6045. {
  6046. return FALSE;
  6047. }
  6048. break;
  6049. case DIVERTINGLEGINFO3_OPCODE:
  6050. if( !EncodeDivertingLeg3APDU( &SupplementaryServiceAPDU,
  6051. ppEncodedAPDU, pdwAPDULen ) )
  6052. {
  6053. return FALSE;
  6054. }
  6055. break;
  6056. case HOLDNOTIFIC_OPCODE:
  6057. case REMOTEHOLD_OPCODE:
  6058. case RETRIEVENOTIFIC_OPCODE:
  6059. case REMOTERETRIEVE_OPCODE:
  6060. case CTIDENTIFY_OPCODE:
  6061. if( !EncodeH450APDUNoArgument( dwAPDUType, &SupplementaryServiceAPDU,
  6062. ppEncodedAPDU, pdwAPDULen ) )
  6063. {
  6064. return FALSE;
  6065. }
  6066. break;
  6067. case CTSETUP_OPCODE:
  6068. if( !EncodeCTSetupAPDU( &SupplementaryServiceAPDU,
  6069. ppEncodedAPDU, pdwAPDULen ) )
  6070. {
  6071. return FALSE;
  6072. }
  6073. break;
  6074. case CTINITIATE_OPCODE:
  6075. if( !EncodeCTInitiateAPDU( &SupplementaryServiceAPDU,
  6076. ppEncodedAPDU, pdwAPDULen ) )
  6077. {
  6078. return FALSE;
  6079. }
  6080. break;
  6081. default:
  6082. _ASSERTE( 0 );
  6083. return FALSE;
  6084. }
  6085. }
  6086. H323DBG((DEBUG_LEVEL_TRACE, "EncodeH450APDU exited: %p.", this ));
  6087. return TRUE;
  6088. }
  6089. //!!always called in a lock
  6090. BOOL
  6091. CH323Call::EncodePDU(
  6092. IN BINARY_STRING *pUserUserData,
  6093. OUT BYTE ** ppbCodedBuffer,
  6094. OUT DWORD * pdwCodedBufferLength,
  6095. IN DWORD dwMessageType,
  6096. WCHAR * pwszCalledPartyNumber
  6097. )
  6098. {
  6099. PQ931MESSAGE pMessage;
  6100. BYTE bBandwidth;
  6101. char pszDisplay[131] = "";
  6102. DWORD dwMessageLength = 0;
  6103. BYTE indexI;
  6104. BOOL retVal;
  6105. H323DBG(( DEBUG_LEVEL_TRACE, "EncodePDU entered: %p.", this ));
  6106. pMessage = new Q931MESSAGE;
  6107. if( pMessage == NULL )
  6108. {
  6109. return FALSE;
  6110. }
  6111. // fill in the required fields for the Q931 message.
  6112. memset( (PVOID)pMessage, 0, sizeof(Q931MESSAGE));
  6113. pMessage->ProtocolDiscriminator = Q931PDVALUE;
  6114. pMessage->wCallRef = m_wQ931CallRef;
  6115. pMessage->MessageType = (BYTE)dwMessageType;
  6116. dwMessageLength +=
  6117. ( 1 + sizeof(PDTYPE) + sizeof(CRTYPE) + sizeof(MESSAGEIDTYPE) );
  6118. if( (dwMessageType == SETUPMESSAGETYPE) ||
  6119. (dwMessageType == CONNECTMESSAGETYPE) )
  6120. {
  6121. if( m_pwszDisplay &&
  6122. WideCharToMultiByte(CP_ACP,
  6123. 0,
  6124. m_pwszDisplay,
  6125. -1,
  6126. pszDisplay,
  6127. sizeof(pszDisplay),
  6128. NULL,
  6129. NULL) == 0)
  6130. {
  6131. delete pMessage;
  6132. return FALSE;
  6133. }
  6134. if( *pszDisplay )
  6135. {
  6136. pMessage->Display.fPresent = TRUE;
  6137. pMessage->Display.dwLength = (BYTE)(strlen(pszDisplay) + 1);
  6138. strcpy((char *)pMessage->Display.pbContents, pszDisplay);
  6139. dwMessageLength += (2 + pMessage->Display.dwLength);
  6140. }
  6141. pMessage->BearerCapability.fPresent = TRUE;
  6142. pMessage->BearerCapability.dwLength = 3;
  6143. pMessage->BearerCapability.pbContents[0] =
  6144. (BYTE)(BEAR_EXT_BIT | BEAR_CCITT | BEAR_UNRESTRICTED_DIGITAL);
  6145. pMessage->BearerCapability.pbContents[1] =
  6146. (BYTE)(BEAR_EXT_BIT | 0x17); //64kbps
  6147. pMessage->BearerCapability.pbContents[2] = (BYTE)
  6148. (BEAR_EXT_BIT | BEAR_LAYER1_INDICATOR | BEAR_LAYER1_H221_H242);
  6149. dwMessageLength += (2+pMessage->BearerCapability.dwLength);
  6150. }
  6151. //if talking to gateway encode the called party number
  6152. if( m_dwAddressType == LINEADDRESSTYPE_PHONENUMBER )
  6153. {
  6154. BYTE bLen = (BYTE)(wcslen(pwszCalledPartyNumber)+1);
  6155. pMessage->CalledPartyNumber.fPresent = TRUE;
  6156. pMessage->CalledPartyNumber.NumberType =
  6157. (BYTE)(CALLED_PARTY_EXT_BIT | CALLED_PARTY_TYPE_UNKNOWN);
  6158. pMessage->CalledPartyNumber.NumberingPlan =
  6159. (BYTE)(CALLED_PARTY_PLAN_E164);
  6160. pMessage->CalledPartyNumber.PartyNumberLength = bLen;
  6161. for( indexI =0; indexI < bLen; indexI++ )
  6162. {
  6163. pMessage->CalledPartyNumber.PartyNumbers[indexI] =
  6164. (BYTE)pwszCalledPartyNumber[indexI];
  6165. }
  6166. dwMessageLength += (2 + pMessage->CalledPartyNumber.PartyNumberLength);
  6167. }
  6168. if( dwMessageType == FACILITYMESSAGETYPE )
  6169. {
  6170. // The facility ie is encoded as present, but empty...
  6171. pMessage->Facility.fPresent = TRUE;
  6172. pMessage->Facility.dwLength = 0;
  6173. pMessage->Facility.pbContents[0] = 0;
  6174. dwMessageLength += (2 + pMessage->Facility.dwLength);
  6175. }
  6176. if (pUserUserData && pUserUserData->pbBuffer)
  6177. {
  6178. if (pUserUserData->length > sizeof(pMessage->UserToUser.pbUserInfo))
  6179. {
  6180. delete pMessage;
  6181. return FALSE;
  6182. }
  6183. pMessage->UserToUser.fPresent = TRUE;
  6184. pMessage->UserToUser.wUserInfoLen = pUserUserData->length;
  6185. //This CopyMemory should be avoided
  6186. //may be we should do:pMessage->UserToUser.pbUserInfo = pUserUserData->pbBuffer;
  6187. //change the definition of pMessage->UserToUser.pbUserInfo to BYTE* from BYTE[0x1000]
  6188. CopyMemory( (PVOID)pMessage->UserToUser.pbUserInfo,
  6189. (PVOID)pUserUserData->pbBuffer, pUserUserData->length );
  6190. dwMessageLength += (4+pMessage->UserToUser.wUserInfoLen);
  6191. }
  6192. _ASSERTE( dwMessageLength );
  6193. retVal = EncodeMessage( pMessage, ppbCodedBuffer,
  6194. pdwCodedBufferLength, dwMessageLength );
  6195. delete pMessage;
  6196. return retVal;
  6197. }
  6198. //!!always called in a lock
  6199. BOOL
  6200. CH323Call::EncodeMessage(
  6201. IN PQ931MESSAGE pMessage,
  6202. OUT BYTE **ppbCodedMessage,
  6203. OUT DWORD *pdwCodedMessageLength,
  6204. IN DWORD dwMessageLength
  6205. )
  6206. {
  6207. BUFFERDESCR pBuf;
  6208. DWORD dwPDULen = 0;
  6209. H323DBG((DEBUG_LEVEL_TRACE, "EncodeMessage entered: %p.", this ));
  6210. *ppbCodedMessage = (BYTE *)new char[ dwMessageLength + 100 ];
  6211. if( *ppbCodedMessage == NULL )
  6212. {
  6213. return FALSE;
  6214. }
  6215. pBuf.dwLength = dwMessageLength + 100;
  6216. pBuf.pbBuffer = *ppbCodedMessage + TPKT_HEADER_SIZE;
  6217. WriteQ931Fields(&pBuf, pMessage, &dwPDULen );
  6218. _ASSERTE( dwPDULen == dwMessageLength );
  6219. SetupTPKTHeader( *ppbCodedMessage , dwPDULen );
  6220. *pdwCodedMessageLength = dwPDULen + 4;
  6221. H323DBG((DEBUG_LEVEL_TRACE, "EncodeMessage exited: %p.", this ));
  6222. return TRUE;
  6223. }
  6224. //!!always called in a lock
  6225. void
  6226. CH323Call::WriteQ931Fields(
  6227. IN PBUFFERDESCR pBuf,
  6228. IN PQ931MESSAGE pMessage,
  6229. OUT DWORD * pdwPDULen
  6230. )
  6231. {
  6232. H323DBG((DEBUG_LEVEL_TRACE, "WriteQ931Fields entered: %p.", this ));
  6233. // write the required information elements...
  6234. WriteProtocolDiscriminator( pBuf, pdwPDULen );
  6235. WriteCallReference( pBuf, &pMessage->wCallRef,
  6236. pdwPDULen );
  6237. WriteMessageType(pBuf, &pMessage->MessageType,
  6238. pdwPDULen);
  6239. // try to write all other information elements...
  6240. // don't write this message.
  6241. if (pMessage->Facility.fPresent)
  6242. {
  6243. WriteVariableOctet(pBuf, IDENT_FACILITY,
  6244. pMessage->Facility.dwLength,
  6245. pMessage->Facility.pbContents,
  6246. pdwPDULen);
  6247. }
  6248. if( pMessage->BearerCapability.fPresent
  6249. && pMessage->BearerCapability.dwLength )
  6250. {
  6251. WriteVariableOctet(pBuf, IDENT_BEARERCAP,
  6252. pMessage->BearerCapability.dwLength,
  6253. pMessage->BearerCapability.pbContents,
  6254. pdwPDULen);
  6255. }
  6256. if (pMessage->Display.fPresent && pMessage->Display.dwLength)
  6257. {
  6258. WriteVariableOctet(pBuf, IDENT_DISPLAY,
  6259. pMessage->Display.dwLength,
  6260. pMessage->Display.pbContents,
  6261. pdwPDULen);
  6262. }
  6263. if( pMessage->CalledPartyNumber.fPresent )
  6264. {
  6265. WritePartyNumber(pBuf,
  6266. IDENT_CALLEDNUMBER,
  6267. pMessage->CalledPartyNumber.NumberType,
  6268. pMessage->CalledPartyNumber.NumberingPlan,
  6269. pMessage->CalledPartyNumber.PartyNumberLength,
  6270. pMessage->CalledPartyNumber.PartyNumbers,
  6271. pdwPDULen);
  6272. }
  6273. if( pMessage->UserToUser.fPresent &&
  6274. pMessage->UserToUser.wUserInfoLen )
  6275. {
  6276. WriteUserInformation(pBuf,
  6277. IDENT_USERUSER,
  6278. pMessage->UserToUser.wUserInfoLen,
  6279. pMessage->UserToUser.pbUserInfo,
  6280. pdwPDULen);
  6281. }
  6282. H323DBG((DEBUG_LEVEL_TRACE, "WriteQ931Fields exited: %p.", this ));
  6283. }
  6284. //!!always calld in a lock
  6285. void
  6286. CH323Call::HandleTransportEvent(void)
  6287. {
  6288. WSANETWORKEVENTS networkEvents;
  6289. int iError;
  6290. H323DBG(( DEBUG_LEVEL_TRACE, "HandleTransportEvent entered: %p.", this ));
  6291. if( (m_callSocket == INVALID_SOCKET) &&
  6292. (m_dwCallType == CALLTYPE_DIVERTEDSRC) )
  6293. {
  6294. H323DBG(( DEBUG_LEVEL_TRACE, "The diverted call is not initialized yet."
  6295. "This is probably an event for the primary call. Ignore it %p.",
  6296. this ));
  6297. return;
  6298. }
  6299. //find out the event that took place
  6300. if(WSAEnumNetworkEvents(m_callSocket,
  6301. m_hTransport,
  6302. &networkEvents ) == SOCKET_ERROR )
  6303. {
  6304. H323DBG((DEBUG_LEVEL_TRACE, "WSAEnumNetworkEvents error:%d, %lx, %p.",
  6305. WSAGetLastError(), m_callSocket, this ));
  6306. return;
  6307. }
  6308. if( networkEvents.lNetworkEvents & FD_CLOSE )
  6309. {
  6310. H323DBG((DEBUG_LEVEL_TRACE, "socket close event: %p.", this ));
  6311. //if the call is in transition then don't close the call when the
  6312. //old socket gets closed
  6313. if( m_fCallInTrnasition == TRUE )
  6314. {
  6315. //the call is noot in transition mode anymore
  6316. m_fCallInTrnasition = FALSE;
  6317. return;
  6318. }
  6319. //convey the Q931 close status to the TAPI call object
  6320. //and the tapisrv
  6321. iError = networkEvents.iErrorCode[FD_CLOSE_BIT];
  6322. SetQ931CallState( Q931_CALL_DISCONNECTED );
  6323. //clean up the Q931 call
  6324. CloseCall( 0 );
  6325. return;
  6326. }
  6327. //This can occur only for outbound calls
  6328. if( (networkEvents.lNetworkEvents) & FD_CONNECT )
  6329. {
  6330. H323DBG((DEBUG_LEVEL_TRACE, "socket connect event: %p.", this ));
  6331. //FD_CONNECT event received
  6332. //This func is called by the callback thread when m_hEventQ931Conn is
  6333. //signalled. This function takes care of the outgoing Q931 calls only
  6334. //call the member function
  6335. iError = networkEvents.iErrorCode[FD_CONNECT_BIT];
  6336. if(iError != ERROR_SUCCESS)
  6337. {
  6338. if( (m_dwCallType & CALLTYPE_FORWARDCONSULT )&&
  6339. (m_dwOrigin == LINECALLORIGIN_OUTBOUND ) )
  6340. {
  6341. //Success of forwarding
  6342. EnableCallForwarding();
  6343. }
  6344. H323DBG((DEBUG_LEVEL_ERROR, "FD_CONNECT returned error: %d.",
  6345. iError ));
  6346. CloseCall( 0 );
  6347. return;
  6348. }
  6349. OnConnectComplete();
  6350. }
  6351. H323DBG((DEBUG_LEVEL_TRACE, "HandleTransportEvent exited: %p.", this ));
  6352. }
  6353. //!!always called in a lock
  6354. int
  6355. CH323Call::InitASNCoder(void)
  6356. {
  6357. int rc;
  6358. H323DBG((DEBUG_LEVEL_TRACE, "InitASNCoder entered: %p.", this ));
  6359. memset((PVOID)&m_ASNCoderInfo, 0, sizeof(m_ASNCoderInfo));
  6360. if( H225ASN_Module == NULL)
  6361. {
  6362. return ASN1_ERR_BADARGS;
  6363. }
  6364. rc = ASN1_CreateEncoder(
  6365. H225ASN_Module, // ptr to mdule
  6366. &(m_ASNCoderInfo.pEncInfo), // ptr to encoder info
  6367. NULL, // buffer ptr
  6368. 0, // buffer size
  6369. NULL); // parent ptr
  6370. if (rc == ASN1_SUCCESS)
  6371. {
  6372. _ASSERTE(m_ASNCoderInfo.pEncInfo );
  6373. rc = ASN1_CreateDecoder(
  6374. H225ASN_Module, // ptr to mdule
  6375. &(m_ASNCoderInfo.pDecInfo), // ptr to decoder info
  6376. NULL, // buffer ptr
  6377. 0, // buffer size
  6378. NULL); // parent ptr
  6379. _ASSERTE(m_ASNCoderInfo.pDecInfo );
  6380. }
  6381. if (rc != ASN1_SUCCESS)
  6382. {
  6383. TermASNCoder();
  6384. }
  6385. H323DBG((DEBUG_LEVEL_TRACE, "InitASNCoder exited: %p.", this ));
  6386. return rc;
  6387. }
  6388. //!!always called in a lock
  6389. int
  6390. CH323Call::TermASNCoder(void)
  6391. {
  6392. if( H225ASN_Module == NULL )
  6393. {
  6394. return ASN1_ERR_BADARGS;
  6395. }
  6396. ASN1_CloseEncoder(m_ASNCoderInfo.pEncInfo);
  6397. ASN1_CloseDecoder(m_ASNCoderInfo.pDecInfo);
  6398. memset( (PVOID)&m_ASNCoderInfo, 0, sizeof(m_ASNCoderInfo));
  6399. return ASN1_SUCCESS;
  6400. }
  6401. //!!always called in a lock
  6402. int
  6403. CH323Call::EncodeASN(
  6404. IN void * pStruct,
  6405. IN int nPDU,
  6406. OUT BYTE ** ppEncoded,
  6407. OUT WORD * pcbEncodedSize
  6408. )
  6409. {
  6410. H323DBG((DEBUG_LEVEL_TRACE, "EncodeASN entered: %p.", this ));
  6411. ASN1encoding_t pEncInfo = m_ASNCoderInfo.pEncInfo;
  6412. int rc = ASN1_Encode(
  6413. pEncInfo, // ptr to encoder info
  6414. pStruct, // pdu data structure
  6415. nPDU, // pdu id
  6416. ASN1ENCODE_ALLOCATEBUFFER, // flags
  6417. NULL, // do not provide buffer
  6418. 0); // buffer size if provided
  6419. if (ASN1_SUCCEEDED(rc))
  6420. {
  6421. if( rc != ASN1_SUCCESS )
  6422. {
  6423. H323DBG((DEBUG_LEVEL_TRACE, "warning while encoding ASN:%d.", rc ));
  6424. }
  6425. *pcbEncodedSize = (WORD)pEncInfo->len; // len of encoded data in buffer
  6426. *ppEncoded = pEncInfo->buf; // buffer to encode into
  6427. }
  6428. else
  6429. {
  6430. H323DBG((DEBUG_LEVEL_TRACE, "error while encoding ASN:%d.", rc ));
  6431. *pcbEncodedSize = 0;
  6432. *ppEncoded = NULL;
  6433. }
  6434. H323DBG((DEBUG_LEVEL_TRACE, "EncodeASN exited: %p.", this ));
  6435. return rc;
  6436. }
  6437. //!!always called in a lock
  6438. int
  6439. CH323Call::DecodeASN(
  6440. OUT void ** ppStruct,
  6441. IN int nPDU,
  6442. IN BYTE * pEncoded,
  6443. IN DWORD cbEncodedSize
  6444. )
  6445. {
  6446. H323DBG((DEBUG_LEVEL_TRACE, "h323call DecodeASN entered: %p.", this ));
  6447. ASN1decoding_t pDecInfo = m_ASNCoderInfo.pDecInfo;
  6448. int rc = ASN1_Decode(
  6449. pDecInfo, // ptr to encoder info
  6450. ppStruct, // pdu data structure
  6451. nPDU, // pdu id
  6452. ASN1DECODE_SETBUFFER, // flags
  6453. pEncoded, // do not provide buffer
  6454. cbEncodedSize); // buffer size if provided
  6455. if (ASN1_SUCCEEDED(rc))
  6456. {
  6457. if( rc != ASN1_SUCCESS )
  6458. {
  6459. H323DBG((DEBUG_LEVEL_TRACE, "warning while deciding ASN:%d.", rc ));
  6460. }
  6461. }
  6462. else
  6463. {
  6464. H323DBG((DEBUG_LEVEL_TRACE, "error while deciding ASN:%d.", rc ));
  6465. H323DUMPBUFFER( (BYTE*)pEncoded, cbEncodedSize);
  6466. *ppStruct = NULL;
  6467. }
  6468. H323DBG((DEBUG_LEVEL_TRACE, "h323call DecodeASN exited: %p.", this ));
  6469. return rc;
  6470. }
  6471. //!!always called in a lock
  6472. int
  6473. CH323Call::InitH450ASNCoder(void)
  6474. {
  6475. int rc;
  6476. H323DBG((DEBUG_LEVEL_TRACE, "InitH450ASNCoder entered: %p.", this ));
  6477. memset((PVOID)&m_H450ASNCoderInfo, 0, sizeof(m_H450ASNCoderInfo));
  6478. if( H4503PP_Module == NULL)
  6479. {
  6480. return ASN1_ERR_BADARGS;
  6481. }
  6482. rc = ASN1_CreateEncoder(
  6483. H4503PP_Module, // ptr to mdule
  6484. &(m_H450ASNCoderInfo.pEncInfo), // ptr to encoder info
  6485. NULL, // buffer ptr
  6486. 0, // buffer size
  6487. NULL); // parent ptr
  6488. if (rc == ASN1_SUCCESS)
  6489. {
  6490. _ASSERTE(m_H450ASNCoderInfo.pEncInfo );
  6491. rc = ASN1_CreateDecoder(
  6492. H4503PP_Module, // ptr to mdule
  6493. &(m_H450ASNCoderInfo.pDecInfo), // ptr to decoder info
  6494. NULL, // buffer ptr
  6495. 0, // buffer size
  6496. NULL ); // parent ptr
  6497. _ASSERTE( m_H450ASNCoderInfo.pDecInfo );
  6498. }
  6499. if (rc != ASN1_SUCCESS)
  6500. {
  6501. TermH450ASNCoder();
  6502. }
  6503. H323DBG((DEBUG_LEVEL_TRACE, "InitH450ASNCoder exited: %p.", this ));
  6504. return rc;
  6505. }
  6506. //!!always called in a lock
  6507. int
  6508. CH323Call::TermH450ASNCoder(void)
  6509. {
  6510. if( H4503PP_Module == NULL )
  6511. {
  6512. return ASN1_ERR_BADARGS;
  6513. }
  6514. ASN1_CloseEncoder(m_H450ASNCoderInfo.pEncInfo);
  6515. ASN1_CloseDecoder(m_H450ASNCoderInfo.pDecInfo);
  6516. memset( (PVOID)&m_H450ASNCoderInfo, 0, sizeof(m_ASNCoderInfo));
  6517. return ASN1_SUCCESS;
  6518. }
  6519. //!!always called in a lock
  6520. int
  6521. CH323Call::EncodeH450ASN(
  6522. IN void * pStruct,
  6523. IN int nPDU,
  6524. OUT BYTE ** ppEncoded,
  6525. OUT WORD * pcbEncodedSize
  6526. )
  6527. {
  6528. H323DBG((DEBUG_LEVEL_TRACE, "EncodeH450ASN entered: %p.", this ));
  6529. ASN1encoding_t pEncInfo = m_H450ASNCoderInfo.pEncInfo;
  6530. int rc = ASN1_Encode(
  6531. pEncInfo, // ptr to encoder info
  6532. pStruct, // pdu data structure
  6533. nPDU, // pdu id
  6534. ASN1ENCODE_ALLOCATEBUFFER, // flags
  6535. NULL, // do not provide buffer
  6536. 0); // buffer size if provided
  6537. if (ASN1_SUCCEEDED(rc))
  6538. {
  6539. if( rc != ASN1_SUCCESS )
  6540. {
  6541. H323DBG((DEBUG_LEVEL_TRACE, "warning while encoding ASN:%d.", rc ));
  6542. }
  6543. *pcbEncodedSize = (WORD)pEncInfo->len; // len of encoded data in buffer
  6544. *ppEncoded = pEncInfo->buf; // buffer to encode into
  6545. }
  6546. else
  6547. {
  6548. H323DBG((DEBUG_LEVEL_TRACE, "error while encoding ASN:%d.", rc ));
  6549. *pcbEncodedSize = 0;
  6550. *ppEncoded = NULL;
  6551. }
  6552. H323DBG((DEBUG_LEVEL_TRACE, "EncodeH450ASN exited: %p.", this ));
  6553. return rc;
  6554. }
  6555. //!!always called in a lock
  6556. int
  6557. CH323Call::DecodeH450ASN(
  6558. OUT void ** ppStruct,
  6559. IN int nPDU,
  6560. IN BYTE * pEncoded,
  6561. IN DWORD cbEncodedSize
  6562. )
  6563. {
  6564. H323DBG((DEBUG_LEVEL_TRACE, "h323call DecodeH450ASN entered: %p.", this ));
  6565. ASN1decoding_t pDecInfo = m_H450ASNCoderInfo.pDecInfo;
  6566. int rc = ASN1_Decode(
  6567. pDecInfo, // ptr to encoder info
  6568. ppStruct, // pdu data structure
  6569. nPDU, // pdu id
  6570. ASN1DECODE_SETBUFFER, // flags
  6571. pEncoded, // do not provide buffer
  6572. cbEncodedSize); // buffer size if provided
  6573. if( ASN1_SUCCEEDED(rc) )
  6574. {
  6575. if( rc != ASN1_SUCCESS )
  6576. {
  6577. H323DBG((DEBUG_LEVEL_TRACE, "warning while deciding ASN:%d.", rc ));
  6578. }
  6579. }
  6580. else
  6581. {
  6582. H323DBG((DEBUG_LEVEL_TRACE, "error while deciding ASN:%d.", rc ));
  6583. H323DUMPBUFFER( (BYTE*)pEncoded, cbEncodedSize);
  6584. *ppStruct = NULL;
  6585. }
  6586. H323DBG(( DEBUG_LEVEL_TRACE, "h323call DecodeH450ASN exited: %p.", this ));
  6587. return rc;
  6588. }
  6589. //------------------------------------------------------------------------
  6590. //------------------------------------------------------------------------
  6591. //!!always called in a lock
  6592. BOOL
  6593. CH323Call::ParseReleaseCompleteASN(
  6594. IN BYTE *pEncodedBuf,
  6595. IN DWORD dwEncodedLength,
  6596. OUT Q931_RELEASE_COMPLETE_ASN *pReleaseASN,
  6597. OUT DWORD* pdwH450APDUType
  6598. )
  6599. {
  6600. H323_UserInformation *pUserInfo;
  6601. int iResult;
  6602. DWORD dwInvokeID = 0;
  6603. H323DBG((DEBUG_LEVEL_TRACE, "ParseReleaseCompleteASN entered: %p.", this ));
  6604. memset( (PVOID)pReleaseASN, 0, sizeof(Q931_RELEASE_COMPLETE_ASN));
  6605. iResult = DecodeASN((void **) &pUserInfo,
  6606. H323_UserInformation_PDU,
  6607. pEncodedBuf,
  6608. dwEncodedLength);
  6609. if (ASN1_FAILED(iResult) || (pUserInfo == NULL))
  6610. {
  6611. return FALSE;
  6612. }
  6613. *pdwH450APDUType = 0;
  6614. if( (pUserInfo->h323_uu_pdu.bit_mask & h4501SupplementaryService_present) &&
  6615. pUserInfo->h323_uu_pdu.h4501SupplementaryService )
  6616. {
  6617. if( !HandleH450APDU( pUserInfo->h323_uu_pdu.h4501SupplementaryService,
  6618. pdwH450APDUType, &dwInvokeID, NULL ) )
  6619. {
  6620. goto cleanup;
  6621. }
  6622. }
  6623. // validate that the PDU user-data uses ASN encoding.
  6624. if( (pUserInfo->bit_mask & user_data_present) &&
  6625. (pUserInfo->user_data.protocol_discriminator != USE_ASN1_ENCODING) )
  6626. {
  6627. goto cleanup;
  6628. }
  6629. // validate that the PDU is H323 Release Complete information.
  6630. if( pUserInfo->h323_uu_pdu.h323_message_body.choice != releaseComplete_chosen )
  6631. {
  6632. goto cleanup;
  6633. }
  6634. // parse the message contained in pUserInfo.
  6635. pReleaseASN->fNonStandardDataPresent = FALSE;
  6636. if( pUserInfo->h323_uu_pdu.bit_mask & H323_UU_PDU_nonStandardData_present )
  6637. {
  6638. if( !ParseNonStandardData( &pReleaseASN -> nonStandardData,
  6639. &pUserInfo->h323_uu_pdu.nonStandardData ) )
  6640. {
  6641. goto cleanup;
  6642. }
  6643. pReleaseASN->fNonStandardDataPresent = TRUE;
  6644. }
  6645. if (pUserInfo->h323_uu_pdu.h323_message_body.u.releaseComplete.bit_mask &
  6646. ReleaseComplete_UUIE_reason_present)
  6647. {
  6648. switch( pUserInfo->h323_uu_pdu.h323_message_body.u.releaseComplete.reason.choice )
  6649. {
  6650. case noBandwidth_chosen:
  6651. pReleaseASN->bReason = H323_REJECT_NO_BANDWIDTH;
  6652. break;
  6653. case gatekeeperResources_chosen:
  6654. pReleaseASN->bReason = H323_REJECT_GATEKEEPER_RESOURCES;
  6655. break;
  6656. case unreachableDestination_chosen:
  6657. pReleaseASN->bReason = H323_REJECT_UNREACHABLE_DESTINATION;
  6658. break;
  6659. case destinationRejection_chosen:
  6660. pReleaseASN->bReason = H323_REJECT_DESTINATION_REJECTION;
  6661. break;
  6662. case ReleaseCompleteReason_invalidRevision_chosen:
  6663. pReleaseASN->bReason = H323_REJECT_INVALID_REVISION;
  6664. break;
  6665. case noPermission_chosen:
  6666. pReleaseASN->bReason = H323_REJECT_NO_PERMISSION;
  6667. break;
  6668. case unreachableGatekeeper_chosen:
  6669. pReleaseASN->bReason = H323_REJECT_UNREACHABLE_GATEKEEPER;
  6670. break;
  6671. case gatewayResources_chosen:
  6672. pReleaseASN->bReason = H323_REJECT_GATEWAY_RESOURCES;
  6673. break;
  6674. case badFormatAddress_chosen:
  6675. pReleaseASN->bReason = H323_REJECT_BAD_FORMAT_ADDRESS;
  6676. break;
  6677. case adaptiveBusy_chosen:
  6678. pReleaseASN->bReason = H323_REJECT_ADAPTIVE_BUSY;
  6679. break;
  6680. case inConf_chosen:
  6681. pReleaseASN->bReason = H323_REJECT_IN_CONF;
  6682. break;
  6683. case facilityCallDeflection_chosen:
  6684. pReleaseASN->bReason = H323_REJECT_CALL_DEFLECTION;
  6685. break;
  6686. default:
  6687. pReleaseASN->bReason = H323_REJECT_UNDEFINED_REASON;
  6688. } // switch
  6689. }
  6690. else
  6691. {
  6692. pReleaseASN->bReason = H323_REJECT_UNDEFINED_REASON;
  6693. }
  6694. H323DBG(( DEBUG_LEVEL_TRACE,
  6695. "ParseReleaseCompleteASN error:%d, q931 error:%d, exit:%p.",
  6696. pReleaseASN->bReason,
  6697. pUserInfo->h323_uu_pdu.h323_message_body.u.releaseComplete.reason.choice,
  6698. this ));
  6699. // Free the PDU data.
  6700. ASN1_FreeDecoded(m_ASNCoderInfo.pDecInfo, pUserInfo,
  6701. H323_UserInformation_PDU );
  6702. return TRUE;
  6703. cleanup:
  6704. if( pReleaseASN->fNonStandardDataPresent )
  6705. {
  6706. delete pReleaseASN -> nonStandardData.sData.pOctetString;
  6707. pReleaseASN -> nonStandardData.sData.pOctetString = NULL;
  6708. pReleaseASN->fNonStandardDataPresent = FALSE;
  6709. }
  6710. ASN1_FreeDecoded( m_ASNCoderInfo.pDecInfo, pUserInfo,
  6711. H323_UserInformation_PDU);
  6712. return FALSE;
  6713. }
  6714. //------------------------------------------------------------------------
  6715. //------------------------------------------------------------------------
  6716. //!!always called in a lock
  6717. BOOL
  6718. CH323Call::ParseConnectASN(
  6719. IN BYTE *pEncodedBuf,
  6720. IN DWORD dwEncodedLength,
  6721. OUT Q931_CONNECT_ASN *pConnectASN,
  6722. OUT DWORD* pdwH450APDUType
  6723. )
  6724. {
  6725. H323_UserInformation *pUserInfo;
  6726. int iResult;
  6727. DWORD dwInvokeID = 0;
  6728. H323DBG((DEBUG_LEVEL_TRACE, "ParseConnectASN entered: %p.", this ));
  6729. memset( (PVOID) pConnectASN, 0, sizeof(Q931_CONNECT_ASN) );
  6730. iResult = DecodeASN((void **) &pUserInfo ,
  6731. H323_UserInformation_PDU,
  6732. pEncodedBuf,
  6733. dwEncodedLength);
  6734. if (ASN1_FAILED(iResult) || (pUserInfo == NULL))
  6735. {
  6736. return FALSE;
  6737. }
  6738. Connect_UUIE & connectMessage =
  6739. pUserInfo->h323_uu_pdu.h323_message_body.u.connect;
  6740. *pdwH450APDUType = 0;
  6741. if( (pUserInfo->h323_uu_pdu.bit_mask & h4501SupplementaryService_present) &&
  6742. pUserInfo->h323_uu_pdu.h4501SupplementaryService )
  6743. {
  6744. if( !HandleH450APDU( pUserInfo->h323_uu_pdu.h4501SupplementaryService,
  6745. pdwH450APDUType, &dwInvokeID, NULL ) )
  6746. {
  6747. goto cleanup;
  6748. }
  6749. }
  6750. // validate that the PDU user-data uses ASN encoding.
  6751. if( (pUserInfo->bit_mask & user_data_present) &&
  6752. (pUserInfo->user_data.protocol_discriminator != USE_ASN1_ENCODING) )
  6753. {
  6754. goto cleanup;
  6755. }
  6756. // validate that the PDU is H323 Connect information.
  6757. if (pUserInfo->h323_uu_pdu.h323_message_body.choice != connect_chosen)
  6758. {
  6759. goto cleanup;
  6760. }
  6761. // make sure that the conference id is formed correctly.
  6762. if (connectMessage.conferenceID.length >
  6763. sizeof(connectMessage.conferenceID.value))
  6764. {
  6765. goto cleanup;
  6766. }
  6767. // parse the message contained in pUserInfo.
  6768. pConnectASN->h245Addr.bMulticast = FALSE;
  6769. pConnectASN->fNonStandardDataPresent = FALSE;
  6770. if( pUserInfo->h323_uu_pdu.bit_mask & H323_UU_PDU_nonStandardData_present )
  6771. {
  6772. if( !ParseNonStandardData( &pConnectASN -> nonStandardData,
  6773. &pUserInfo->h323_uu_pdu.nonStandardData ) )
  6774. {
  6775. goto cleanup;
  6776. }
  6777. pConnectASN->fNonStandardDataPresent = TRUE;
  6778. }
  6779. pConnectASN->h245AddrPresent = FALSE;
  6780. if( connectMessage.bit_mask & Connect_UUIE_h245Address_present )
  6781. {
  6782. if( connectMessage.h245Address.choice != ipAddress_chosen )
  6783. {
  6784. goto cleanup;
  6785. }
  6786. pConnectASN->h245Addr.nAddrType = H323_IP_BINARY;
  6787. pConnectASN->h245Addr.Addr.IP_Binary.wPort =
  6788. connectMessage.h245Address.u.ipAddress.port;
  6789. pConnectASN->h245Addr.Addr.IP_Binary.dwAddr =
  6790. ntohl( *((DWORD*)connectMessage.h245Address.u.ipAddress.ip.value) );
  6791. pConnectASN->h245AddrPresent = TRUE;
  6792. }
  6793. // no validation of destinationInfo needed.
  6794. pConnectASN->EndpointType.pVendorInfo = NULL;
  6795. if( connectMessage.destinationInfo.bit_mask & (vendor_present))
  6796. {
  6797. if( !ParseVendorInfo( &pConnectASN->VendorInfo,
  6798. &connectMessage.destinationInfo.vendor) )
  6799. {
  6800. goto cleanup;
  6801. }
  6802. pConnectASN->EndpointType.pVendorInfo = &(pConnectASN->VendorInfo);
  6803. }
  6804. pConnectASN->EndpointType.bIsTerminal = FALSE;
  6805. if (connectMessage.destinationInfo.bit_mask & (terminal_present))
  6806. {
  6807. pConnectASN->EndpointType.bIsTerminal = TRUE;
  6808. }
  6809. pConnectASN->EndpointType.bIsGateway = FALSE;
  6810. if (connectMessage.destinationInfo.bit_mask & (gateway_present))
  6811. {
  6812. pConnectASN->EndpointType.bIsGateway = TRUE;
  6813. }
  6814. pConnectASN -> fFastStartPresent = FALSE;
  6815. if( (connectMessage.bit_mask & Connect_UUIE_fastStart_present) &&
  6816. connectMessage.fastStart )
  6817. {
  6818. pConnectASN->pFastStart = CopyFastStart(
  6819. (PSetup_UUIE_fastStart)connectMessage.fastStart );
  6820. if( pConnectASN->pFastStart != NULL )
  6821. {
  6822. pConnectASN -> fFastStartPresent = TRUE;
  6823. }
  6824. }
  6825. CopyConferenceID( &pConnectASN -> ConferenceID,
  6826. &connectMessage.conferenceID );
  6827. if( pUserInfo->h323_uu_pdu.h245Tunneling )
  6828. {
  6829. //the remote endpoint has sent a tunneling proposal
  6830. m_fh245Tunneling |= REMOTE_H245_TUNNELING;
  6831. }
  6832. // Free the PDU data.
  6833. ASN1_FreeDecoded(m_ASNCoderInfo.pDecInfo, pUserInfo,
  6834. H323_UserInformation_PDU);
  6835. H323DBG((DEBUG_LEVEL_TRACE, "ParseConnectASN exited: %p.", this ));
  6836. return TRUE;
  6837. cleanup:
  6838. FreeConnectASN( pConnectASN );
  6839. ASN1_FreeDecoded(m_ASNCoderInfo.pDecInfo, pUserInfo,
  6840. H323_UserInformation_PDU );
  6841. return FALSE;
  6842. }
  6843. //!!always called in a lock
  6844. BOOL
  6845. CH323Call::ParseAlertingASN(
  6846. IN BYTE *pEncodedBuf,
  6847. IN DWORD dwEncodedLength,
  6848. OUT Q931_ALERTING_ASN *pAlertingASN,
  6849. OUT DWORD* pdwH450APDUType
  6850. )
  6851. {
  6852. H323_UserInformation *pUserInfo;
  6853. int iResult;
  6854. DWORD dwInvokeID = 0;
  6855. H323DBG((DEBUG_LEVEL_TRACE, "ParseAlertingASN entered: %p.", this ));
  6856. memset( (PVOID) pAlertingASN, 0, sizeof(Q931_ALERTING_ASN) );
  6857. iResult = DecodeASN((void **) &pUserInfo,
  6858. H323_UserInformation_PDU,
  6859. pEncodedBuf,
  6860. dwEncodedLength);
  6861. if (ASN1_FAILED(iResult) || (pUserInfo == NULL))
  6862. {
  6863. return FALSE;
  6864. }
  6865. Alerting_UUIE & alertingMessage =
  6866. pUserInfo->h323_uu_pdu.h323_message_body.u.alerting;
  6867. *pdwH450APDUType = 0;
  6868. if( (pUserInfo->h323_uu_pdu.bit_mask & h4501SupplementaryService_present) &&
  6869. pUserInfo->h323_uu_pdu.h4501SupplementaryService )
  6870. {
  6871. if( !HandleH450APDU( pUserInfo->h323_uu_pdu.h4501SupplementaryService,
  6872. pdwH450APDUType, &dwInvokeID, NULL ) )
  6873. {
  6874. goto cleanup;
  6875. }
  6876. }
  6877. // validate that the PDU user-data uses ASN encoding.
  6878. if( (pUserInfo->bit_mask & user_data_present ) &&
  6879. (pUserInfo->user_data.protocol_discriminator != USE_ASN1_ENCODING) )
  6880. {
  6881. goto cleanup;
  6882. }
  6883. // validate that the PDU is H323 Alerting information.
  6884. if (pUserInfo->h323_uu_pdu.h323_message_body.choice != alerting_chosen)
  6885. {
  6886. goto cleanup;
  6887. }
  6888. // parse the message contained in pUserInfo.
  6889. pAlertingASN->h245Addr.bMulticast = FALSE;
  6890. pAlertingASN->fNonStandardDataPresent = FALSE;
  6891. if( pUserInfo->h323_uu_pdu.bit_mask & H323_UU_PDU_nonStandardData_present )
  6892. {
  6893. if( !ParseNonStandardData( &pAlertingASN -> nonStandardData,
  6894. &pUserInfo->h323_uu_pdu.nonStandardData ) )
  6895. {
  6896. goto cleanup;
  6897. }
  6898. pAlertingASN->fNonStandardDataPresent = TRUE;
  6899. }
  6900. if( alertingMessage.bit_mask & Alerting_UUIE_h245Address_present )
  6901. {
  6902. if( alertingMessage.h245Address.choice != ipAddress_chosen )
  6903. {
  6904. goto cleanup;
  6905. }
  6906. pAlertingASN->h245Addr.nAddrType = H323_IP_BINARY;
  6907. pAlertingASN->h245Addr.Addr.IP_Binary.wPort =
  6908. alertingMessage.h245Address.u.ipAddress.port;
  6909. AddressReverseAndCopy(
  6910. &(pAlertingASN->h245Addr.Addr.IP_Binary.dwAddr),
  6911. alertingMessage.h245Address.u.ipAddress.ip.value );
  6912. }
  6913. pAlertingASN -> fFastStartPresent = FALSE;
  6914. if( (alertingMessage.bit_mask & Alerting_UUIE_fastStart_present) &&
  6915. alertingMessage.fastStart )
  6916. {
  6917. pAlertingASN->pFastStart = CopyFastStart(
  6918. (PSetup_UUIE_fastStart)alertingMessage.fastStart);
  6919. if( pAlertingASN->pFastStart != NULL )
  6920. pAlertingASN-> fFastStartPresent = TRUE;
  6921. }
  6922. if( pUserInfo->h323_uu_pdu.h245Tunneling )
  6923. {
  6924. m_fh245Tunneling |= REMOTE_H245_TUNNELING;
  6925. }
  6926. // Free the PDU data.
  6927. ASN1_FreeDecoded(m_ASNCoderInfo.pDecInfo, pUserInfo,
  6928. H323_UserInformation_PDU);
  6929. H323DBG((DEBUG_LEVEL_TRACE, "ParseAlertingASN exited: %p.", this ));
  6930. return TRUE;
  6931. cleanup:
  6932. FreeAlertingASN( pAlertingASN );
  6933. ASN1_FreeDecoded( m_ASNCoderInfo.pDecInfo, pUserInfo,
  6934. H323_UserInformation_PDU );
  6935. return FALSE;
  6936. }
  6937. //!!aleways called in a lock
  6938. BOOL
  6939. CH323Call::ParseProceedingASN(
  6940. IN BYTE *pEncodedBuf,
  6941. IN DWORD dwEncodedLength,
  6942. OUT Q931_CALL_PROCEEDING_ASN *pProceedingASN,
  6943. OUT DWORD* pdwH450APDUType
  6944. )
  6945. {
  6946. H323_UserInformation * pUserInfo;
  6947. int iResult;
  6948. DWORD dwInvokeID = 0;
  6949. H323DBG((DEBUG_LEVEL_TRACE, "ParseProceedingASN entered: %p.", this ));
  6950. memset( (PVOID) pProceedingASN, 0, sizeof(Q931_CALL_PROCEEDING_ASN) );
  6951. iResult = DecodeASN((void **) &pUserInfo,
  6952. H323_UserInformation_PDU,
  6953. pEncodedBuf,
  6954. dwEncodedLength);
  6955. if (ASN1_FAILED(iResult) || (pUserInfo == NULL))
  6956. {
  6957. return FALSE;
  6958. }
  6959. CallProceeding_UUIE & proceedingMessage =
  6960. pUserInfo->h323_uu_pdu.h323_message_body.u.callProceeding;
  6961. *pdwH450APDUType = 0;
  6962. if( (pUserInfo->h323_uu_pdu.bit_mask & h4501SupplementaryService_present) &&
  6963. pUserInfo->h323_uu_pdu.h4501SupplementaryService )
  6964. {
  6965. if( !HandleH450APDU( pUserInfo->h323_uu_pdu.h4501SupplementaryService,
  6966. pdwH450APDUType, &dwInvokeID, NULL ) )
  6967. goto cleanup;
  6968. }
  6969. // validate that the PDU user-data uses ASN encoding.
  6970. if( (pUserInfo->bit_mask & user_data_present) &&
  6971. (pUserInfo->user_data.protocol_discriminator != USE_ASN1_ENCODING) )
  6972. {
  6973. goto cleanup;
  6974. }
  6975. // validate that the PDU is H323 Proceeding information.
  6976. // validate that the PDU is H323 pCall Proceeding information.
  6977. if( pUserInfo->h323_uu_pdu.h323_message_body.choice != callProceeding_chosen )
  6978. {
  6979. goto cleanup;
  6980. }
  6981. // parse the message contained in pUserInfo.
  6982. pProceedingASN->fNonStandardDataPresent = FALSE;
  6983. if( pUserInfo->h323_uu_pdu.bit_mask & H323_UU_PDU_nonStandardData_present )
  6984. {
  6985. if( !ParseNonStandardData( &pProceedingASN -> nonStandardData,
  6986. &pUserInfo->h323_uu_pdu.nonStandardData ) )
  6987. {
  6988. goto cleanup;
  6989. }
  6990. pProceedingASN->fNonStandardDataPresent = TRUE;
  6991. }
  6992. //copy the H245 address information
  6993. pProceedingASN->fH245AddrPresent = FALSE;
  6994. if( proceedingMessage.bit_mask & CallProceeding_UUIE_h245Address_present )
  6995. {
  6996. if( proceedingMessage.h245Address.choice != ipAddress_chosen )
  6997. {
  6998. goto cleanup;
  6999. }
  7000. pProceedingASN->h245Addr.nAddrType = H323_IP_BINARY;
  7001. pProceedingASN->h245Addr.Addr.IP_Binary.wPort =
  7002. proceedingMessage.h245Address.u.ipAddress.port;
  7003. AddressReverseAndCopy(
  7004. &(pProceedingASN->h245Addr.Addr.IP_Binary.dwAddr),
  7005. proceedingMessage.h245Address.u.ipAddress.ip.value );
  7006. pProceedingASN->h245Addr.bMulticast = FALSE;
  7007. pProceedingASN->fH245AddrPresent = TRUE;
  7008. }
  7009. pProceedingASN -> fFastStartPresent = FALSE;
  7010. if( (proceedingMessage.bit_mask & CallProceeding_UUIE_fastStart_present) &&
  7011. proceedingMessage.fastStart )
  7012. {
  7013. pProceedingASN->pFastStart = CopyFastStart(
  7014. (PSetup_UUIE_fastStart)proceedingMessage.fastStart);
  7015. if( pProceedingASN->pFastStart != NULL )
  7016. pProceedingASN-> fFastStartPresent = TRUE;
  7017. }
  7018. //ignore the destinationInfo field.
  7019. if( pUserInfo->h323_uu_pdu.h245Tunneling )
  7020. {
  7021. if( m_dwOrigin == LINECALLORIGIN_INBOUND )
  7022. {
  7023. //the msp has enabled tunneling in ProceedWithAnswer messsage
  7024. m_fh245Tunneling |= LOCAL_H245_TUNNELING;
  7025. }
  7026. else
  7027. //the remote endpoint has sent a tunneling proposal
  7028. m_fh245Tunneling |= REMOTE_H245_TUNNELING;
  7029. }
  7030. // Free the PDU data.
  7031. ASN1_FreeDecoded(m_ASNCoderInfo.pDecInfo, pUserInfo,
  7032. H323_UserInformation_PDU );
  7033. H323DBG((DEBUG_LEVEL_TRACE, "ParseProceedingASN exited: %p.", this ));
  7034. return TRUE;
  7035. cleanup:
  7036. FreeProceedingASN( pProceedingASN );
  7037. ASN1_FreeDecoded(m_ASNCoderInfo.pDecInfo, pUserInfo,
  7038. H323_UserInformation_PDU );
  7039. return FALSE;
  7040. }
  7041. //!!always called in a lock
  7042. BOOL
  7043. CH323Call::ParseFacilityASN(
  7044. IN BYTE * pEncodedBuf,
  7045. IN DWORD dwEncodedLength,
  7046. OUT Q931_FACILITY_ASN * pFacilityASN
  7047. )
  7048. {
  7049. H323_UserInformation *pUserInfo;
  7050. int iResult;
  7051. H323DBG((DEBUG_LEVEL_TRACE, "ParseFacilityASN entered: %p.", this ));
  7052. ZeroMemory( (PVOID) pFacilityASN, sizeof(Q931_FACILITY_ASN) );
  7053. iResult = DecodeASN((void **) &pUserInfo,
  7054. H323_UserInformation_PDU,
  7055. pEncodedBuf,
  7056. dwEncodedLength);
  7057. if( ASN1_FAILED(iResult) || (pUserInfo == NULL) )
  7058. {
  7059. return FALSE;
  7060. }
  7061. // validate that the PDU is H323 facility information.
  7062. if( pUserInfo->h323_uu_pdu.h323_message_body.choice == facility_chosen )
  7063. {
  7064. Facility_UUIE & facilityMessage =
  7065. pUserInfo->h323_uu_pdu.h323_message_body.u.facility;
  7066. // validate that the PDU user-data uses ASN encoding.
  7067. if( (pUserInfo->bit_mask & user_data_present) &&
  7068. (pUserInfo->user_data.protocol_discriminator != USE_ASN1_ENCODING) )
  7069. {
  7070. goto cleanup;
  7071. }
  7072. // make sure that the conference id is formed correctly.
  7073. if( facilityMessage.conferenceID.length >
  7074. sizeof(facilityMessage.conferenceID.value) )
  7075. {
  7076. //goto cleanup;
  7077. }
  7078. // parse the message contained in pUserInfo.
  7079. pFacilityASN->fNonStandardDataPresent = FALSE;
  7080. if( pUserInfo->h323_uu_pdu.bit_mask & H323_UU_PDU_nonStandardData_present )
  7081. {
  7082. if( !ParseNonStandardData( &pFacilityASN -> nonStandardData,
  7083. &pUserInfo->h323_uu_pdu.nonStandardData ) )
  7084. {
  7085. goto cleanup;
  7086. }
  7087. pFacilityASN->fNonStandardDataPresent = TRUE;
  7088. }
  7089. pFacilityASN->fAlternativeAddressPresent = FALSE;
  7090. if( facilityMessage.bit_mask & alternativeAddress_present )
  7091. {
  7092. if( facilityMessage.alternativeAddress.choice == ipAddress_chosen )
  7093. {
  7094. pFacilityASN->AlternativeAddr.nAddrType = H323_IP_BINARY;
  7095. pFacilityASN->AlternativeAddr.Addr.IP_Binary.wPort =
  7096. facilityMessage.alternativeAddress.u.ipAddress.port;
  7097. AddressReverseAndCopy(
  7098. &(pFacilityASN->AlternativeAddr.Addr.IP_Binary.dwAddr),
  7099. facilityMessage.alternativeAddress.u.ipAddress.ip.value );
  7100. pFacilityASN->fAlternativeAddressPresent = TRUE;
  7101. }
  7102. }
  7103. if( facilityMessage.bit_mask & alternativeAliasAddress_present )
  7104. {
  7105. if( !AliasAddrToAliasNames( &(pFacilityASN->pAlternativeAliasList),
  7106. (PSetup_UUIE_sourceAddress)
  7107. &(facilityMessage.alternativeAliasAddress) ) )
  7108. {
  7109. pFacilityASN -> pAlternativeAliasList = NULL;
  7110. //goto cleanup;
  7111. }
  7112. }
  7113. if( facilityMessage.bit_mask & Facility_UUIE_conferenceID_present )
  7114. {
  7115. CopyConferenceID( &pFacilityASN -> ConferenceID,
  7116. &facilityMessage.conferenceID );
  7117. pFacilityASN -> ConferenceIDPresent = TRUE;
  7118. }
  7119. pFacilityASN->bReason = facilityMessage.reason.choice;
  7120. pFacilityASN->fH245AddrPresent = FALSE;
  7121. if( facilityMessage.bit_mask & Facility_UUIE_h245Address_present )
  7122. {
  7123. if( facilityMessage.h245Address.choice == ipAddress_chosen )
  7124. {
  7125. pFacilityASN->h245Addr.nAddrType = H323_IP_BINARY;
  7126. pFacilityASN->h245Addr.Addr.IP_Binary.wPort =
  7127. facilityMessage.h245Address.u.ipAddress.port;
  7128. pFacilityASN->h245Addr.Addr.IP_Binary.dwAddr =
  7129. ntohl( *((DWORD*)facilityMessage.h245Address.u.ipAddress.ip.value) );
  7130. pFacilityASN->fH245AddrPresent = TRUE;
  7131. }
  7132. }
  7133. }
  7134. pFacilityASN->dwH450APDUType = 0;
  7135. if( (pUserInfo->h323_uu_pdu.bit_mask & h4501SupplementaryService_present) &&
  7136. pUserInfo->h323_uu_pdu.h4501SupplementaryService )
  7137. {
  7138. pFacilityASN->dwInvokeID = 0;
  7139. if( !HandleH450APDU( pUserInfo->h323_uu_pdu.h4501SupplementaryService,
  7140. &pFacilityASN->dwH450APDUType, &pFacilityASN->dwInvokeID, NULL ) )
  7141. {
  7142. goto cleanup;
  7143. }
  7144. }
  7145. if( pUserInfo->h323_uu_pdu.bit_mask & h245Control_present )
  7146. {
  7147. if( pUserInfo->h323_uu_pdu.h245Control != NULL )
  7148. {
  7149. pFacilityASN->pH245PDU.value =
  7150. new BYTE[pUserInfo->h323_uu_pdu.h245Control->value.length];
  7151. if( pFacilityASN->pH245PDU.value != NULL )
  7152. {
  7153. CopyMemory( (PVOID)pFacilityASN->pH245PDU.value,
  7154. (PVOID)pUserInfo->h323_uu_pdu.h245Control->value.value,
  7155. pUserInfo->h323_uu_pdu.h245Control->value.length );
  7156. }
  7157. pFacilityASN->pH245PDU.length =
  7158. pUserInfo->h323_uu_pdu.h245Control->value.length;
  7159. }
  7160. }
  7161. ASN1_FreeDecoded( m_ASNCoderInfo.pDecInfo, pUserInfo,
  7162. H323_UserInformation_PDU );
  7163. H323DBG((DEBUG_LEVEL_TRACE, "ParseFacilityASN exited: %p.", this ));
  7164. return TRUE;
  7165. cleanup:
  7166. if( pFacilityASN -> pAlternativeAliasList != NULL )
  7167. {
  7168. FreeAliasNames( pFacilityASN -> pAlternativeAliasList );
  7169. pFacilityASN -> pAlternativeAliasList = NULL;
  7170. }
  7171. if( pFacilityASN->fNonStandardDataPresent != NULL )
  7172. {
  7173. delete pFacilityASN->nonStandardData.sData.pOctetString;
  7174. pFacilityASN->nonStandardData.sData.pOctetString = NULL;
  7175. pFacilityASN->fNonStandardDataPresent = NULL;
  7176. }
  7177. ASN1_FreeDecoded(m_ASNCoderInfo.pDecInfo, pUserInfo,
  7178. H323_UserInformation_PDU );
  7179. return FALSE;
  7180. }
  7181. //!!aleways called in a lock
  7182. BOOL
  7183. CH323Call::ParseSetupASN(
  7184. IN BYTE *pEncodedBuf,
  7185. IN DWORD dwEncodedLength,
  7186. OUT Q931_SETUP_ASN *pSetupASN,
  7187. OUT DWORD* pdwH450APDUType
  7188. )
  7189. {
  7190. H323_UserInformation *pUserInfo;
  7191. HRESULT hr;
  7192. int iResult;
  7193. DWORD dwInvokeID = 0;
  7194. H323DBG((DEBUG_LEVEL_TRACE, "ParseSetupASN entered: %p.", this ));
  7195. memset( (PVOID)pSetupASN, 0, sizeof(Q931_SETUP_ASN));
  7196. iResult = DecodeASN((void **) &pUserInfo,
  7197. H323_UserInformation_PDU,
  7198. pEncodedBuf,
  7199. dwEncodedLength);
  7200. if (ASN1_FAILED(iResult) || (pUserInfo == NULL))
  7201. {
  7202. return FALSE;
  7203. }
  7204. Setup_UUIE & setupMessage = pUserInfo->h323_uu_pdu.h323_message_body.u.setup;
  7205. // validate that the PDU user-data uses ASN encoding.
  7206. if( (pUserInfo->bit_mask & user_data_present) &&
  7207. (pUserInfo->user_data.protocol_discriminator != USE_ASN1_ENCODING) )
  7208. {
  7209. //log
  7210. goto cleanup;
  7211. }
  7212. // validate that the PDU is H323 Setup information.
  7213. if( pUserInfo->h323_uu_pdu.h323_message_body.choice != setup_chosen )
  7214. {
  7215. //log
  7216. goto cleanup;
  7217. }
  7218. // make sure that the conference id is formed correctly.
  7219. if (setupMessage.conferenceID.length >
  7220. sizeof(setupMessage.conferenceID.value))
  7221. {
  7222. goto cleanup;
  7223. }
  7224. // parse the message contained in pUserInfo.
  7225. pSetupASN->sourceAddr.bMulticast = FALSE;
  7226. pSetupASN->callerAddr.bMulticast = FALSE;
  7227. pSetupASN->calleeDestAddr.bMulticast = FALSE;
  7228. pSetupASN->calleeAddr.bMulticast = FALSE;
  7229. // no validation of sourceInfo needed.
  7230. //copy thevendor info
  7231. pSetupASN->EndpointType.pVendorInfo = NULL;
  7232. if( setupMessage.sourceInfo.bit_mask & vendor_present )
  7233. {
  7234. if( !ParseVendorInfo( &pSetupASN->VendorInfo,
  7235. &setupMessage.sourceInfo.vendor) )
  7236. {
  7237. goto cleanup;
  7238. }
  7239. pSetupASN->EndpointType.pVendorInfo = &(pSetupASN->VendorInfo);
  7240. }
  7241. pSetupASN->EndpointType.bIsTerminal = FALSE;
  7242. if( setupMessage.sourceInfo.bit_mask & terminal_present )
  7243. {
  7244. pSetupASN->EndpointType.bIsTerminal = TRUE;
  7245. }
  7246. pSetupASN->EndpointType.bIsGateway = FALSE;
  7247. if( setupMessage.sourceInfo.bit_mask & gateway_present )
  7248. {
  7249. pSetupASN->EndpointType.bIsGateway = TRUE;
  7250. }
  7251. pSetupASN->fNonStandardDataPresent = FALSE;
  7252. if( pUserInfo->h323_uu_pdu.bit_mask & H323_UU_PDU_nonStandardData_present )
  7253. {
  7254. if( !ParseNonStandardData( &pSetupASN -> nonStandardData,
  7255. &pUserInfo->h323_uu_pdu.nonStandardData ) )
  7256. {
  7257. goto cleanup;
  7258. }
  7259. pSetupASN->fNonStandardDataPresent = TRUE;
  7260. }
  7261. // parse the sourceAddress aliases here...
  7262. if( setupMessage.bit_mask & sourceAddress_present )
  7263. {
  7264. if( !AliasAddrToAliasNames( &(pSetupASN->pCallerAliasList),
  7265. setupMessage.sourceAddress ) )
  7266. {
  7267. pSetupASN->pCallerAliasList = NULL;
  7268. //goto cleanup;
  7269. }
  7270. }
  7271. // parse the destinationAddress aliases here...
  7272. if( (setupMessage.bit_mask & destinationAddress_present) &&
  7273. setupMessage.destinationAddress )
  7274. {
  7275. if( !AliasAddrToAliasNames( &(pSetupASN->pCalleeAliasList),
  7276. (PSetup_UUIE_sourceAddress)setupMessage.destinationAddress) )
  7277. {
  7278. pSetupASN->pCalleeAliasList = NULL;
  7279. //goto cleanup;
  7280. }
  7281. }
  7282. // parse the destExtraCallInfo aliases here...
  7283. if( (setupMessage.bit_mask & Setup_UUIE_destExtraCallInfo_present) &&
  7284. setupMessage.destExtraCallInfo )
  7285. {
  7286. if( !AliasAddrToAliasNames(&(pSetupASN->pExtraAliasList),
  7287. (PSetup_UUIE_sourceAddress)setupMessage.destExtraCallInfo) )
  7288. {
  7289. pSetupASN->pExtraAliasList = NULL;
  7290. //goto cleanup;
  7291. }
  7292. }
  7293. // parse the remoteExtensionAddress aliases here...
  7294. if( setupMessage.bit_mask & Setup_UUIE_remoteExtensionAddress_present )
  7295. {
  7296. pSetupASN->pExtensionAliasItem = new H323_ALIASITEM;
  7297. if( pSetupASN->pExtensionAliasItem == NULL )
  7298. {
  7299. goto cleanup;
  7300. }
  7301. hr = AliasAddrToAliasItem(pSetupASN->pExtensionAliasItem,
  7302. &(setupMessage.remoteExtensionAddress));
  7303. if( hr == E_OUTOFMEMORY )
  7304. {
  7305. goto cleanup;
  7306. }
  7307. }
  7308. pSetupASN -> fCalleeDestAddrPresent = FALSE;
  7309. if( setupMessage.bit_mask & Setup_UUIE_destCallSignalAddress_present )
  7310. {
  7311. if( setupMessage.destCallSignalAddress.choice != ipAddress_chosen )
  7312. {
  7313. goto cleanup;
  7314. }
  7315. pSetupASN->calleeDestAddr.nAddrType = H323_IP_BINARY;
  7316. pSetupASN->calleeDestAddr.Addr.IP_Binary.wPort =
  7317. setupMessage.destCallSignalAddress.u.ipAddress.port;
  7318. AddressReverseAndCopy(
  7319. &(pSetupASN->calleeDestAddr.Addr.IP_Binary.dwAddr),
  7320. setupMessage.destCallSignalAddress.u.ipAddress.ip.value );
  7321. pSetupASN -> fCalleeDestAddrPresent = TRUE;
  7322. }
  7323. pSetupASN->fSourceAddrPresent = FALSE;
  7324. if( setupMessage.bit_mask & sourceCallSignalAddress_present )
  7325. {
  7326. if( setupMessage.sourceCallSignalAddress.choice != ipAddress_chosen )
  7327. {
  7328. goto cleanup;
  7329. }
  7330. pSetupASN->sourceAddr.nAddrType = H323_IP_BINARY;
  7331. pSetupASN->sourceAddr.Addr.IP_Binary.wPort =
  7332. setupMessage.sourceCallSignalAddress.u.ipAddress.port;
  7333. pSetupASN->sourceAddr.Addr.IP_Binary.dwAddr = ntohl( *((DWORD*)
  7334. setupMessage.sourceCallSignalAddress.u.ipAddress.ip.value) );
  7335. pSetupASN->fSourceAddrPresent = TRUE;
  7336. }
  7337. pSetupASN->bCallerIsMC = setupMessage.activeMC;
  7338. pSetupASN -> fFastStartPresent = FALSE;
  7339. if( (setupMessage.bit_mask & Setup_UUIE_fastStart_present) &&
  7340. setupMessage.fastStart )
  7341. {
  7342. pSetupASN->pFastStart = CopyFastStart( setupMessage.fastStart );
  7343. if( pSetupASN->pFastStart != NULL )
  7344. {
  7345. pSetupASN -> fFastStartPresent = TRUE;
  7346. }
  7347. }
  7348. CopyConferenceID (&pSetupASN -> ConferenceID, &setupMessage.conferenceID);
  7349. //copy the call identifier
  7350. pSetupASN -> fCallIdentifierPresent = FALSE;
  7351. if( setupMessage.bit_mask & Setup_UUIE_callIdentifier_present )
  7352. {
  7353. pSetupASN -> fCallIdentifierPresent = TRUE;
  7354. CopyMemory( (PVOID)&(pSetupASN->callIdentifier),
  7355. setupMessage.callIdentifier.guid.value,
  7356. sizeof(GUID) );
  7357. }
  7358. if( pUserInfo->h323_uu_pdu.h245Tunneling )
  7359. {
  7360. if( m_dwOrigin == LINECALLORIGIN_INBOUND )
  7361. {
  7362. //the remote endpoint has sent a tunneling proposal
  7363. m_fh245Tunneling |= REMOTE_H245_TUNNELING;
  7364. }
  7365. else
  7366. {
  7367. //the msp has enabled tunneling in ReadyToInitiate messsage
  7368. m_fh245Tunneling |= LOCAL_H245_TUNNELING;
  7369. }
  7370. }
  7371. pSetupASN->wGoal = (WORD)setupMessage.conferenceGoal.choice;
  7372. pSetupASN->wCallType = setupMessage.callType.choice;
  7373. *pdwH450APDUType = 0;
  7374. if( (pUserInfo->h323_uu_pdu.bit_mask & h4501SupplementaryService_present) &&
  7375. pUserInfo->h323_uu_pdu.h4501SupplementaryService )
  7376. {
  7377. if( !HandleH450APDU( pUserInfo->h323_uu_pdu.h4501SupplementaryService,
  7378. pdwH450APDUType, &dwInvokeID, pSetupASN ) )
  7379. {
  7380. goto cleanup;
  7381. }
  7382. }
  7383. // Free the PDU data.
  7384. ASN1_FreeDecoded( m_ASNCoderInfo.pDecInfo, pUserInfo,
  7385. H323_UserInformation_PDU );
  7386. H323DBG(( DEBUG_LEVEL_TRACE, "ParseSetupASN exited: %p.", this ));
  7387. return TRUE;
  7388. cleanup:
  7389. FreeSetupASN( pSetupASN );
  7390. ASN1_FreeDecoded(m_ASNCoderInfo.pDecInfo, pUserInfo,
  7391. H323_UserInformation_PDU);
  7392. return FALSE;
  7393. }
  7394. //-----------------------------------------------------------------------------
  7395. //GLOBAL CALLBACK FUNCTIONS CALLED BY THREAD POOL
  7396. //-----------------------------------------------------------------------------
  7397. // static
  7398. void
  7399. NTAPI CH323Call::IoCompletionCallback(
  7400. IN DWORD dwStatus,
  7401. IN DWORD dwBytesTransferred,
  7402. IN OVERLAPPED * pOverlapped
  7403. )
  7404. {
  7405. CALL_OVERLAPPED *pCallOverlapped;
  7406. CH323Call* pCall;
  7407. H323DBG(( DEBUG_LEVEL_TRACE, "CH323Call-IoCompletionCallback entered." ));
  7408. _ASSERTE (pOverlapped);
  7409. pCallOverlapped = CONTAINING_RECORD( pOverlapped, CALL_OVERLAPPED,
  7410. Overlapped );
  7411. pCall = pCallOverlapped -> pCall;
  7412. switch (pCallOverlapped -> Type)
  7413. {
  7414. case OVERLAPPED_TYPE_SEND:
  7415. pCall -> OnWriteComplete( dwStatus,
  7416. static_cast<CALL_SEND_CONTEXT *>(pCallOverlapped) );
  7417. break;
  7418. case OVERLAPPED_TYPE_RECV:
  7419. pCallOverlapped -> BytesTransferred = dwBytesTransferred;
  7420. pCall -> OnReadComplete( dwStatus,
  7421. static_cast<CALL_RECV_CONTEXT *>(pCallOverlapped) );
  7422. break;
  7423. default:
  7424. _ASSERTE(FALSE);
  7425. }
  7426. H323DBG(( DEBUG_LEVEL_TRACE, "CH323Call-IoCompletionCallback exited." ));
  7427. }
  7428. void
  7429. CH323Call::OnWriteComplete(
  7430. IN DWORD dwStatus,
  7431. IN CALL_SEND_CONTEXT * pSendContext
  7432. )
  7433. {
  7434. H323DBG(( DEBUG_LEVEL_TRACE, "OnWriteComplete entered:%p.",this ));
  7435. Lock();
  7436. _ASSERTE( m_IoRefCount != 0 );
  7437. m_IoRefCount--;
  7438. H323DBG((DEBUG_LEVEL_TRACE, "WriteComplete:m_IoRefCount: %d:%p.",
  7439. m_IoRefCount, this ));
  7440. if( m_dwFlags & CALLOBJECT_SHUTDOWN )
  7441. {
  7442. if( m_IoRefCount == 0 )
  7443. {
  7444. QueueTAPICallRequest( TSPI_DELETE_CALL, NULL );
  7445. H323DBG((DEBUG_LEVEL_TRACE, "call delete:%p.", this ));
  7446. }
  7447. }
  7448. else if( dwStatus == ERROR_SUCCESS )
  7449. {
  7450. if( IsInList( &m_sendBufList, &pSendContext->ListEntry ) )
  7451. {
  7452. RemoveEntryList( &pSendContext->ListEntry );
  7453. delete pSendContext->WSABuf.buf;
  7454. delete pSendContext;
  7455. }
  7456. }
  7457. Unlock();
  7458. H323DBG(( DEBUG_LEVEL_TRACE, "OnWriteComplete exited:%p.",this ));
  7459. }
  7460. void
  7461. CH323Call::OnReadComplete(
  7462. IN DWORD dwStatus,
  7463. IN CALL_RECV_CONTEXT * pRecvContext )
  7464. {
  7465. H323DBG(( DEBUG_LEVEL_TRACE, "OnReadComplete entered:%p.",this ));
  7466. Lock();
  7467. _ASSERTE( m_IoRefCount != 0 );
  7468. m_IoRefCount --;
  7469. H323DBG(( DEBUG_LEVEL_TRACE, "RecvBuffer:m_IoRefCount:%d:%p.",
  7470. m_IoRefCount, this ));
  7471. if( m_dwFlags & CALLOBJECT_SHUTDOWN )
  7472. {
  7473. if( m_IoRefCount == 0 )
  7474. {
  7475. QueueTAPICallRequest( TSPI_DELETE_CALL, NULL );
  7476. H323DBG((DEBUG_LEVEL_TRACE, "call delete:%p.", this ));
  7477. }
  7478. }
  7479. else
  7480. {
  7481. if( dwStatus == ERROR_SUCCESS )
  7482. {
  7483. _ASSERTE( m_pRecvBuffer == pRecvContext );
  7484. if( pRecvContext->BytesTransferred == 0 )
  7485. {
  7486. CloseCall( 0 );
  7487. H323DBG((DEBUG_LEVEL_TRACE, "0 bytes recvd:%p.", this ));
  7488. }
  7489. else
  7490. {
  7491. ReadEvent( pRecvContext->BytesTransferred );
  7492. }
  7493. }
  7494. }
  7495. Unlock();
  7496. H323DBG(( DEBUG_LEVEL_TRACE, "OnReadComplete exited:%p.",this ));
  7497. }
  7498. // static
  7499. void
  7500. NTAPI CH323Call::SetupSentTimerCallback(
  7501. IN PVOID Parameter1,
  7502. IN BOOLEAN bTimer
  7503. )
  7504. {
  7505. PH323_CALL pCall = NULL;
  7506. //if the timer expired
  7507. _ASSERTE( bTimer );
  7508. H323DBG(( DEBUG_LEVEL_TRACE, "Q931 setup expired event recvd." ));
  7509. pCall=g_pH323Line -> FindH323CallAndLock((HDRVCALL) Parameter1);
  7510. if( pCall != NULL )
  7511. {
  7512. pCall -> SetupSentTimerExpired();
  7513. pCall -> Unlock();
  7514. }
  7515. }
  7516. // static
  7517. void
  7518. NTAPI CH323Call::CheckRestrictionTimerCallback(
  7519. IN PVOID Parameter1,
  7520. IN BOOLEAN bTimer
  7521. )
  7522. {
  7523. //if the timer expired
  7524. _ASSERTE( bTimer );
  7525. H323DBG(( DEBUG_LEVEL_TRACE, "CheckRestrictionTimerCallback entered." ));
  7526. if(!QueueTAPILineRequest(
  7527. TSPI_CLOSE_CALL,
  7528. (HDRVCALL) Parameter1,
  7529. NULL,
  7530. LINEDISCONNECTMODE_NOANSWER,
  7531. NULL) )
  7532. {
  7533. H323DBG(( DEBUG_LEVEL_ERROR, "could not post H323 close event." ));
  7534. }
  7535. H323DBG(( DEBUG_LEVEL_TRACE, "CheckRestrictionTimerCallback exited." ));
  7536. }
  7537. // static
  7538. void
  7539. NTAPI CH323Call::CallReroutingTimerCallback(
  7540. IN PVOID Parameter1,
  7541. IN BOOLEAN bTimer
  7542. )
  7543. {
  7544. //If the timer expired
  7545. _ASSERTE( bTimer );
  7546. H323DBG(( DEBUG_LEVEL_TRACE, "CallReroutingTimerCallback entered." ));
  7547. if(!QueueTAPILineRequest(
  7548. TSPI_CLOSE_CALL,
  7549. (HDRVCALL) Parameter1,
  7550. NULL,
  7551. LINEDISCONNECTMODE_NOANSWER,
  7552. NULL) )
  7553. {
  7554. H323DBG(( DEBUG_LEVEL_ERROR, "could not post H323 close event." ));
  7555. }
  7556. H323DBG(( DEBUG_LEVEL_TRACE, "CallReroutingTimerCallback exited." ));
  7557. }
  7558. //-----------------------------------------------------------------------------
  7559. //CALL DIVERSION (H450.3) ENCODE/DECODE ROUTINES
  7560. //-----------------------------------------------------------------------------
  7561. BOOL
  7562. CH323Call::HandleH450APDU(
  7563. IN PH323_UU_PDU_h4501SupplementaryService pH450APDU,
  7564. IN DWORD* pdwH450APDUType,
  7565. OUT DWORD* pdwInvokeID,
  7566. IN Q931_SETUP_ASN* pSetupASN
  7567. )
  7568. {
  7569. BOOL retVal = TRUE;
  7570. H4501SupplementaryService * pH450APDUStruct = NULL;
  7571. ServiceApdus_rosApdus * pROSApdu = NULL;
  7572. int iResult;
  7573. BYTE pEncodedArg[H450_ENCODED_ARG_LEN];
  7574. DWORD dwEncodedArgLen;
  7575. DWORD dwOpcode;
  7576. H323DBG(( DEBUG_LEVEL_TRACE, "HandleH450APDU entered:%p.", this ));
  7577. //right now assuming that only one APDU is passed at a time
  7578. iResult = DecodeH450ASN( (void **) &pH450APDUStruct,
  7579. H4501SupplementaryService_PDU,
  7580. pH450APDU->value.value,
  7581. pH450APDU->value.length );
  7582. if( ASN1_FAILED(iResult) || (pH450APDUStruct == NULL) )
  7583. {
  7584. return FALSE;
  7585. }
  7586. if( pH450APDUStruct->serviceApdu.choice != rosApdus_chosen )
  7587. {
  7588. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pH450APDUStruct,
  7589. H4501SupplementaryService_PDU );
  7590. return FALSE;
  7591. }
  7592. pROSApdu = pH450APDUStruct->serviceApdu.u.rosApdus;
  7593. switch( pROSApdu->value.choice )
  7594. {
  7595. case H4503ROS_invoke_chosen:
  7596. if( (pROSApdu->value.u.invoke.opcode.choice != local_chosen) ||
  7597. (pROSApdu->value.u.invoke.argument.length > H450_ENCODED_ARG_LEN) )
  7598. {
  7599. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pH450APDUStruct,
  7600. H4501SupplementaryService_PDU );
  7601. return FALSE;
  7602. }
  7603. *pdwInvokeID = pROSApdu->value.u.invoke.invokeId;
  7604. dwEncodedArgLen = pROSApdu->value.u.invoke.argument.length;
  7605. CopyMemory( (PVOID)pEncodedArg,
  7606. (PVOID)pROSApdu->value.u.invoke.argument.value,
  7607. dwEncodedArgLen );
  7608. dwOpcode = pROSApdu->value.u.invoke.opcode.u.local;
  7609. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pH450APDUStruct,
  7610. H4501SupplementaryService_PDU );
  7611. *pdwH450APDUType = dwOpcode;
  7612. switch( dwOpcode )
  7613. {
  7614. case CALLREROUTING_OPCODE:
  7615. retVal = HandleCallRerouting( pEncodedArg, dwEncodedArgLen );
  7616. break;
  7617. case DIVERTINGLEGINFO1_OPCODE:
  7618. retVal = HandleDiversionLegInfo1( pEncodedArg, dwEncodedArgLen );
  7619. break;
  7620. case DIVERTINGLEGINFO2_OPCODE:
  7621. retVal = HandleDiversionLegInfo2( pEncodedArg, dwEncodedArgLen );
  7622. break;
  7623. case DIVERTINGLEGINFO3_OPCODE:
  7624. //Don't bail out even if this function fails.
  7625. HandleDiversionLegInfo3( pEncodedArg, dwEncodedArgLen );
  7626. break;
  7627. case CHECKRESTRICTION_OPCODE:
  7628. if( pSetupASN == NULL )
  7629. {
  7630. retVal = FALSE;
  7631. }
  7632. else
  7633. {
  7634. retVal = HandleCheckRestriction( pEncodedArg, dwEncodedArgLen,
  7635. pSetupASN );
  7636. }
  7637. if( retVal )
  7638. {
  7639. retVal = SendQ931Message( *pdwInvokeID, 0, 0,
  7640. CONNECTMESSAGETYPE,
  7641. H450_RETURNRESULT|CHECKRESTRICTION_OPCODE );
  7642. }
  7643. break;
  7644. case CTIDENTIFY_OPCODE:
  7645. retVal = HandleCTIdentify( *pdwInvokeID );
  7646. m_dwInvokeID = *pdwInvokeID;
  7647. break;
  7648. case CTINITIATE_OPCODE:
  7649. retVal = HandleCTInitiate( pEncodedArg, dwEncodedArgLen );
  7650. m_dwInvokeID = *pdwInvokeID;
  7651. break;
  7652. case CTSETUP_OPCODE:
  7653. retVal = HandleCTSetup( pEncodedArg, dwEncodedArgLen );
  7654. m_dwInvokeID = *pdwInvokeID;
  7655. break;
  7656. case HOLDNOTIFIC_OPCODE:
  7657. //local hold request from the remote endpoint
  7658. if( m_dwCallState != LINECALLSTATE_ONHOLD )
  7659. {
  7660. SendMSPMessage( SP_MSG_Hold, 0, 1, NULL );
  7661. ChangeCallState( LINECALLSTATE_ONHOLD, 0 );
  7662. }
  7663. break;
  7664. case RETRIEVENOTIFIC_OPCODE:
  7665. //local retrieve request from the remote endpoint
  7666. if( (m_dwCallState == LINECALLSTATE_ONHOLD) &&
  7667. !(m_dwFlags & TSPI_CALL_LOCAL_HOLD) )
  7668. {
  7669. SendMSPMessage( SP_MSG_Hold, 0, 0, NULL );
  7670. ChangeCallState( LINECALLSTATE_CONNECTED, 0 );
  7671. }
  7672. break;
  7673. case REMOTEHOLD_OPCODE:
  7674. //remote hold request from remote endpoint
  7675. if( m_dwCallState != LINECALLSTATE_ONHOLD )
  7676. {
  7677. SendMSPMessage( SP_MSG_Hold, 0, 1, NULL );
  7678. ChangeCallState( LINECALLSTATE_ONHOLD, 0 );
  7679. retVal = SendQ931Message( *pdwInvokeID, 0, 0,
  7680. FACILITYMESSAGETYPE,
  7681. REMOTEHOLD_OPCODE| H450_RETURNRESULT );
  7682. }
  7683. break;
  7684. case REMOTERETRIEVE_OPCODE:
  7685. //remote retrieve request from remote endpoint
  7686. if( m_dwCallState == LINECALLSTATE_ONHOLD )
  7687. {
  7688. SendMSPMessage( SP_MSG_Hold, 0, 0, NULL );
  7689. ChangeCallState( LINECALLSTATE_CONNECTED, 0 );
  7690. retVal = SendQ931Message( *pdwInvokeID, 0, 0,
  7691. FACILITYMESSAGETYPE,
  7692. REMOTERETRIEVE_OPCODE| H450_RETURNRESULT );
  7693. }
  7694. break;
  7695. default:
  7696. _ASSERTE( 0 );
  7697. return FALSE;
  7698. }
  7699. break;
  7700. case H4503ROS_returnResult_chosen:
  7701. *pdwH450APDUType = H4503_DUMMYTYPERETURNRESULT_APDU;
  7702. *pdwInvokeID =
  7703. pH450APDUStruct->serviceApdu.u.rosApdus->value.u.returnResult.invokeId;
  7704. retVal = HandleReturnResultDummyType( pH450APDUStruct );
  7705. // Free the PDU data.
  7706. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pH450APDUStruct,
  7707. H4501SupplementaryService_PDU );
  7708. break;
  7709. case H4503ROS_returnError_chosen:
  7710. *pdwH450APDUType = H4503_RETURNERROR_APDU;
  7711. *pdwInvokeID =
  7712. pH450APDUStruct->serviceApdu.u.rosApdus->value.u.returnError.invokeId;
  7713. retVal = HandleReturnError( pH450APDUStruct );
  7714. // Free the PDU data.
  7715. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pH450APDUStruct,
  7716. H4501SupplementaryService_PDU );
  7717. break;
  7718. case reject_chosen:
  7719. *pdwH450APDUType = H4503_REJECT_APDU;
  7720. *pdwInvokeID =
  7721. pH450APDUStruct->serviceApdu.u.rosApdus->value.u.reject.invokeId;
  7722. retVal = HandleReject( pH450APDUStruct );
  7723. // Free the PDU data.
  7724. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pH450APDUStruct,
  7725. H4501SupplementaryService_PDU );
  7726. break;
  7727. default:
  7728. _ASSERTE( 0 );
  7729. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pH450APDUStruct,
  7730. H4501SupplementaryService_PDU );
  7731. return FALSE;
  7732. break;
  7733. }
  7734. if( retVal == FALSE )
  7735. {
  7736. SendQ931Message( *pdwInvokeID,
  7737. 0,
  7738. 0,
  7739. RELEASECOMPLMESSAGETYPE,
  7740. H450_REJECT );
  7741. }
  7742. H323DBG(( DEBUG_LEVEL_TRACE, "HandleH450APDU exited:%p.", this ));
  7743. return retVal;
  7744. }
  7745. BOOL
  7746. CH323Call::HandleReturnError(
  7747. IN H4501SupplementaryService * pH450APDUStruct
  7748. )
  7749. {
  7750. H323DBG(( DEBUG_LEVEL_TRACE, "HandleReturnError entered:%p.", this ));
  7751. ReturnError * pReturnError =
  7752. &(pH450APDUStruct->serviceApdu.u.rosApdus->value.u.returnError);
  7753. if( IsValidInvokeID( pReturnError->invokeId ) == FALSE )
  7754. {
  7755. //ignore APDU
  7756. return TRUE;
  7757. }
  7758. CloseCall( 0 );
  7759. H323DBG(( DEBUG_LEVEL_TRACE, "HandleReturnError exited:%p.", this ));
  7760. return TRUE;
  7761. }
  7762. BOOL
  7763. CH323Call::HandleReject(
  7764. IN H4501SupplementaryService * pH450APDUStruct
  7765. )
  7766. {
  7767. H323DBG(( DEBUG_LEVEL_TRACE, "HandleReject entered:%p.", this ));
  7768. Reject * pReject =
  7769. &(pH450APDUStruct->serviceApdu.u.rosApdus->value.u.reject);
  7770. if( IsValidInvokeID( pReject->invokeId ) == FALSE )
  7771. {
  7772. //ignore the APDU
  7773. return TRUE;
  7774. }
  7775. CloseCall( 0 );
  7776. H323DBG(( DEBUG_LEVEL_TRACE, "HandleReject exited:%p.", this ));
  7777. return TRUE;
  7778. }
  7779. BOOL
  7780. CH323Call::HandleReturnResultDummyType(
  7781. IN H4501SupplementaryService * pH450APDUStruct
  7782. )
  7783. {
  7784. H323DBG(( DEBUG_LEVEL_TRACE, "HandleReturnResultDummyType entered:%p.",
  7785. this ));
  7786. ReturnResult* dummyResult =
  7787. &(pH450APDUStruct->serviceApdu.u.rosApdus->value.u.returnResult);
  7788. if( dummyResult->bit_mask & result_present )
  7789. {
  7790. if( dummyResult->result.opcode.choice != local_chosen )
  7791. {
  7792. return FALSE;
  7793. }
  7794. switch( dummyResult->result.opcode.u.local )
  7795. {
  7796. case CHECKRESTRICTION_OPCODE:
  7797. //forwarding has been enabled. inform the user
  7798. if( !EnableCallForwarding() )
  7799. {
  7800. return FALSE;
  7801. }
  7802. //close the call
  7803. CloseCall( 0 );
  7804. break;
  7805. case CALLREROUTING_OPCODE:
  7806. //call has been rerouted. log the info or inform the user
  7807. m_dwCallDiversionState = H4503_CALLREROUTING_RRSUCC;
  7808. _ASSERTE( m_hCallReroutingTimer );
  7809. if( m_hCallReroutingTimer != NULL )
  7810. {
  7811. DeleteTimerQueueTimer( H323TimerQueue,
  7812. m_hCallReroutingTimer, NULL );
  7813. m_hCallReroutingTimer = NULL;
  7814. }
  7815. break;
  7816. case CTIDENTIFY_OPCODE:
  7817. //call tranfer has been accepted by transfered-to endpoint
  7818. m_dwCallDiversionState = H4502_CIIDENTIFY_RRSUCC;
  7819. _ASSERTE( m_hCTIdentifyTimer );
  7820. if( m_hCTIdentifyTimer != NULL )
  7821. {
  7822. DeleteTimerQueueTimer( H323TimerQueue, m_hCTIdentifyTimer, NULL );
  7823. m_hCTIdentifyTimer = NULL;
  7824. }
  7825. return HandleCTIdentifyReturnResult( dummyResult->result.result.value,
  7826. dummyResult->result.result.length );
  7827. break;
  7828. case CTINITIATE_OPCODE:
  7829. _ASSERTE( m_hCTInitiateTimer );
  7830. if( m_hCTInitiateTimer != NULL )
  7831. {
  7832. DeleteTimerQueueTimer( H323TimerQueue, m_hCTInitiateTimer, NULL );
  7833. m_hCTInitiateTimer = NULL;
  7834. }
  7835. break;
  7836. case CTSETUP_OPCODE:
  7837. case REMOTEHOLD_OPCODE:
  7838. case REMOTERETRIEVE_OPCODE:
  7839. //no processing required
  7840. break;
  7841. default:
  7842. H323DBG(( DEBUG_LEVEL_ERROR, "wrong opcode.",
  7843. dummyResult->result.opcode.u.local ));
  7844. break;
  7845. }
  7846. }
  7847. else if( IsValidInvokeID( dummyResult->invokeId ) == FALSE )
  7848. {
  7849. return FALSE;
  7850. }
  7851. H323DBG(( DEBUG_LEVEL_TRACE, "HandleReturnResultDummyType exited:%p.",
  7852. this ));
  7853. return TRUE;
  7854. }
  7855. BOOL
  7856. CH323Call::EnableCallForwarding()
  7857. {
  7858. m_dwCallDiversionState = H4503_CHECKRESTRICTION_SUCC;
  7859. if( m_pCallForwardParams != NULL )
  7860. {
  7861. g_pH323Line->SetCallForwardParams( m_pCallForwardParams );
  7862. m_pCallForwardParams = NULL;
  7863. }
  7864. else if( m_pForwardAddress != NULL )
  7865. {
  7866. if( !g_pH323Line->SetCallForwardParams( m_pForwardAddress ) )
  7867. {
  7868. return FALSE;
  7869. }
  7870. m_pForwardAddress = NULL;
  7871. }
  7872. //_ASSERTE( m_hCheckRestrictionTimer );
  7873. //stop the timer
  7874. if( m_hCheckRestrictionTimer )
  7875. {
  7876. DeleteTimerQueueTimer( H323TimerQueue, m_hCheckRestrictionTimer,
  7877. NULL );
  7878. m_hCheckRestrictionTimer = NULL;
  7879. }
  7880. //inform the user about change in line forward state
  7881. (*g_pfnLineEventProc)(
  7882. g_pH323Line->m_htLine,
  7883. (HTAPICALL)NULL,
  7884. (DWORD)LINE_ADDRESSSTATE,
  7885. (DWORD)LINEADDRESSSTATE_FORWARD,
  7886. (DWORD)LINEADDRESSSTATE_FORWARD,
  7887. (DWORD)0
  7888. );
  7889. return TRUE;
  7890. }
  7891. BOOL
  7892. CH323Call::HandleCTIdentifyReturnResult(
  7893. IN BYTE * pEncodeArg,
  7894. IN DWORD dwEncodedArgLen
  7895. )
  7896. {
  7897. PH323_CALL pCall = NULL;
  7898. CTIdentifyRes * pCTIdentifyRes;
  7899. int iResult;
  7900. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCTIdentifyReturnResult entered:%p.", this ));
  7901. if( (pEncodeArg == NULL) || (dwEncodedArgLen==0) )
  7902. {
  7903. return FALSE;
  7904. }
  7905. iResult = DecodeH450ASN( (void **) &pCTIdentifyRes,
  7906. CTIdentifyRes_PDU, pEncodeArg, dwEncodedArgLen );
  7907. if( ASN1_FAILED(iResult) || (pCTIdentifyRes == NULL) )
  7908. {
  7909. return FALSE;
  7910. }
  7911. //send a CTInitiate message on the primary call
  7912. if( !QueueSuppServiceWorkItem( SEND_CTINITIATE_MESSAGE, m_hdRelatedCall,
  7913. (ULONG_PTR)pCTIdentifyRes ))
  7914. {
  7915. //close the consultation call.
  7916. CloseCall( 0 );
  7917. }
  7918. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCTIdentifyReturnResult exited:%p.", this ));
  7919. return TRUE;
  7920. }
  7921. BOOL
  7922. CH323Call::HandleCTIdentify(
  7923. IN DWORD dwInvokeID
  7924. )
  7925. {
  7926. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCTIdentify entered:%p.", this ));
  7927. BOOL retVal = TRUE;
  7928. //send the return result for CTIdentify
  7929. retVal = SendQ931Message( dwInvokeID, 0, 0, FACILITYMESSAGETYPE,
  7930. H450_RETURNRESULT|CTIDENTIFY_OPCODE );
  7931. m_dwCallType |= CALLTYPE_TRANSFERED2_CONSULT;
  7932. //start the timer for CTIdenity message
  7933. if( retVal )
  7934. {
  7935. retVal = CreateTimerQueueTimer(
  7936. &m_hCTIdentifyRRTimer,
  7937. H323TimerQueue,
  7938. CH323Call::CTIdentifyRRExpiredCallback,
  7939. (PVOID)m_hdCall,
  7940. CTIDENTIFYRR_SENT_TIMEOUT, 0,
  7941. WT_EXECUTEINIOTHREAD | WT_EXECUTEONLYONCE );
  7942. }
  7943. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCTIdentify exited:%p.", this ));
  7944. return retVal;
  7945. }
  7946. BOOL
  7947. CH323Call::HandleCTInitiate(
  7948. IN BYTE * pEncodeArg,
  7949. IN DWORD dwEncodedArgLen
  7950. )
  7951. {
  7952. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCTInitiate entered:%p.", this ));
  7953. CTInitiateArg * pCTInitiateArg;
  7954. int iResult = DecodeH450ASN( (void **) &pCTInitiateArg,
  7955. CTInitiateArg_PDU,
  7956. pEncodeArg, dwEncodedArgLen );
  7957. if( ASN1_FAILED(iResult) || (pCTInitiateArg == NULL) )
  7958. {
  7959. return FALSE;
  7960. }
  7961. //argument.callIdentity
  7962. CopyMemory( (PVOID)m_pCTCallIdentity, pCTInitiateArg->callIdentity,
  7963. sizeof(m_pCTCallIdentity) );
  7964. //argument.reroutingNumber
  7965. if( !AliasAddrToAliasNames( &m_pTransferedToAlias,
  7966. (PSetup_UUIE_sourceAddress)
  7967. pCTInitiateArg->reroutingNumber.destinationAddress ) )
  7968. {
  7969. goto cleanup;
  7970. }
  7971. m_dwCallType |= CALLTYPE_TRANSFERED_PRIMARY;
  7972. m_dwCallDiversionState = H4502_CTINITIATE_RECV;
  7973. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pCTInitiateArg,
  7974. CTInitiateArg_PDU );
  7975. //queue an event for creating a new call
  7976. if( !QueueSuppServiceWorkItem( TSPI_DIAL_TRNASFEREDCALL, m_hdCall,
  7977. (ULONG_PTR)m_pTransferedToAlias ))
  7978. {
  7979. H323DBG(( DEBUG_LEVEL_TRACE, "could not post dial transfer event." ));
  7980. }
  7981. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCTInitiate exited:%p.", this ));
  7982. return TRUE;
  7983. cleanup:
  7984. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pCTInitiateArg,
  7985. CTInitiateArg_PDU );
  7986. return FALSE;
  7987. }
  7988. //!!always called in a lock
  7989. BOOL
  7990. CH323Call::HandleCTSetup(
  7991. IN BYTE * pEncodeArg,
  7992. IN DWORD dwEncodedArgLen
  7993. )
  7994. {
  7995. PH323_CALL pCall = NULL;
  7996. WORD wRelatedCallRef = 0;
  7997. int iCTCallID;
  7998. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCTSetup entered:%p.", this ));
  7999. CTSetupArg * pCTSetupArg;
  8000. int iResult = DecodeH450ASN( (void **) &pCTSetupArg,
  8001. CTSetupArg_PDU, pEncodeArg, dwEncodedArgLen );
  8002. if( ASN1_FAILED(iResult) || (pCTSetupArg == NULL) )
  8003. {
  8004. return FALSE;
  8005. }
  8006. m_dwCallType |= CALLTYPE_TRANSFEREDDEST;
  8007. m_dwCallDiversionState = H4502_CTSETUP_RECV;
  8008. iCTCallID = atoi( pCTSetupArg->callIdentity );
  8009. if( iCTCallID != 0 )
  8010. {
  8011. m_hdRelatedCall = g_pH323Line -> GetCallFromCTCallIdentity( iCTCallID );
  8012. if( m_hdRelatedCall )
  8013. {
  8014. if( !QueueSuppServiceWorkItem( STOP_CTIDENTIFYRR_TIMER,
  8015. m_hdRelatedCall, (ULONG_PTR)m_hdCall ))
  8016. {
  8017. m_hdRelatedCall = NULL;
  8018. }
  8019. }
  8020. }
  8021. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pCTSetupArg,
  8022. CTSetupArg_PDU );
  8023. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCTSEtup exited:%p.", this ));
  8024. return TRUE;
  8025. }
  8026. BOOL
  8027. CH323Call::HandleCheckRestriction(
  8028. IN BYTE * pEncodeArg,
  8029. IN DWORD dwEncodedArgLen,
  8030. IN Q931_SETUP_ASN* pSetupASN
  8031. )
  8032. {
  8033. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCheckRestriction entered:%p.", this ));
  8034. CheckRestrictionArgument * pCheckRestriction;
  8035. int iResult = DecodeH450ASN( (void **) &pCheckRestriction,
  8036. CheckRestrictionArgument_PDU,
  8037. pEncodeArg, dwEncodedArgLen );
  8038. if( ASN1_FAILED(iResult) || (pCheckRestriction == NULL) )
  8039. {
  8040. return FALSE;
  8041. }
  8042. if( pSetupASN->pCalleeAliasList != NULL )
  8043. {
  8044. FreeAliasNames( pSetupASN->pCalleeAliasList );
  8045. pSetupASN->pCalleeAliasList = NULL;
  8046. }
  8047. if( !AliasAddrToAliasNames( &(pSetupASN->pCalleeAliasList),
  8048. (PSetup_UUIE_sourceAddress)pCheckRestriction->divertedToNr.destinationAddress ) )
  8049. {
  8050. pSetupASN->pCalleeAliasList = NULL;
  8051. goto cleanup;
  8052. }
  8053. if( pSetupASN->pCallerAliasList != NULL )
  8054. {
  8055. FreeAliasNames( pSetupASN->pCallerAliasList );
  8056. pSetupASN->pCallerAliasList = NULL;
  8057. }
  8058. if( !AliasAddrToAliasNames( &(pSetupASN->pCallerAliasList),
  8059. (PSetup_UUIE_sourceAddress)
  8060. pCheckRestriction->servedUserNr.destinationAddress ) )
  8061. {
  8062. pSetupASN->pCallerAliasList = NULL;
  8063. goto cleanup;
  8064. }
  8065. m_dwCallType |= CALLTYPE_FORWARDCONSULT;
  8066. if( !InitializeIncomingCall( pSetupASN, CALLTYPE_FORWARDCONSULT, 0 ) )
  8067. {
  8068. goto cleanup;
  8069. }
  8070. FreeSetupASN( pSetupASN );
  8071. m_dwStateMachine = Q931_SETUP_RECVD;
  8072. m_dwCallDiversionState = H4503_CHECKRESTRICTION_RECV;
  8073. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pCheckRestriction,
  8074. CheckRestrictionArgument_PDU );
  8075. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCheckRestriction exited:%p.", this ));
  8076. return TRUE;
  8077. cleanup:
  8078. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pCheckRestriction,
  8079. CheckRestrictionArgument_PDU );
  8080. return FALSE;
  8081. }
  8082. BOOL
  8083. CH323Call::HandleDiversionLegInfo1(
  8084. IN BYTE * pEncodeArg,
  8085. IN DWORD dwEncodedArgLen
  8086. )
  8087. {
  8088. H323DBG(( DEBUG_LEVEL_TRACE, "HandleDiversionLegInfo1 entered:%p.", this ));
  8089. DivertingLegInformation1Argument * plegInfo1Invoke;
  8090. int iResult = DecodeH450ASN( (void **) &plegInfo1Invoke,
  8091. DivertingLegInformation1Argument_PDU,
  8092. pEncodeArg, dwEncodedArgLen );
  8093. if( ASN1_FAILED(iResult) || (plegInfo1Invoke == NULL) )
  8094. {
  8095. return FALSE;
  8096. }
  8097. if( m_pCallReroutingInfo == NULL )
  8098. {
  8099. m_pCallReroutingInfo = new CALLREROUTINGINFO;
  8100. if( m_pCallReroutingInfo == NULL )
  8101. {
  8102. return FALSE;
  8103. }
  8104. ZeroMemory( (PVOID)m_pCallReroutingInfo, sizeof(CALLREROUTINGINFO) );
  8105. }
  8106. m_pCallReroutingInfo->diversionReason = plegInfo1Invoke->diversionReason;
  8107. m_pCallReroutingInfo->fPresentAllow = plegInfo1Invoke->subscriptionOption;
  8108. //argument.divertedToNr
  8109. if( m_pCallReroutingInfo->divertedToNrAlias != NULL )
  8110. {
  8111. FreeAliasNames( m_pCallReroutingInfo->divertedToNrAlias );
  8112. m_pCallReroutingInfo->divertedToNrAlias = NULL;
  8113. }
  8114. if( !AliasAddrToAliasNames( &(m_pCallReroutingInfo->divertedToNrAlias),
  8115. (PSetup_UUIE_sourceAddress)
  8116. (plegInfo1Invoke->nominatedNr.destinationAddress) ) )
  8117. {
  8118. goto cleanup;
  8119. }
  8120. m_dwCallType |= CALLTYPE_DIVERTEDSRC_NOROUTING;
  8121. m_dwCallDiversionState = H4503_DIVERSIONLEG1_RECVD;
  8122. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, plegInfo1Invoke,
  8123. DivertingLegInformation1Argument_PDU );
  8124. H323DBG(( DEBUG_LEVEL_TRACE, "HandleDiversionLegInfo1 exited:%p.", this ));
  8125. return TRUE;
  8126. cleanup:
  8127. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, plegInfo1Invoke,
  8128. DivertingLegInformation1Argument_PDU );
  8129. FreeCallReroutingInfo();
  8130. return FALSE;
  8131. }
  8132. BOOL
  8133. CH323Call::HandleDiversionLegInfo2(
  8134. IN BYTE * pEncodeArg,
  8135. IN DWORD dwEncodedArgLen
  8136. )
  8137. {
  8138. H323DBG(( DEBUG_LEVEL_TRACE, "HandleDiversionLegInfo2 entered:%p.", this ));
  8139. DivertingLegInformation2Argument * plegInfo2Invoke;
  8140. int iResult = DecodeH450ASN( (void **) &plegInfo2Invoke,
  8141. DivertingLegInformation2Argument_PDU,
  8142. pEncodeArg, dwEncodedArgLen );
  8143. if( ASN1_FAILED(iResult) || (plegInfo2Invoke == NULL) )
  8144. {
  8145. return FALSE;
  8146. }
  8147. _ASSERTE(!m_pCallReroutingInfo);
  8148. m_pCallReroutingInfo = new CALLREROUTINGINFO;
  8149. if( m_pCallReroutingInfo == NULL )
  8150. {
  8151. H323DBG(( DEBUG_LEVEL_TRACE, "memory failure." ));
  8152. goto cleanup;
  8153. }
  8154. ZeroMemory( (PVOID)m_pCallReroutingInfo, sizeof(CALLREROUTINGINFO) );
  8155. //argument.diversionCounter
  8156. m_pCallReroutingInfo->diversionCounter =
  8157. plegInfo2Invoke->diversionCounter;
  8158. //argument.diversionReason
  8159. m_pCallReroutingInfo->diversionReason = plegInfo2Invoke->diversionReason;
  8160. if( m_pCallReroutingInfo->divertingNrAlias != NULL )
  8161. {
  8162. FreeAliasNames( m_pCallReroutingInfo->divertingNrAlias );
  8163. m_pCallReroutingInfo->divertingNrAlias = NULL;
  8164. }
  8165. if( (plegInfo2Invoke->bit_mask & divertingNr_present ) &&
  8166. plegInfo2Invoke->divertingNr.destinationAddress )
  8167. {
  8168. //argument.divertingNr
  8169. if( !AliasAddrToAliasNames( &(m_pCallReroutingInfo->divertingNrAlias),
  8170. (PSetup_UUIE_sourceAddress)
  8171. (plegInfo2Invoke->divertingNr.destinationAddress) ) )
  8172. {
  8173. H323DBG(( DEBUG_LEVEL_TRACE, "no divertingnr alias." ));
  8174. //goto cleanup;
  8175. }
  8176. }
  8177. //argument.originalCalledNr
  8178. if( (plegInfo2Invoke->bit_mask &
  8179. DivertingLegInformation2Argument_originalCalledNr_present ) &&
  8180. plegInfo2Invoke->originalCalledNr.destinationAddress )
  8181. {
  8182. if( m_pCallReroutingInfo->originalCalledNr != NULL )
  8183. {
  8184. FreeAliasNames( m_pCallReroutingInfo->originalCalledNr );
  8185. m_pCallReroutingInfo->originalCalledNr = NULL;
  8186. }
  8187. if( !AliasAddrToAliasNames( &(m_pCallReroutingInfo->originalCalledNr),
  8188. (PSetup_UUIE_sourceAddress)
  8189. (plegInfo2Invoke->originalCalledNr.destinationAddress)) )
  8190. {
  8191. H323DBG(( DEBUG_LEVEL_TRACE, "no originalcalled alias." ));
  8192. //goto cleanup;
  8193. }
  8194. }
  8195. m_dwCallType |= CALLTYPE_DIVERTEDDEST;
  8196. m_dwCallDiversionState = H4503_DIVERSIONLEG2_RECVD;
  8197. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, plegInfo2Invoke,
  8198. DivertingLegInformation2Argument_PDU );
  8199. H323DBG(( DEBUG_LEVEL_TRACE, "HandleDiversionLegInfo2 exited:%p.", this ));
  8200. return TRUE;
  8201. cleanup:
  8202. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, plegInfo2Invoke,
  8203. DivertingLegInformation2Argument_PDU );
  8204. FreeCallReroutingInfo();
  8205. return FALSE;
  8206. }
  8207. void
  8208. CH323Call::FreeCallReroutingInfo(void)
  8209. {
  8210. H323DBG(( DEBUG_LEVEL_TRACE, "FreeCallReroutingInfo entered:%p.", this ));
  8211. if( m_pCallReroutingInfo != NULL )
  8212. {
  8213. FreeAliasNames( m_pCallReroutingInfo->divertingNrAlias );
  8214. FreeAliasNames( m_pCallReroutingInfo->originalCalledNr );
  8215. FreeAliasNames( m_pCallReroutingInfo->divertedToNrAlias );
  8216. FreeAliasNames( m_pCallReroutingInfo->diversionNrAlias );
  8217. delete m_pCallReroutingInfo;
  8218. m_pCallReroutingInfo = NULL;
  8219. }
  8220. H323DBG(( DEBUG_LEVEL_TRACE, "FreeCallReroutingInfo exited:%p.", this ));
  8221. }
  8222. BOOL
  8223. CH323Call::HandleDiversionLegInfo3(
  8224. IN BYTE * pEncodeArg,
  8225. IN DWORD dwEncodedArgLen
  8226. )
  8227. {
  8228. H323DBG(( DEBUG_LEVEL_TRACE, "HandleDiversionLegInfo3 entered:%p.", this ));
  8229. DivertingLegInformation3Argument * plegInfo3Invoke;
  8230. int iResult = DecodeH450ASN( (void **) &plegInfo3Invoke,
  8231. DivertingLegInformation3Argument_PDU,
  8232. pEncodeArg, dwEncodedArgLen );
  8233. if( ASN1_FAILED(iResult) || (plegInfo3Invoke == NULL) )
  8234. {
  8235. return FALSE;
  8236. }
  8237. _ASSERTE(m_pCallReroutingInfo);
  8238. m_pCallReroutingInfo-> fPresentAllow =
  8239. plegInfo3Invoke->presentationAllowedIndicator;
  8240. if( m_pCallReroutingInfo->diversionNrAlias )
  8241. {
  8242. FreeAliasNames( m_pCallReroutingInfo->diversionNrAlias );
  8243. m_pCallReroutingInfo->diversionNrAlias = NULL;
  8244. }
  8245. //argument.redirectionNr
  8246. if( (plegInfo3Invoke->bit_mask & redirectionNr_present ) &&
  8247. plegInfo3Invoke->redirectionNr.destinationAddress )
  8248. {
  8249. if( !AliasAddrToAliasNames( &(m_pCallReroutingInfo->diversionNrAlias),
  8250. (PSetup_UUIE_sourceAddress)
  8251. (plegInfo3Invoke->redirectionNr.destinationAddress) ) )
  8252. {
  8253. //goto cleanup;
  8254. }
  8255. }
  8256. _ASSERTE( (m_dwCallType & CALLTYPE_DIVERTEDSRC ) ||
  8257. (m_dwCallType & CALLTYPE_DIVERTEDSRC_NOROUTING ) );
  8258. m_dwCallDiversionState = H4503_DIVERSIONLEG3_RECVD;
  8259. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, plegInfo3Invoke,
  8260. DivertingLegInformation3Argument_PDU );
  8261. H323DBG(( DEBUG_LEVEL_TRACE, "HandleDiversionLegInfo3 exited:%p.", this ));
  8262. return TRUE;
  8263. /*cleanup:
  8264. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, plegInfo3Invoke,
  8265. DivertingLegInformation3Argument_PDU );
  8266. FreeCallReroutingInfo();
  8267. return FALSE;
  8268. */
  8269. }
  8270. BOOL
  8271. CH323Call::HandleCallRerouting(
  8272. IN BYTE * pEncodeArg,
  8273. IN DWORD dwEncodedArgLen
  8274. )
  8275. {
  8276. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCallRerouting entered:%p.", this ));
  8277. CallReroutingArgument* pCallReroutingInv;
  8278. int iResult = DecodeH450ASN( (void **) &pCallReroutingInv,
  8279. CallReroutingArgument_PDU,
  8280. pEncodeArg, dwEncodedArgLen );
  8281. if( ASN1_FAILED(iResult) || (pCallReroutingInv == NULL) )
  8282. {
  8283. return FALSE;
  8284. }
  8285. if( m_pCallReroutingInfo == NULL )
  8286. {
  8287. m_pCallReroutingInfo = new CALLREROUTINGINFO;
  8288. if( m_pCallReroutingInfo == NULL )
  8289. {
  8290. goto cleanup;
  8291. }
  8292. ZeroMemory( (PVOID)m_pCallReroutingInfo, sizeof(CALLREROUTINGINFO) );
  8293. }
  8294. if( pCallReroutingInv->diversionCounter > MAX_DIVERSION_COUNTER )
  8295. return FALSE;
  8296. m_pCallReroutingInfo->diversionCounter =
  8297. pCallReroutingInv->diversionCounter;
  8298. m_pCallReroutingInfo->diversionReason = pCallReroutingInv->reroutingReason;
  8299. if( pCallReroutingInv->bit_mask & originalReroutingReason_present )
  8300. {
  8301. m_pCallReroutingInfo->originalDiversionReason =
  8302. pCallReroutingInv->originalReroutingReason;
  8303. }
  8304. else
  8305. {
  8306. m_pCallReroutingInfo->originalDiversionReason =
  8307. pCallReroutingInv->reroutingReason;
  8308. }
  8309. if( ( pCallReroutingInv->bit_mask &
  8310. CallReroutingArgument_originalCalledNr_present ) &&
  8311. pCallReroutingInv->originalCalledNr.destinationAddress )
  8312. {
  8313. if( m_pCallReroutingInfo->originalCalledNr != NULL )
  8314. {
  8315. FreeAliasNames( m_pCallReroutingInfo->originalCalledNr );
  8316. m_pCallReroutingInfo->originalCalledNr = NULL;
  8317. }
  8318. if( !AliasAddrToAliasNames( &(m_pCallReroutingInfo->originalCalledNr),
  8319. (PSetup_UUIE_sourceAddress)
  8320. (pCallReroutingInv->originalCalledNr.destinationAddress) ) )
  8321. {
  8322. //goto cleanup;
  8323. }
  8324. }
  8325. if( m_pCallReroutingInfo->divertingNrAlias != NULL )
  8326. {
  8327. FreeAliasNames( m_pCallReroutingInfo->divertingNrAlias );
  8328. m_pCallReroutingInfo->divertingNrAlias = NULL;
  8329. }
  8330. if( !AliasAddrToAliasNames( &(m_pCallReroutingInfo->divertingNrAlias),
  8331. (PSetup_UUIE_sourceAddress)
  8332. (pCallReroutingInv->lastReroutingNr.destinationAddress) ) )
  8333. {
  8334. goto cleanup;
  8335. }
  8336. if( m_pCallReroutingInfo->divertedToNrAlias != NULL )
  8337. {
  8338. FreeAliasNames( m_pCallReroutingInfo->divertedToNrAlias );
  8339. m_pCallReroutingInfo->divertedToNrAlias = NULL;
  8340. }
  8341. if( !AliasAddrToAliasNames( &(m_pCallReroutingInfo->divertedToNrAlias),
  8342. (PSetup_UUIE_sourceAddress)
  8343. (pCallReroutingInv->calledAddress.destinationAddress) ) )
  8344. {
  8345. goto cleanup;
  8346. }
  8347. m_dwCallType |= CALLTYPE_DIVERTEDSRC;
  8348. m_dwCallDiversionState = H4503_CALLREROUTING_RECVD;
  8349. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pCallReroutingInv,
  8350. CallReroutingArgument_PDU );
  8351. H323DBG(( DEBUG_LEVEL_TRACE, "HandleCallRerouting exited:%p.", this ));
  8352. return TRUE;
  8353. cleanup:
  8354. ASN1_FreeDecoded( m_H450ASNCoderInfo.pDecInfo, pCallReroutingInv,
  8355. CallReroutingArgument_PDU );
  8356. FreeCallReroutingInfo();
  8357. return FALSE;
  8358. }
  8359. BOOL
  8360. CH323Call::EncodeRejectAPDU(
  8361. IN H4501SupplementaryService * pSupplementaryServiceAPDU,
  8362. IN DWORD dwInvokeID,
  8363. OUT BYTE** ppEncodedAPDU,
  8364. OUT DWORD* pdwAPDULen
  8365. )
  8366. {
  8367. WORD wAPDULen;
  8368. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeRejectAPDU entered:%p.", this ));
  8369. ServiceApdus_rosApdus *pROSAPDU =
  8370. pSupplementaryServiceAPDU->serviceApdu.u.rosApdus;
  8371. pROSAPDU->next = NULL;
  8372. pROSAPDU->value.choice = reject_chosen;
  8373. pROSAPDU->value.u.reject.invokeId = (WORD)dwInvokeID;
  8374. pROSAPDU->value.u.reject.problem.choice = H4503ROS_invoke_chosen;
  8375. pROSAPDU->value.u.reject.problem.u.invoke = InvokeProblem_mistypedArgument;
  8376. //call ASN.1 encoding functions
  8377. int rc = EncodeH450ASN( (void *) pSupplementaryServiceAPDU,
  8378. H4501SupplementaryService_PDU,
  8379. ppEncodedAPDU,
  8380. &wAPDULen );
  8381. *pdwAPDULen = wAPDULen;
  8382. if( ASN1_FAILED(rc) || (*ppEncodedAPDU == NULL) || (pdwAPDULen == 0) )
  8383. {
  8384. return FALSE;
  8385. }
  8386. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeRejectAPDU exited:%p.", this ));
  8387. return TRUE;
  8388. }
  8389. BOOL
  8390. CH323Call::EncodeReturnErrorAPDU(
  8391. IN DWORD dwInvokeID,
  8392. IN DWORD dwErrorCode,
  8393. IN H4501SupplementaryService *pH450APDU,
  8394. OUT BYTE** ppEncodedAPDU,
  8395. OUT DWORD* pdwAPDULen
  8396. )
  8397. {
  8398. WORD wAPDULen;
  8399. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeReturnErrorAPDU entered:%p.", this ));
  8400. ServiceApdus_rosApdus *pROSAPDU = pH450APDU->serviceApdu.u.rosApdus;
  8401. pROSAPDU->next = NULL;
  8402. pROSAPDU ->value.choice = H4503ROS_returnError_chosen;
  8403. pROSAPDU ->value.u.returnError.invokeId = (WORD)dwInvokeID;
  8404. pROSAPDU ->value.u.returnError.errcode.choice = local_chosen;
  8405. pROSAPDU ->value.u.returnError.errcode.u.local = dwErrorCode;
  8406. //call ASN.1 encoding functions
  8407. int rc = EncodeH450ASN( (void *) pH450APDU,
  8408. H4501SupplementaryService_PDU,
  8409. ppEncodedAPDU,
  8410. &wAPDULen );
  8411. *pdwAPDULen = wAPDULen;
  8412. if( ASN1_FAILED(rc) || (*ppEncodedAPDU == NULL) || (pdwAPDULen == 0) )
  8413. {
  8414. return FALSE;
  8415. }
  8416. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeReturnErrorAPDU exited:%p.", this ));
  8417. return TRUE;
  8418. }
  8419. BOOL
  8420. CH323Call::EncodeDummyReturnResultAPDU(
  8421. IN DWORD dwInvokeID,
  8422. IN DWORD dwOpCode,
  8423. IN H4501SupplementaryService *pH450APDU,
  8424. OUT BYTE** ppEncodedAPDU,
  8425. OUT DWORD* pdwAPDULen
  8426. )
  8427. {
  8428. BYTE pBufEncodedArg[H450_ENCODED_ARG_LEN];
  8429. WORD wEncodedLen = 0;
  8430. int rc;
  8431. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeDummyReturnResultAPDU entered:%p.",
  8432. this ));
  8433. ServiceApdus_rosApdus *pROSAPDU = pH450APDU->serviceApdu.u.rosApdus;
  8434. pROSAPDU->next = NULL;
  8435. pROSAPDU ->value.choice = H4503ROS_returnResult_chosen;
  8436. pROSAPDU ->value.u.returnResult.invokeId = (WORD)dwInvokeID;
  8437. pROSAPDU ->value.u.returnResult.bit_mask = result_present;
  8438. pROSAPDU ->value.u.returnResult.result.opcode.choice = local_chosen;
  8439. pROSAPDU ->value.u.returnResult.result.opcode.u.local = dwOpCode;
  8440. //dummy result not present
  8441. pROSAPDU ->value.u.returnResult.result.result.length = 0;
  8442. pROSAPDU ->value.u.returnResult.result.result.value = NULL;
  8443. switch( dwOpCode )
  8444. {
  8445. case CTIDENTIFY_OPCODE:
  8446. pROSAPDU ->value.u.returnResult.result.result.value = pBufEncodedArg;
  8447. if( !EncodeCTIdentifyReturnResult( pROSAPDU ) )
  8448. {
  8449. return FALSE;
  8450. }
  8451. break;
  8452. default:
  8453. pROSAPDU ->value.u.returnResult.result.result.value = pBufEncodedArg;
  8454. if( !EncodeDummyResult( pROSAPDU ) )
  8455. {
  8456. return FALSE;
  8457. }
  8458. break;
  8459. }
  8460. //call ASN.1 encoding functions
  8461. rc = EncodeH450ASN( (void *) pH450APDU,
  8462. H4501SupplementaryService_PDU,
  8463. ppEncodedAPDU,
  8464. &wEncodedLen );
  8465. *pdwAPDULen = wEncodedLen;
  8466. if( ASN1_FAILED(rc) || (*ppEncodedAPDU == NULL) || (pdwAPDULen == 0) )
  8467. {
  8468. return FALSE;
  8469. }
  8470. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeDummyReturnResultAPDU exited:%p.",
  8471. this ));
  8472. return TRUE;
  8473. }
  8474. BOOL
  8475. CH323Call::EncodeDummyResult(
  8476. OUT ServiceApdus_rosApdus *pROSAPDU
  8477. )
  8478. {
  8479. DummyRes dummyRes;
  8480. BYTE *pEncodedArg = NULL;
  8481. WORD wEncodedLen = 0;
  8482. int rc;
  8483. UCHAR sData[3] = "MS";
  8484. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeDummyResult entered:%p.", this ));
  8485. ZeroMemory( (PVOID)&dummyRes, sizeof(DummyRes) );
  8486. dummyRes.choice = DummyRes_nonStandardData_chosen;
  8487. dummyRes.u.nonStandardData.nonStandardIdentifier.choice
  8488. = H225NonStandardIdentifier_h221NonStandard_chosen;
  8489. dummyRes.u.nonStandardData.nonStandardIdentifier.u.h221NonStandard.t35CountryCode
  8490. = H221_COUNTRY_CODE_USA;
  8491. dummyRes.u.nonStandardData.nonStandardIdentifier.u.h221NonStandard.t35Extension
  8492. = H221_COUNTRY_EXT_USA;
  8493. dummyRes.u.nonStandardData.nonStandardIdentifier.u.h221NonStandard.manufacturerCode
  8494. = H221_MFG_CODE_MICROSOFT;
  8495. dummyRes.u.nonStandardData.data.length = 2;
  8496. dummyRes.u.nonStandardData.data.value = sData;
  8497. //encode the return result argument.
  8498. rc = EncodeH450ASN( (void*) &dummyRes,
  8499. DummyRes_PDU,
  8500. &pEncodedArg,
  8501. &wEncodedLen );
  8502. if( ASN1_FAILED(rc) || (pEncodedArg == NULL) || (wEncodedLen == 0) )
  8503. {
  8504. return FALSE;
  8505. }
  8506. pROSAPDU ->value.u.returnResult.result.result.length = wEncodedLen;
  8507. CopyMemory( (PVOID)pROSAPDU ->value.u.returnResult.result.result.value,
  8508. pEncodedArg, wEncodedLen );
  8509. //free the previous asn buffer before
  8510. ASN1_FreeEncoded(m_ASNCoderInfo.pEncInfo, pEncodedArg );
  8511. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeDummyResult exited:%p.", this ));
  8512. return TRUE;
  8513. }
  8514. BOOL
  8515. CH323Call::EncodeCTIdentifyReturnResult(
  8516. OUT ServiceApdus_rosApdus *pROSAPDU
  8517. )
  8518. {
  8519. CTIdentifyRes cTIdentifyRes;
  8520. BYTE *pEncodedArg = NULL;
  8521. WORD wEncodedLen = 0;
  8522. int iCallID;
  8523. int rc;
  8524. ZeroMemory( (PVOID)&cTIdentifyRes, sizeof(CTIdentifyRes) );
  8525. iCallID = g_pH323Line -> GetCTCallIdentity(m_hdCall );
  8526. if( iCallID == 0 )
  8527. {
  8528. return FALSE;
  8529. }
  8530. //argument.callIdentity
  8531. _itoa( iCallID, (char*)m_pCTCallIdentity, 10 );
  8532. CopyMemory( (PVOID)cTIdentifyRes.callIdentity, (PVOID)m_pCTCallIdentity,
  8533. sizeof(m_pCTCallIdentity) );
  8534. //argument.reroutingNumber
  8535. cTIdentifyRes.reroutingNumber.bit_mask = 0;
  8536. cTIdentifyRes.reroutingNumber.destinationAddress =
  8537. (PEndpointAddress_destinationAddress)
  8538. SetMsgAddressAlias( m_pCalleeAliasNames );
  8539. if( cTIdentifyRes.reroutingNumber.destinationAddress == NULL )
  8540. {
  8541. return FALSE;
  8542. }
  8543. //encode the return result argument.
  8544. rc = EncodeH450ASN( (void *) &cTIdentifyRes,
  8545. CTIdentifyRes_PDU,
  8546. &pEncodedArg,
  8547. &wEncodedLen );
  8548. if( ASN1_FAILED(rc) || (pEncodedArg == NULL) || (wEncodedLen == 0) )
  8549. {
  8550. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  8551. cTIdentifyRes.reroutingNumber.destinationAddress );
  8552. return FALSE;
  8553. }
  8554. pROSAPDU ->value.u.returnResult.result.result.length = wEncodedLen;
  8555. CopyMemory( (PVOID)pROSAPDU ->value.u.returnResult.result.result.value,
  8556. pEncodedArg, wEncodedLen );
  8557. //free the previous asn buffer before
  8558. ASN1_FreeEncoded(m_ASNCoderInfo.pEncInfo, pEncodedArg );
  8559. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  8560. cTIdentifyRes.reroutingNumber.destinationAddress );
  8561. return TRUE;
  8562. }
  8563. //supplemantary services functions
  8564. BOOL
  8565. CH323Call::EncodeCheckRestrictionAPDU(
  8566. OUT H4501SupplementaryService *pSupplementaryServiceAPDU,
  8567. OUT BYTE** ppEncodedAPDU,
  8568. OUT DWORD* pdwAPDULen
  8569. )
  8570. {
  8571. BYTE *pEncodedArg = NULL;
  8572. WORD wEncodedLen = 0;
  8573. BYTE pBufEncodedArg[H450_ENCODED_ARG_LEN];
  8574. BOOL retVal = FALSE;
  8575. int rc = 0;
  8576. TCHAR szMsg[20];
  8577. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeCheckRestrictionAPDU entered:%p.",
  8578. this ));
  8579. ServiceApdus_rosApdus *pROSAPDU =
  8580. pSupplementaryServiceAPDU->serviceApdu.u.rosApdus;
  8581. pROSAPDU->next = NULL;
  8582. pROSAPDU->value.choice = H4503ROS_invoke_chosen;
  8583. pROSAPDU->value.u.invoke.bit_mask = argument_present;
  8584. //invoke ID
  8585. pROSAPDU->value.u.invoke.invokeId = g_pH323Line->GetNextInvokeID();
  8586. m_dwInvokeID = pROSAPDU->value.u.invoke.invokeId;
  8587. //opcode
  8588. pROSAPDU->value.u.invoke.opcode.choice = local_chosen;
  8589. pROSAPDU->value.u.invoke.opcode.u.local = CHECKRESTRICTION_OPCODE;
  8590. //argument
  8591. CheckRestrictionArgument checkRestrictionArgument;
  8592. ZeroMemory( (PVOID)&checkRestrictionArgument,
  8593. sizeof(CheckRestrictionArgument) );
  8594. //argument.divertedToNR
  8595. checkRestrictionArgument.divertedToNr.bit_mask = 0;
  8596. checkRestrictionArgument.divertedToNr.destinationAddress =
  8597. (PEndpointAddress_destinationAddress)
  8598. SetMsgAddressAlias( m_pCalleeAliasNames );
  8599. if( checkRestrictionArgument.divertedToNr.destinationAddress == NULL )
  8600. {
  8601. goto cleanup;
  8602. }
  8603. if( m_pCallerAliasNames == NULL )
  8604. {
  8605. m_pCallerAliasNames = new H323_ALIASNAMES;
  8606. if( m_pCallerAliasNames == NULL )
  8607. {
  8608. H323DBG(( DEBUG_LEVEL_ERROR, "could not allocate caller name." ));
  8609. goto cleanup;
  8610. }
  8611. memset( (PVOID)m_pCallerAliasNames, 0, sizeof(H323_ALIASNAMES) );
  8612. LoadString( g_hInstance,
  8613. IDS_UNKNOWN,
  8614. szMsg,
  8615. 20
  8616. );
  8617. if( !AddAliasItem( m_pCallerAliasNames,
  8618. szMsg,
  8619. h323_ID_chosen ) )
  8620. {
  8621. goto cleanup;
  8622. }
  8623. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  8624. }
  8625. //argument.servedUserNR
  8626. checkRestrictionArgument.servedUserNr.bit_mask = 0;
  8627. checkRestrictionArgument.servedUserNr.destinationAddress =
  8628. (PEndpointAddress_destinationAddress)
  8629. SetMsgAddressAlias( m_pCallerAliasNames );
  8630. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  8631. if( checkRestrictionArgument.servedUserNr.destinationAddress == NULL )
  8632. {
  8633. goto cleanup;
  8634. }
  8635. //argument.basicservice
  8636. checkRestrictionArgument.basicService = allServices;
  8637. //encode the checkrestriction argument.
  8638. rc = EncodeH450ASN( (void *) &checkRestrictionArgument,
  8639. CheckRestrictionArgument_PDU,
  8640. &pEncodedArg,
  8641. &wEncodedLen );
  8642. if( ASN1_FAILED(rc) || (pEncodedArg == NULL) || (wEncodedLen == 0) )
  8643. {
  8644. goto cleanup;
  8645. }
  8646. pROSAPDU->value.u.invoke.argument.value = pBufEncodedArg;
  8647. pROSAPDU->value.u.invoke.argument.length = wEncodedLen;
  8648. CopyMemory( (PVOID)pROSAPDU->value.u.invoke.argument.value,
  8649. pEncodedArg, wEncodedLen );
  8650. //free the previous asn buffer before
  8651. ASN1_FreeEncoded(m_ASNCoderInfo.pEncInfo, pEncodedArg );
  8652. //call ASN.1 encoding functions
  8653. rc = EncodeH450ASN( (void *) pSupplementaryServiceAPDU,
  8654. H4501SupplementaryService_PDU,
  8655. ppEncodedAPDU,
  8656. &wEncodedLen );
  8657. *pdwAPDULen = wEncodedLen;
  8658. if( ASN1_FAILED(rc) || (*ppEncodedAPDU == NULL) || (pdwAPDULen == 0) )
  8659. {
  8660. goto cleanup;
  8661. }
  8662. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeCheckRestrictionAPDU exited:%p.",
  8663. this ));
  8664. retVal = TRUE;
  8665. cleanup:
  8666. if( checkRestrictionArgument.servedUserNr.destinationAddress )
  8667. {
  8668. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  8669. checkRestrictionArgument.servedUserNr.destinationAddress );
  8670. }
  8671. if( checkRestrictionArgument.divertedToNr.destinationAddress )
  8672. {
  8673. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  8674. checkRestrictionArgument.divertedToNr.destinationAddress );
  8675. }
  8676. return retVal;
  8677. }
  8678. BOOL
  8679. CH323Call::EncodeDivertingLeg2APDU(
  8680. OUT H4501SupplementaryService *pSupplementaryServiceAPDU,
  8681. OUT BYTE** ppEncodedAPDU,
  8682. OUT DWORD* pdwAPDULen
  8683. )
  8684. {
  8685. BYTE *pEncodedArg = NULL;
  8686. WORD wEncodedLen = 0;
  8687. BYTE pBufEncodedArg[H450_ENCODED_ARG_LEN];
  8688. BOOL retVal = FALSE;
  8689. int rc = 0;
  8690. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeDivertingLeg2APDU entered:%p.", this ));
  8691. pSupplementaryServiceAPDU->interpretationApdu.choice =
  8692. discardAnyUnrecognizedInvokePdu_chosen;
  8693. ServiceApdus_rosApdus *pROSAPDU =
  8694. pSupplementaryServiceAPDU->serviceApdu.u.rosApdus;
  8695. pROSAPDU->next = NULL;
  8696. pROSAPDU->value.choice = H4503ROS_invoke_chosen;
  8697. pROSAPDU->value.u.invoke.bit_mask = argument_present;
  8698. //invoke ID
  8699. pROSAPDU->value.u.invoke.invokeId = g_pH323Line->GetNextInvokeID();
  8700. //opcode
  8701. pROSAPDU->value.u.invoke.opcode.choice = local_chosen;
  8702. pROSAPDU->value.u.invoke.opcode.u.local = DIVERTINGLEGINFO2_OPCODE;
  8703. //argument
  8704. DivertingLegInformation2Argument divertLegInfo2Arg;
  8705. ZeroMemory( (PVOID)&divertLegInfo2Arg,
  8706. sizeof(DivertingLegInformation2Argument) );
  8707. //argument.diversionCounter
  8708. divertLegInfo2Arg.diversionCounter
  8709. = (WORD)m_pCallReroutingInfo->diversionCounter;
  8710. //argument.diversionreason
  8711. divertLegInfo2Arg.diversionReason = m_pCallReroutingInfo->diversionReason;
  8712. //argument.originalDiversionReason
  8713. if( m_pCallReroutingInfo->originalDiversionReason != 0 )
  8714. {
  8715. divertLegInfo2Arg.originalDiversionReason =
  8716. m_pCallReroutingInfo->originalDiversionReason;
  8717. divertLegInfo2Arg.bit_mask |= originalDiversionReason_present;
  8718. }
  8719. //argument.divertingNr
  8720. if( m_pCallReroutingInfo->divertingNrAlias != NULL )
  8721. {
  8722. divertLegInfo2Arg.bit_mask |= divertingNr_present;
  8723. divertLegInfo2Arg.divertingNr.bit_mask = 0;
  8724. divertLegInfo2Arg.divertingNr.destinationAddress
  8725. = (PEndpointAddress_destinationAddress)
  8726. SetMsgAddressAlias( m_pCallReroutingInfo->divertingNrAlias );
  8727. if( divertLegInfo2Arg.divertingNr.destinationAddress == NULL )
  8728. {
  8729. return FALSE;
  8730. }
  8731. }
  8732. //argument.originalCalledNr
  8733. if( m_pCallReroutingInfo->originalCalledNr != NULL )
  8734. {
  8735. divertLegInfo2Arg.bit_mask |=
  8736. DivertingLegInformation2Argument_originalCalledNr_present;
  8737. divertLegInfo2Arg.originalCalledNr.bit_mask = 0;
  8738. divertLegInfo2Arg.originalCalledNr.destinationAddress
  8739. = (PEndpointAddress_destinationAddress)
  8740. SetMsgAddressAlias( m_pCallReroutingInfo->originalCalledNr );
  8741. if( divertLegInfo2Arg.originalCalledNr.destinationAddress == NULL )
  8742. {
  8743. goto cleanup;
  8744. }
  8745. }
  8746. //encode the divertingleg2 argument.
  8747. rc = EncodeH450ASN( (void *) &divertLegInfo2Arg,
  8748. DivertingLegInformation2Argument_PDU,
  8749. &pEncodedArg,
  8750. &wEncodedLen );
  8751. if( ASN1_FAILED(rc) || (pEncodedArg == NULL) || (wEncodedLen == 0) )
  8752. {
  8753. goto cleanup;
  8754. }
  8755. pROSAPDU->value.u.invoke.argument.value = pBufEncodedArg;
  8756. pROSAPDU->value.u.invoke.argument.length = wEncodedLen;
  8757. CopyMemory( (PVOID)pROSAPDU->value.u.invoke.argument.value,
  8758. pEncodedArg, wEncodedLen );
  8759. //free the previous asn buffer before encoding new one
  8760. ASN1_FreeEncoded(m_ASNCoderInfo.pEncInfo, pEncodedArg );
  8761. //call ASN.1 encoding function for APDU
  8762. rc = EncodeH450ASN( (void *) pSupplementaryServiceAPDU,
  8763. H4501SupplementaryService_PDU,
  8764. ppEncodedAPDU,
  8765. &wEncodedLen );
  8766. *pdwAPDULen = wEncodedLen;
  8767. if( ASN1_FAILED(rc) || (*ppEncodedAPDU == NULL) || (pdwAPDULen == 0) )
  8768. {
  8769. goto cleanup;
  8770. }
  8771. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeDivertingLeg2APDU exited:%p.", this ));
  8772. retVal= TRUE;
  8773. cleanup:
  8774. if( divertLegInfo2Arg.divertingNr.destinationAddress )
  8775. {
  8776. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  8777. divertLegInfo2Arg.divertingNr.destinationAddress );
  8778. }
  8779. if( divertLegInfo2Arg.originalCalledNr.destinationAddress )
  8780. {
  8781. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  8782. divertLegInfo2Arg.originalCalledNr.destinationAddress );
  8783. }
  8784. return retVal;
  8785. }
  8786. BOOL
  8787. CH323Call::EncodeDivertingLeg3APDU(
  8788. OUT H4501SupplementaryService *pSupplementaryServiceAPDU,
  8789. OUT BYTE** ppEncodedAPDU,
  8790. OUT DWORD* pdwAPDULen
  8791. )
  8792. {
  8793. BYTE *pEncodedArg = NULL;
  8794. WORD wEncodedLen = 0;
  8795. BYTE pBufEncodedArg[H450_ENCODED_ARG_LEN];
  8796. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeDivertingLeg3APDU entered:%p.", this ));
  8797. pSupplementaryServiceAPDU->interpretationApdu.choice =
  8798. discardAnyUnrecognizedInvokePdu_chosen;
  8799. ServiceApdus_rosApdus *pROSAPDU =
  8800. pSupplementaryServiceAPDU->serviceApdu.u.rosApdus;
  8801. pROSAPDU->next = NULL;
  8802. pROSAPDU->value.choice = H4503ROS_invoke_chosen;
  8803. pROSAPDU->value.u.invoke.bit_mask = argument_present;
  8804. //invoke ID
  8805. pROSAPDU->value.u.invoke.invokeId = g_pH323Line->GetNextInvokeID();
  8806. //opcode
  8807. pROSAPDU->value.u.invoke.opcode.choice = local_chosen;
  8808. pROSAPDU->value.u.invoke.opcode.u.local = DIVERTINGLEGINFO3_OPCODE;
  8809. //argument
  8810. DivertingLegInformation3Argument divertLegInfo3Arg;
  8811. ZeroMemory( (PVOID)&divertLegInfo3Arg,
  8812. sizeof(DivertingLegInformation3Argument) );
  8813. //argument.presentationallowed
  8814. divertLegInfo3Arg.presentationAllowedIndicator = TRUE;
  8815. //argument.redirectionNr
  8816. divertLegInfo3Arg.redirectionNr.bit_mask = 0;
  8817. divertLegInfo3Arg.redirectionNr.destinationAddress =
  8818. (PEndpointAddress_destinationAddress)
  8819. SetMsgAddressAlias( m_pCalleeAliasNames );
  8820. if( divertLegInfo3Arg.redirectionNr.destinationAddress )
  8821. {
  8822. divertLegInfo3Arg.bit_mask |= redirectionNr_present;
  8823. }
  8824. //encode the divertingleg3 argument.
  8825. int rc = EncodeH450ASN( (void *) &divertLegInfo3Arg,
  8826. DivertingLegInformation3Argument_PDU,
  8827. &pEncodedArg,
  8828. &wEncodedLen );
  8829. if( ASN1_FAILED(rc) || (pEncodedArg == NULL) || (wEncodedLen == 0) )
  8830. {
  8831. if( divertLegInfo3Arg.redirectionNr.destinationAddress )
  8832. {
  8833. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  8834. divertLegInfo3Arg.redirectionNr.destinationAddress );
  8835. }
  8836. return FALSE;
  8837. }
  8838. pROSAPDU->value.u.invoke.argument.value = pBufEncodedArg;
  8839. pROSAPDU->value.u.invoke.argument.length = wEncodedLen;
  8840. CopyMemory( (PVOID)pROSAPDU->value.u.invoke.argument.value,
  8841. pEncodedArg, wEncodedLen );
  8842. //free the previous asn buffer before encoding new one
  8843. ASN1_FreeEncoded(m_ASNCoderInfo.pEncInfo, pEncodedArg );
  8844. if( divertLegInfo3Arg.redirectionNr.destinationAddress )
  8845. {
  8846. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  8847. divertLegInfo3Arg.redirectionNr.destinationAddress );
  8848. }
  8849. //call ASN.1 encoding function for APDU
  8850. rc = EncodeH450ASN( (void *) pSupplementaryServiceAPDU,
  8851. H4501SupplementaryService_PDU,
  8852. ppEncodedAPDU,
  8853. &wEncodedLen );
  8854. *pdwAPDULen = wEncodedLen;
  8855. if( ASN1_FAILED(rc) || (*ppEncodedAPDU == NULL) || (pdwAPDULen == 0) )
  8856. {
  8857. return FALSE;
  8858. }
  8859. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeDivertingLeg3APDU exited:%p.", this ));
  8860. return TRUE;
  8861. }
  8862. BOOL
  8863. CH323Call::EncodeCallReroutingAPDU(
  8864. OUT H4501SupplementaryService *pSupplementaryServiceAPDU,
  8865. OUT BYTE** ppEncodedAPDU,
  8866. OUT DWORD* pdwAPDULen
  8867. )
  8868. {
  8869. BYTE *pEncodedArg = NULL;
  8870. WORD wEncodedLen = 0;
  8871. BYTE pBufEncodedArg[H450_ENCODED_ARG_LEN];
  8872. BOOL retVal = FALSE;
  8873. int rc = 0;
  8874. UCHAR bearerCap[5];
  8875. TCHAR szMsg[20];
  8876. PH323_ALIASNAMES pCallerAliasNames = m_pCallerAliasNames;
  8877. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeCallReroutingAPDU entered:%p.", this ));
  8878. _ASSERTE( m_pCallReroutingInfo );
  8879. ServiceApdus_rosApdus *pROSAPDU =
  8880. pSupplementaryServiceAPDU->serviceApdu.u.rosApdus;
  8881. pROSAPDU->next = NULL;
  8882. pROSAPDU->value.choice = H4503ROS_invoke_chosen;
  8883. pROSAPDU->value.u.invoke.bit_mask = argument_present;
  8884. //invoke ID
  8885. pROSAPDU->value.u.invoke.invokeId = g_pH323Line->GetNextInvokeID();
  8886. m_dwInvokeID = pROSAPDU->value.u.invoke.invokeId;
  8887. //opcode
  8888. pROSAPDU->value.u.invoke.opcode.choice = local_chosen;
  8889. pROSAPDU->value.u.invoke.opcode.u.local = CALLREROUTING_OPCODE;
  8890. //argument
  8891. CallReroutingArgument callReroutingArg;
  8892. ZeroMemory( (PVOID)&callReroutingArg, sizeof(CallReroutingArgument) );
  8893. //argument.reroutingReason
  8894. callReroutingArg.reroutingReason = m_pCallReroutingInfo->diversionReason;
  8895. //argument.originalReroutingReason
  8896. if( m_pCallReroutingInfo->originalDiversionReason != 0 )
  8897. {
  8898. callReroutingArg.originalReroutingReason
  8899. = m_pCallReroutingInfo->originalDiversionReason;
  8900. }
  8901. else
  8902. {
  8903. callReroutingArg.originalReroutingReason
  8904. = m_pCallReroutingInfo->diversionReason;
  8905. }
  8906. //argument.diversionCounter
  8907. callReroutingArg.diversionCounter =
  8908. ++(m_pCallReroutingInfo->diversionCounter);
  8909. //argument.calledAddress
  8910. callReroutingArg.calledAddress.bit_mask = 0;
  8911. callReroutingArg.calledAddress.destinationAddress
  8912. = (PEndpointAddress_destinationAddress)
  8913. SetMsgAddressAlias(m_pCallReroutingInfo->divertedToNrAlias);
  8914. if( callReroutingArg.calledAddress.destinationAddress == NULL )
  8915. {
  8916. goto cleanup;
  8917. }
  8918. //argument.lastReroutingNr
  8919. callReroutingArg.lastReroutingNr.bit_mask = 0;
  8920. callReroutingArg.lastReroutingNr.destinationAddress
  8921. = (PEndpointAddress_destinationAddress)
  8922. SetMsgAddressAlias(m_pCalleeAliasNames);
  8923. if( callReroutingArg.lastReroutingNr.destinationAddress == NULL )
  8924. {
  8925. goto cleanup;
  8926. }
  8927. //argument.subscriptionoption
  8928. callReroutingArg.subscriptionOption = notificationWithDivertedToNr;
  8929. //argument.callingNumber
  8930. callReroutingArg.callingNumber.bit_mask = 0;
  8931. if( pCallerAliasNames == NULL )
  8932. {
  8933. pCallerAliasNames = new H323_ALIASNAMES;
  8934. if( pCallerAliasNames == NULL )
  8935. {
  8936. H323DBG(( DEBUG_LEVEL_ERROR, "could not allocate caller name." ));
  8937. goto cleanup;
  8938. }
  8939. memset( (PVOID)pCallerAliasNames, 0, sizeof(H323_ALIASNAMES) );
  8940. LoadString( g_hInstance,
  8941. IDS_UNKNOWN,
  8942. szMsg,
  8943. 20
  8944. );
  8945. if( !AddAliasItem( pCallerAliasNames,
  8946. szMsg,
  8947. h323_ID_chosen ) )
  8948. {
  8949. goto cleanup;
  8950. }
  8951. }
  8952. callReroutingArg.callingNumber.destinationAddress
  8953. = (PEndpointAddress_destinationAddress)
  8954. SetMsgAddressAlias(pCallerAliasNames);
  8955. if( callReroutingArg.callingNumber.destinationAddress == NULL )
  8956. {
  8957. goto cleanup;
  8958. }
  8959. //argumnt.h225infoelement
  8960. callReroutingArg.h225InfoElement.length = 5;
  8961. callReroutingArg.h225InfoElement.value = bearerCap;
  8962. bearerCap[0]= IDENT_BEARERCAP;
  8963. bearerCap[1]= 0x03; //length of the bearer capability
  8964. bearerCap[2]= (BYTE)(BEAR_EXT_BIT | BEAR_CCITT | BEAR_UNRESTRICTED_DIGITAL);
  8965. bearerCap[3]= BEAR_EXT_BIT | 0x17;
  8966. bearerCap[4]= (BYTE)(BEAR_EXT_BIT | BEAR_LAYER1_INDICATOR |
  8967. BEAR_LAYER1_H221_H242);
  8968. //argument.callingNumber
  8969. if( m_pCallReroutingInfo->originalCalledNr != NULL )
  8970. {
  8971. callReroutingArg.originalCalledNr.bit_mask = 0;
  8972. callReroutingArg.originalCalledNr.destinationAddress
  8973. = (PEndpointAddress_destinationAddress)
  8974. SetMsgAddressAlias( m_pCallReroutingInfo->originalCalledNr );
  8975. if( callReroutingArg.originalCalledNr.destinationAddress != NULL )
  8976. {
  8977. callReroutingArg.bit_mask |=
  8978. CallReroutingArgument_originalCalledNr_present;
  8979. }
  8980. }
  8981. //encode the callrerouting argument.
  8982. rc = EncodeH450ASN( (void *) &callReroutingArg,
  8983. CallReroutingArgument_PDU,
  8984. &pEncodedArg,
  8985. &wEncodedLen );
  8986. if( ASN1_FAILED(rc) || (pEncodedArg == NULL) || (wEncodedLen == 0) )
  8987. {
  8988. goto cleanup;
  8989. }
  8990. pROSAPDU->value.u.invoke.argument.value = pBufEncodedArg;
  8991. pROSAPDU->value.u.invoke.argument.length = wEncodedLen;
  8992. CopyMemory( (PVOID)pROSAPDU->value.u.invoke.argument.value,
  8993. pEncodedArg, wEncodedLen );
  8994. //free the previous asn buffer before encoding new one
  8995. ASN1_FreeEncoded(m_ASNCoderInfo.pEncInfo, pEncodedArg );
  8996. //call ASN.1 encoding function for APDU
  8997. rc = EncodeH450ASN( (void *) pSupplementaryServiceAPDU,
  8998. H4501SupplementaryService_PDU,
  8999. ppEncodedAPDU,
  9000. &wEncodedLen );
  9001. *pdwAPDULen = wEncodedLen;
  9002. if( ASN1_FAILED(rc) || (*ppEncodedAPDU == NULL) || (pdwAPDULen == 0) )
  9003. {
  9004. goto cleanup;
  9005. }
  9006. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeCallReroutingAPDU exited:%p.", this ));
  9007. retVal = TRUE;
  9008. cleanup:
  9009. if( pCallerAliasNames != m_pCallerAliasNames )
  9010. {
  9011. FreeAliasNames( pCallerAliasNames );
  9012. }
  9013. FreeCallReroutingArg( &callReroutingArg );
  9014. return retVal;
  9015. }
  9016. //No need to call in a lock!!
  9017. void
  9018. CH323Call::FreeCallReroutingArg(
  9019. CallReroutingArgument* pCallReroutingArg
  9020. )
  9021. {
  9022. //free all the aliases
  9023. if( pCallReroutingArg->calledAddress.destinationAddress != NULL )
  9024. {
  9025. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  9026. pCallReroutingArg->calledAddress.destinationAddress );
  9027. }
  9028. if( pCallReroutingArg->lastReroutingNr.destinationAddress != NULL )
  9029. {
  9030. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  9031. pCallReroutingArg->lastReroutingNr.destinationAddress );
  9032. }
  9033. if( pCallReroutingArg->callingNumber.destinationAddress != NULL )
  9034. {
  9035. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  9036. pCallReroutingArg->callingNumber.destinationAddress );
  9037. }
  9038. if( pCallReroutingArg->originalCalledNr.destinationAddress != NULL )
  9039. {
  9040. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  9041. pCallReroutingArg->originalCalledNr.destinationAddress );
  9042. }
  9043. }
  9044. // static
  9045. void
  9046. NTAPI CH323Call::CallEstablishmentExpiredCallback(
  9047. IN PVOID DriverCallHandle, // HDRVCALL
  9048. IN BOOLEAN bTimer)
  9049. {
  9050. PH323_CALL pCall = NULL;
  9051. H323DBG(( DEBUG_LEVEL_TRACE, "CallEstablishmentExpiredCallback entered." ));
  9052. //if the timer expired
  9053. _ASSERTE( bTimer );
  9054. H323DBG(( DEBUG_LEVEL_TRACE, "Q931 setup expired event recvd." ));
  9055. pCall=g_pH323Line -> FindH323CallAndLock((HDRVCALL) DriverCallHandle);
  9056. if( pCall != NULL )
  9057. {
  9058. if( pCall -> GetStateMachine() != Q931_CONNECT_RECVD )
  9059. {
  9060. //time out has occured
  9061. pCall -> CloseCall( LINEDISCONNECTMODE_NOANSWER );
  9062. }
  9063. pCall -> Unlock();
  9064. }
  9065. H323DBG(( DEBUG_LEVEL_TRACE, "CallEstablishmentExpiredCallback exited." ));
  9066. }
  9067. //-----------------------------------------------------------------------------
  9068. //CALL TRANSFER (H450.2) ENCODE/DECODE ROUTINES
  9069. //-----------------------------------------------------------------------------
  9070. BOOL
  9071. CH323Call::EncodeH450APDUNoArgument(
  9072. IN DWORD dwOpcode,
  9073. OUT H4501SupplementaryService *pSupplementaryServiceAPDU,
  9074. OUT BYTE** ppEncodedAPDU,
  9075. OUT DWORD* pdwAPDULen
  9076. )
  9077. {
  9078. BYTE *pEncodedArg = NULL;
  9079. WORD wEncodedLen = 0;
  9080. int rc;
  9081. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeH450APDUNoArgument entered:%p.",
  9082. this ));
  9083. ServiceApdus_rosApdus *pROSAPDU =
  9084. pSupplementaryServiceAPDU->serviceApdu.u.rosApdus;
  9085. pROSAPDU->next = NULL;
  9086. pROSAPDU->value.choice = H4503ROS_invoke_chosen;
  9087. pROSAPDU->value.u.invoke.bit_mask = 0;
  9088. //invoke ID
  9089. pROSAPDU->value.u.invoke.invokeId = g_pH323Line->GetNextInvokeID();
  9090. m_dwInvokeID = pROSAPDU->value.u.invoke.invokeId;
  9091. //opcode
  9092. pROSAPDU->value.u.invoke.opcode.choice = local_chosen;
  9093. pROSAPDU->value.u.invoke.opcode.u.local = dwOpcode;
  9094. //no argument passed
  9095. //call ASN.1 encoding function for APDU
  9096. rc = EncodeH450ASN( (void *) pSupplementaryServiceAPDU,
  9097. H4501SupplementaryService_PDU,
  9098. ppEncodedAPDU,
  9099. &wEncodedLen );
  9100. *pdwAPDULen = wEncodedLen;
  9101. if( ASN1_FAILED(rc) || (*ppEncodedAPDU == NULL) || (pdwAPDULen == 0) )
  9102. {
  9103. return FALSE;
  9104. }
  9105. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeH450APDUNoArgument exited:%p.",
  9106. this ));
  9107. return TRUE;
  9108. }
  9109. BOOL
  9110. CH323Call::EncodeCTInitiateAPDU(
  9111. OUT H4501SupplementaryService *pSupplementaryServiceAPDU,
  9112. OUT BYTE** ppEncodedAPDU,
  9113. OUT DWORD* pdwAPDULen
  9114. )
  9115. {
  9116. BYTE *pEncodedArg = NULL;
  9117. WORD wEncodedLen = 0;
  9118. BYTE pBufEncodedArg[H450_ENCODED_ARG_LEN];
  9119. int rc = 0;
  9120. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeCTInitiateAPDU entered:%p.", this ));
  9121. ServiceApdus_rosApdus *pROSAPDU =
  9122. pSupplementaryServiceAPDU->serviceApdu.u.rosApdus;
  9123. pROSAPDU->next = NULL;
  9124. pROSAPDU->value.choice = H4503ROS_invoke_chosen;
  9125. pROSAPDU->value.u.invoke.bit_mask = argument_present;
  9126. //invoke ID
  9127. pROSAPDU->value.u.invoke.invokeId = g_pH323Line->GetNextInvokeID();
  9128. m_dwInvokeID = pROSAPDU->value.u.invoke.invokeId;
  9129. //opcode
  9130. pROSAPDU->value.u.invoke.opcode.choice = local_chosen;
  9131. pROSAPDU->value.u.invoke.opcode.u.local = CTINITIATE_OPCODE;
  9132. //argument
  9133. CTInitiateArg cTInitiateArg;
  9134. ZeroMemory( (PVOID)&cTInitiateArg, sizeof(CTInitiateArg) );
  9135. //argument.callIdentity
  9136. CopyMemory( (PVOID)cTInitiateArg.callIdentity,
  9137. (PVOID)m_pCTCallIdentity, sizeof(m_pCTCallIdentity) );
  9138. //argument.reroutingNumber
  9139. cTInitiateArg.reroutingNumber.bit_mask = 0;
  9140. cTInitiateArg.reroutingNumber.destinationAddress =
  9141. (PEndpointAddress_destinationAddress)
  9142. SetMsgAddressAlias( m_pTransferedToAlias );
  9143. if( cTInitiateArg.reroutingNumber.destinationAddress == NULL )
  9144. {
  9145. return FALSE;
  9146. }
  9147. //encode the CTSetup argument.
  9148. rc = EncodeH450ASN( (void *) &cTInitiateArg,
  9149. CTInitiateArg_PDU,
  9150. &pEncodedArg,
  9151. &wEncodedLen );
  9152. if( ASN1_FAILED(rc) || (pEncodedArg == NULL) || (wEncodedLen == 0) )
  9153. {
  9154. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  9155. cTInitiateArg.reroutingNumber.destinationAddress );
  9156. return FALSE;
  9157. }
  9158. pROSAPDU->value.u.invoke.argument.value = pBufEncodedArg;
  9159. pROSAPDU->value.u.invoke.argument.length = wEncodedLen;
  9160. CopyMemory( (PVOID)pROSAPDU->value.u.invoke.argument.value,
  9161. pEncodedArg, wEncodedLen );
  9162. //free the previous asn buffer before encoding new one
  9163. ASN1_FreeEncoded(m_ASNCoderInfo.pEncInfo, pEncodedArg );
  9164. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  9165. cTInitiateArg.reroutingNumber.destinationAddress );
  9166. //call ASN.1 encoding function for APDU
  9167. rc = EncodeH450ASN( (void *) pSupplementaryServiceAPDU,
  9168. H4501SupplementaryService_PDU,
  9169. ppEncodedAPDU,
  9170. &wEncodedLen );
  9171. *pdwAPDULen = wEncodedLen;
  9172. if( ASN1_FAILED(rc) || (*ppEncodedAPDU == NULL) || (pdwAPDULen == 0) )
  9173. {
  9174. return FALSE;
  9175. }
  9176. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeCTInitiateAPDU exited:%p.", this ));
  9177. return TRUE;
  9178. }
  9179. BOOL
  9180. CH323Call::EncodeCTSetupAPDU(
  9181. OUT H4501SupplementaryService *pSupplementaryServiceAPDU,
  9182. OUT BYTE** ppEncodedAPDU,
  9183. OUT DWORD* pdwAPDULen
  9184. )
  9185. {
  9186. BYTE *pEncodedArg = NULL;
  9187. WORD wEncodedLen = 0;
  9188. BYTE pBufEncodedArg[H450_ENCODED_ARG_LEN];
  9189. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeCTSetupAPDU entered:%p.", this ));
  9190. ServiceApdus_rosApdus *pROSAPDU =
  9191. pSupplementaryServiceAPDU->serviceApdu.u.rosApdus;
  9192. pROSAPDU->next = NULL;
  9193. pROSAPDU->value.choice = H4503ROS_invoke_chosen;
  9194. pROSAPDU->value.u.invoke.bit_mask = argument_present;
  9195. //invoke ID
  9196. pROSAPDU->value.u.invoke.invokeId = g_pH323Line->GetNextInvokeID();
  9197. m_dwInvokeID = pROSAPDU->value.u.invoke.invokeId;
  9198. //opcode
  9199. pROSAPDU->value.u.invoke.opcode.choice = local_chosen;
  9200. pROSAPDU->value.u.invoke.opcode.u.local = CTSETUP_OPCODE;
  9201. //argument
  9202. CTSetupArg cTSetupArg;
  9203. ZeroMemory( (PVOID)&cTSetupArg, sizeof(CTSetupArg) );
  9204. //argument.callIdentity
  9205. CopyMemory( (PVOID)cTSetupArg.callIdentity,
  9206. (PVOID)m_pCTCallIdentity, sizeof(m_pCTCallIdentity) );
  9207. //no argument.transferingNumber
  9208. //encode the CTSetup argument.
  9209. int rc = EncodeH450ASN( (void *) &cTSetupArg,
  9210. CTSetupArg_PDU,
  9211. &pEncodedArg,
  9212. &wEncodedLen );
  9213. if( ASN1_FAILED(rc) || (pEncodedArg == NULL) || (wEncodedLen == 0) )
  9214. {
  9215. return FALSE;
  9216. }
  9217. pROSAPDU->value.u.invoke.argument.value = pBufEncodedArg;
  9218. pROSAPDU->value.u.invoke.argument.length = wEncodedLen;
  9219. CopyMemory( (PVOID)pROSAPDU->value.u.invoke.argument.value,
  9220. pEncodedArg, wEncodedLen );
  9221. //free the previous asn buffer before encoding new one
  9222. ASN1_FreeEncoded(m_ASNCoderInfo.pEncInfo, pEncodedArg );
  9223. //call ASN.1 encoding function for APDU
  9224. rc = EncodeH450ASN( (void *) pSupplementaryServiceAPDU,
  9225. H4501SupplementaryService_PDU,
  9226. ppEncodedAPDU,
  9227. &wEncodedLen );
  9228. *pdwAPDULen = wEncodedLen;
  9229. if( ASN1_FAILED(rc) || (*ppEncodedAPDU == NULL) || (pdwAPDULen == 0) )
  9230. {
  9231. return FALSE;
  9232. }
  9233. H323DBG(( DEBUG_LEVEL_TRACE, "EncodeCTSetupAPDU exited:%p.", this ));
  9234. return TRUE;
  9235. }
  9236. void CH323Call::PostLineEvent (
  9237. IN DWORD MessageID,
  9238. IN DWORD_PTR Parameter1,
  9239. IN DWORD_PTR Parameter2,
  9240. IN DWORD_PTR Parameter3)
  9241. {
  9242. (*g_pfnLineEventProc) (
  9243. g_pH323Line -> m_htLine,
  9244. m_htCall,
  9245. MessageID,
  9246. Parameter1,
  9247. Parameter2,
  9248. Parameter3);
  9249. }
  9250. //!!must be always called in a lock
  9251. void
  9252. CH323Call::DecrementIoRefCount(
  9253. OUT BOOL * pfDelete
  9254. )
  9255. {
  9256. _ASSERTE( m_IoRefCount != 0 );
  9257. m_IoRefCount--;
  9258. H323DBG((DEBUG_LEVEL_TRACE, "DecrementIoRefCount:m_IoRefCount:%d:%p.",
  9259. m_IoRefCount, this ));
  9260. *pfDelete = FALSE;
  9261. if( m_dwFlags & CALLOBJECT_SHUTDOWN )
  9262. {
  9263. *pfDelete = (m_IoRefCount==0) ? TRUE : FALSE;
  9264. }
  9265. }
  9266. //!!must be always called in a lock
  9267. void
  9268. CH323Call::StopCTIdentifyRRTimer(
  9269. HDRVCALL hdRelatedCall
  9270. )
  9271. {
  9272. if( m_hCTIdentifyRRTimer != NULL )
  9273. {
  9274. DeleteTimerQueueTimer( H323TimerQueue, m_hCTIdentifyRRTimer, NULL );
  9275. m_hCTIdentifyRRTimer = NULL;
  9276. }
  9277. m_hdRelatedCall = hdRelatedCall;
  9278. }
  9279. void
  9280. CH323Call::InitializeRecvBuf()
  9281. {
  9282. m_RecvBuf.WSABuf.len = sizeof(TPKT_HEADER_SIZE);
  9283. m_RecvBuf.WSABuf.buf = m_RecvBuf.arBuf;
  9284. m_RecvBuf.dwPDULen = m_RecvBuf.dwBytesCopied = 0;
  9285. m_bStartOfPDU = TRUE;
  9286. }
  9287. BOOL
  9288. CH323Call::SetCallData(
  9289. LPVOID lpCallData,
  9290. DWORD dwSize )
  9291. {
  9292. if( m_CallData.pOctetString != NULL )
  9293. {
  9294. delete m_CallData.pOctetString;
  9295. }
  9296. m_CallData.pOctetString = new BYTE[dwSize];
  9297. if( m_CallData.pOctetString == NULL )
  9298. {
  9299. m_CallData.wOctetStringLength = 0;
  9300. return FALSE;
  9301. }
  9302. CopyMemory( (PVOID)m_CallData.pOctetString, lpCallData, dwSize );
  9303. m_CallData.wOctetStringLength = (WORD)dwSize;
  9304. return TRUE;
  9305. }
  9306. // Global Functions
  9307. BOOL
  9308. IsPhoneNumber(
  9309. char * szAddr
  9310. )
  9311. {
  9312. while( *szAddr )
  9313. {
  9314. if( !isdigit(*szAddr) &&
  9315. ('#' != *szAddr) &&
  9316. ('*' != *szAddr) &&
  9317. ('+' != *szAddr)
  9318. )
  9319. return FALSE;
  9320. szAddr++;
  9321. }
  9322. return TRUE;
  9323. }
  9324. BOOL
  9325. IsValidE164String(
  9326. IN WCHAR* wszDigits
  9327. )
  9328. {
  9329. for( ; (*wszDigits) != L'\0'; wszDigits++ )
  9330. {
  9331. if(!(
  9332. ((*wszDigits >= L'0') && (*wszDigits <= L'9')) ||
  9333. (*wszDigits == L'*') ||
  9334. (*wszDigits == L'#') ||
  9335. (*wszDigits == L'!') ||
  9336. (*wszDigits == L',')
  9337. ))
  9338. {
  9339. return FALSE;
  9340. }
  9341. }
  9342. return TRUE;
  9343. }