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.

831 lines
22 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. rascall.cpp
  5. Abstract:
  6. The RAS call functionality (ARQ/DRQ/ACF/DCF/IRR/ARJ/DRJ)
  7. Author:
  8. Nikhil Bobde (NikhilB)
  9. Revision History:
  10. --*/
  11. #include "globals.h"
  12. #include "q931obj.h"
  13. #include "line.h"
  14. #include "q931pdu.h"
  15. #include "ras.h"
  16. //!!always called from a lock
  17. BOOL
  18. CH323Call::SendARQ(
  19. IN long seqNumber
  20. )
  21. {
  22. RasMessage rasMessage;
  23. AdmissionRequest * ARQ;
  24. EXPIRE_CONTEXT * pExpireContext;
  25. PH323_ALIASNAMES pAliasList;
  26. PAdmissionRequest_destinationInfo destInfo = NULL;
  27. H323DBG(( DEBUG_LEVEL_TRACE, "SendARQ entered:%p.",this ));
  28. //if not registered with the GK then return failure
  29. if (!RasIsRegistered())
  30. return FALSE;
  31. pExpireContext = new EXPIRE_CONTEXT;
  32. if( pExpireContext == NULL )
  33. {
  34. return FALSE;
  35. }
  36. ZeroMemory( &rasMessage, sizeof RasMessage );
  37. rasMessage.choice = admissionRequest_chosen;
  38. ARQ = &rasMessage.u.admissionRequest;
  39. // get sequence number
  40. if( seqNumber != NOT_RESEND_SEQ_NUM )
  41. {
  42. ARQ -> requestSeqNum = (WORD)seqNumber;
  43. }
  44. else
  45. {
  46. m_wARQSeqNum = RasAllocSequenceNumber();
  47. ARQ -> requestSeqNum = m_wARQSeqNum;
  48. }
  49. ARQ -> callType.choice = pointToPoint_chosen;
  50. // endpointIdentifier
  51. RasGetEndpointID (&ARQ -> endpointIdentifier);
  52. // srcInfo: pass on the registered aliases
  53. pAliasList = RASGetRegisteredAliasList();
  54. ARQ -> srcInfo = (PAdmissionRequest_srcInfo)
  55. SetMsgAddressAlias( pAliasList );
  56. if( ARQ -> srcInfo == NULL )
  57. {
  58. delete pExpireContext;
  59. return FALSE;
  60. }
  61. // destInfo
  62. if( (m_dwOrigin==LINECALLORIGIN_OUTBOUND) && m_pCalleeAliasNames &&
  63. (m_pCalleeAliasNames -> wCount) )
  64. {
  65. ARQ -> destinationInfo = (PAdmissionRequest_destinationInfo)
  66. SetMsgAddressAlias( m_pCalleeAliasNames );
  67. if( ARQ -> destinationInfo != NULL )
  68. {
  69. ARQ -> bit_mask |= AdmissionRequest_destinationInfo_present;
  70. }
  71. }
  72. else if( (m_dwOrigin==LINECALLORIGIN_INBOUND) && m_pCallerAliasNames
  73. && (m_pCallerAliasNames -> wCount) )
  74. {
  75. ARQ -> destinationInfo = (PAdmissionRequest_destinationInfo)
  76. SetMsgAddressAlias( m_pCallerAliasNames );
  77. //H323DBG(( DEBUG_LEVEL_ERROR, "Caller alias count:%d : %p", m_pCallerAliasNames->wCount, this ));
  78. if( ARQ -> destinationInfo )
  79. {
  80. ARQ -> bit_mask |= AdmissionRequest_destinationInfo_present;
  81. }
  82. }
  83. for( destInfo = ARQ -> destinationInfo; destInfo; destInfo=destInfo->next )
  84. {
  85. H323DBG(( DEBUG_LEVEL_TRACE, "the alias:%s.", destInfo->value.u.e164 ));
  86. }
  87. ARQ -> bandWidth = 0;
  88. ARQ -> callReferenceValue = m_wCallReference;
  89. // no destExtraCallInfo
  90. // no srcCallSignalAddress
  91. // no nonStandardData
  92. // no callServices
  93. CopyConferenceID (&ARQ -> conferenceID, &m_ConferenceID);
  94. ARQ -> activeMC = FALSE;
  95. ARQ -> answerCall = ( m_dwOrigin == LINECALLORIGIN_INBOUND );
  96. ARQ -> canMapAlias = TRUE;
  97. CopyMemory( (PVOID)&ARQ -> callIdentifier.guid.value,
  98. (PVOID)&m_callIdentifier, sizeof(GUID) );
  99. ARQ -> callIdentifier.guid.length = sizeof (GUID);
  100. ARQ -> bit_mask |= AdmissionRequest_callIdentifier_present;
  101. // no srcAlternatives
  102. // no destAlternatives
  103. // no gatekeeperIdentifier
  104. // no tokens
  105. // no cryptoTokens
  106. // no integrityCheckValue
  107. // no transportQOS
  108. ARQ -> willSupplyUUIEs = FALSE;
  109. if( m_hARQTimer != NULL )
  110. {
  111. DeleteTimerQueueTimer( H323TimerQueue, m_hARQTimer, NULL );
  112. m_hARQTimer = NULL;
  113. }
  114. pExpireContext -> DriverCallHandle = m_hdCall;
  115. pExpireContext -> seqNumber = ARQ -> requestSeqNum;
  116. if( !CreateTimerQueueTimer(
  117. &m_hARQTimer,
  118. H323TimerQueue,
  119. CH323Call::ARQExpiredCallback,
  120. (PVOID)pExpireContext,
  121. ARQ_EXPIRE_TIME, 0,
  122. WT_EXECUTEINIOTHREAD | WT_EXECUTEONLYONCE ))
  123. {
  124. goto cleanup;
  125. }
  126. if( RasEncodeSendMessage (&rasMessage) != S_OK )
  127. {
  128. goto cleanup;
  129. }
  130. if( ARQ -> bit_mask & AdmissionRequest_destinationInfo_present )
  131. {
  132. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  133. ARQ -> destinationInfo );
  134. }
  135. FreeAddressAliases( (PSetup_UUIE_destinationAddress)ARQ -> srcInfo );
  136. m_dwRASCallState = RASCALL_STATE_ARQSENT;
  137. m_dwARQRetryCount++;
  138. _ASSERTE( m_pARQExpireContext == NULL );
  139. m_pARQExpireContext = pExpireContext;
  140. H323DBG(( DEBUG_LEVEL_TRACE, "SendARQ exited:%p.",this ));
  141. return TRUE;
  142. cleanup:
  143. if( m_hARQTimer != NULL )
  144. {
  145. DeleteTimerQueueTimer( H323TimerQueue,
  146. m_hARQTimer, NULL );
  147. m_hARQTimer = NULL;
  148. m_dwARQRetryCount = 0;
  149. }
  150. if( ARQ -> bit_mask & AdmissionRequest_destinationInfo_present )
  151. {
  152. FreeAddressAliases( (PSetup_UUIE_destinationAddress)
  153. ARQ -> destinationInfo );
  154. }
  155. if( pExpireContext != NULL )
  156. {
  157. delete pExpireContext;
  158. }
  159. FreeAddressAliases( (PSetup_UUIE_destinationAddress)ARQ -> srcInfo );
  160. return FALSE;
  161. }
  162. //!!always called from a lock
  163. BOOL
  164. CH323Call::SendDRQ(
  165. IN USHORT usDisengageReason,
  166. IN long seqNumber,
  167. IN BOOL fResendOnExpire
  168. )
  169. {
  170. RasMessage rasMessage;
  171. DisengageRequest * DRQ;
  172. EXPIRE_CONTEXT * pExpireContext;
  173. H323DBG(( DEBUG_LEVEL_TRACE, "SendDRQ entered:%p.",this ));
  174. ZeroMemory( &rasMessage, sizeof(rasMessage) );
  175. rasMessage.choice = disengageRequest_chosen;
  176. DRQ = &rasMessage.u.disengageRequest;
  177. //if not registered with the GK then return failure
  178. if (!RasIsRegistered())
  179. {
  180. return FALSE;
  181. }
  182. if( fResendOnExpire == TRUE )
  183. {
  184. pExpireContext = new EXPIRE_CONTEXT;
  185. if( pExpireContext == NULL )
  186. {
  187. return FALSE;
  188. }
  189. }
  190. // get sequence number
  191. if( seqNumber != NOT_RESEND_SEQ_NUM )
  192. {
  193. DRQ -> requestSeqNum = (WORD)seqNumber;
  194. }
  195. else
  196. {
  197. m_wDRQSeqNum = RasAllocSequenceNumber();
  198. DRQ -> requestSeqNum = m_wDRQSeqNum;
  199. }
  200. DRQ -> callReferenceValue = m_wCallReference;
  201. DRQ -> disengageReason.choice = usDisengageReason;
  202. // endpoint identifier
  203. RasGetEndpointID (&DRQ -> endpointIdentifier);
  204. // conferenceID
  205. CopyConferenceID (&DRQ -> conferenceID, &m_ConferenceID);
  206. // callIdentifier
  207. CopyConferenceID (&DRQ -> callIdentifier.guid, &m_callIdentifier);
  208. DRQ -> bit_mask |= DisengageRequest_callIdentifier_present;
  209. if( RasEncodeSendMessage( &rasMessage ) != S_OK )
  210. {
  211. delete pExpireContext;
  212. return FALSE;
  213. }
  214. if( m_hDRQTimer != NULL )
  215. {
  216. DeleteTimerQueueTimer( H323TimerQueue, m_hDRQTimer, NULL );
  217. m_hDRQTimer = NULL;
  218. }
  219. if( fResendOnExpire == TRUE )
  220. {
  221. pExpireContext -> DriverCallHandle = m_hdCall;
  222. pExpireContext -> seqNumber = DRQ -> requestSeqNum;
  223. if( !CreateTimerQueueTimer(
  224. &m_hDRQTimer,
  225. H323TimerQueue,
  226. CH323Call::DRQExpiredCallback,
  227. (PVOID)pExpireContext,
  228. ARQ_EXPIRE_TIME, 0,
  229. WT_EXECUTEINIOTHREAD | WT_EXECUTEONLYONCE ))
  230. {
  231. delete pExpireContext;
  232. return FALSE;
  233. }
  234. _ASSERTE( m_pDRQExpireContext == NULL );
  235. m_pDRQExpireContext = pExpireContext;
  236. }
  237. m_dwRASCallState = RASCALL_STATE_DRQSENT;
  238. m_dwDRQRetryCount++;
  239. H323DBG(( DEBUG_LEVEL_TRACE, "SendDRQ exited:%p.",this ));
  240. return TRUE;
  241. }
  242. //!!always called from a lock
  243. void
  244. CH323Call::OnDisengageRequest(
  245. IN DisengageRequest * DRQ
  246. )
  247. {
  248. GUID RequestConferenceID;
  249. H323DBG(( DEBUG_LEVEL_TRACE, "OnDisengageRequest entered:%p.",this ));
  250. if( (m_dwRASCallState == RASCALL_STATE_UNREGISTERED) ||
  251. (m_dwRASCallState == RASCALL_STATE_ARJRECVD) )
  252. {
  253. return;
  254. }
  255. CopyConferenceID (&RequestConferenceID, &DRQ -> conferenceID);
  256. if (!IsEqualGUID (m_ConferenceID, RequestConferenceID))
  257. {
  258. H323DBG ((DEBUG_LEVEL_ERROR, "DisengageRequest conference ID does not match this call, ignoring..."));
  259. return;
  260. }
  261. if (SendDCF (DRQ -> requestSeqNum))
  262. {
  263. m_dwRASCallState = RASCALL_STATE_UNREGISTERED;
  264. CloseCall( 0 );
  265. }
  266. H323DBG(( DEBUG_LEVEL_TRACE, "OnDisengageRequest exited:%p.",this ));
  267. }
  268. //!!always called in a lock
  269. BOOL
  270. CH323Call::SendDCF(
  271. IN WORD seqNumber
  272. )
  273. {
  274. RasMessage rasMessage;
  275. DisengageConfirm * DCF;
  276. H323DBG(( DEBUG_LEVEL_TRACE, "SendDCF entered:%p.",this ));
  277. ZeroMemory( &rasMessage, sizeof(rasMessage) );
  278. rasMessage.choice = disengageConfirm_chosen;
  279. DCF = &rasMessage.u.disengageConfirm;
  280. //if not registered with the GK then return failure
  281. if (!RasIsRegistered())
  282. {
  283. return FALSE;
  284. }
  285. DCF -> requestSeqNum = seqNumber;
  286. if (RasEncodeSendMessage (&rasMessage) != S_OK)
  287. {
  288. return FALSE;
  289. }
  290. H323DBG(( DEBUG_LEVEL_TRACE, "SendDCF exited:%p.",this ));
  291. return TRUE;
  292. }
  293. //!!always called from a lock
  294. void
  295. CH323Call::OnDisengageReject(
  296. IN DisengageReject* DRJ
  297. )
  298. {
  299. H323DBG(( DEBUG_LEVEL_TRACE, "OnDisengageReject entered:%p.",this ));
  300. if( DRJ -> requestSeqNum != m_wDRQSeqNum )
  301. {
  302. return;
  303. }
  304. if( m_dwRASCallState != RASCALL_STATE_DRQSENT )
  305. {
  306. return;
  307. }
  308. if( DRJ->rejectReason.choice == requestToDropOther_chosen )
  309. {
  310. //
  311. H323DBG(( DEBUG_LEVEL_ERROR, "!!something is wrong in the way DRQ is encoded.",this ));
  312. }
  313. else //if( DRJ->rejectReason.choice == DisengageRejectReason_notRegistered_chosen )
  314. {
  315. //the call has been unregistered but is still around, so dsrop it
  316. m_dwRASCallState = RASCALL_STATE_UNREGISTERED;
  317. //CloseCall( 0 );
  318. }
  319. H323DBG(( DEBUG_LEVEL_TRACE, "OnDisengageReject exited:%p.",this ));
  320. }
  321. void
  322. CH323Call::OnRequestInProgress(
  323. IN RequestInProgress* RIP
  324. )
  325. {
  326. H323DBG(( DEBUG_LEVEL_TRACE, "OnRequestInProgress entered:%p.",this ));
  327. EXPIRE_CONTEXT * pExpireContext;
  328. if( RIP -> requestSeqNum != m_wARQSeqNum )
  329. {
  330. return;
  331. }
  332. if( m_dwRASCallState != RASCALL_STATE_ARQSENT )
  333. {
  334. return;
  335. }
  336. //if delay is more than 30 seconds ignore it
  337. if( (RIP->delay > 0) && (RIP->delay > 30000) )
  338. {
  339. return;
  340. }
  341. pExpireContext = new EXPIRE_CONTEXT;
  342. if( pExpireContext == NULL )
  343. {
  344. return;
  345. }
  346. //restart the timer
  347. if( m_hARQTimer != NULL )
  348. {
  349. DeleteTimerQueueTimer( H323TimerQueue, m_hARQTimer, NULL );
  350. m_hARQTimer = NULL;
  351. }
  352. pExpireContext -> DriverCallHandle = m_hdCall;
  353. pExpireContext -> seqNumber = m_wARQSeqNum;
  354. if( !CreateTimerQueueTimer(
  355. &m_hARQTimer,
  356. H323TimerQueue,
  357. CH323Call::ARQExpiredCallback,
  358. (PVOID)pExpireContext,
  359. (DWORD)RIP->delay, 0,
  360. WT_EXECUTEINIOTHREAD | WT_EXECUTEONLYONCE ))
  361. {
  362. //close the call
  363. CloseCall( 0 );
  364. }
  365. H323DBG(( DEBUG_LEVEL_TRACE, "OnRequestInProgress exited:%p.",this ));
  366. }
  367. //!!always called from a lock
  368. void
  369. CH323Call::OnDisengageConfirm(
  370. IN DisengageConfirm* DCF
  371. )
  372. {
  373. H323DBG(( DEBUG_LEVEL_TRACE, "OnDisengageConfirm entered:%p.",this ));
  374. if( DCF -> requestSeqNum != m_wDRQSeqNum )
  375. {
  376. return;
  377. }
  378. if( m_dwRASCallState == RASCALL_STATE_DRQSENT )
  379. {
  380. if( m_hDRQTimer != NULL )
  381. {
  382. DeleteTimerQueueTimer( H323TimerQueue, m_hDRQTimer,
  383. NULL );
  384. m_hDRQTimer = NULL;
  385. }
  386. //nikhil:if this is a replacement call/diverted call then this may lead
  387. //to inconsistent behaviour
  388. m_dwRASCallState = RASCALL_STATE_UNREGISTERED;
  389. //CloseCall( 0 );
  390. }
  391. H323DBG(( DEBUG_LEVEL_TRACE, "OnDisengageConfirm exited:%p.",this ));
  392. }
  393. //!!always called from a lock
  394. void
  395. CH323Call::OnAdmissionConfirm(
  396. IN AdmissionConfirm * ACF
  397. )
  398. {
  399. PH323_CALL pCall = NULL;
  400. H323DBG(( DEBUG_LEVEL_TRACE, "OnAdmissionConfirm entered:%p.",this ));
  401. _ASSERTE( m_dwRASCallState != RASCALL_STATE_IDLE );
  402. if( ACF -> requestSeqNum != m_wARQSeqNum )
  403. {
  404. return;
  405. }
  406. if( m_hARQTimer != NULL )
  407. {
  408. DeleteTimerQueueTimer( H323TimerQueue, m_hARQTimer,
  409. NULL );
  410. m_hARQTimer = NULL;
  411. m_dwARQRetryCount = 0;
  412. }
  413. if( m_dwRASCallState == RASCALL_STATE_ARQSENT )
  414. {
  415. m_dwRASCallState = RASCALL_STATE_REGISTERED;
  416. if( m_dwOrigin == LINECALLORIGIN_OUTBOUND )
  417. {
  418. if( (ACF ->destCallSignalAddress.choice != ipAddress_chosen) ||
  419. (ACF->destCallSignalAddress.u.ipAddress.ip.length != 4) )
  420. {
  421. DropCall( LINEDISCONNECTMODE_BADADDRESS );
  422. return;
  423. }
  424. // save converted address
  425. m_CalleeAddr.nAddrType = H323_IP_BINARY;
  426. m_CalleeAddr.Addr.IP_Binary.dwAddr =
  427. ntohl(*(DWORD*)(ACF->destCallSignalAddress.u.ipAddress.ip.value) );
  428. m_CalleeAddr.Addr.IP_Binary.wPort =
  429. ACF->destCallSignalAddress.u.ipAddress.port;
  430. m_CalleeAddr.bMulticast =
  431. IN_MULTICAST(m_CalleeAddr.Addr.IP_Binary.dwAddr);
  432. //Replaces the first alias in the callee list (the dialableAddress
  433. //passed in TSPI_lineMakecall ). The GK looks at the first alias
  434. //only. Its assumed that only the first alias is mapped by the GK.
  435. if( (ACF -> bit_mask & AdmissionConfirm_destinationInfo_present) &&
  436. ACF->destinationInfo )
  437. {
  438. MapAliasItem( m_pCalleeAliasNames,
  439. &(ACF->destinationInfo->value) );
  440. }
  441. if( !PlaceCall() )
  442. {
  443. DropCall( LINEDISCONNECTMODE_UNREACHABLE );
  444. }
  445. }
  446. else
  447. {
  448. if( (m_dwCallType & CALLTYPE_TRANSFEREDDEST) && m_hdRelatedCall )
  449. {
  450. MSPMessageData* pMSPMessageData = new MSPMessageData;
  451. if( pMSPMessageData == NULL )
  452. {
  453. CloseCall( 0 );
  454. return;
  455. }
  456. pMSPMessageData->hdCall = m_hdRelatedCall;
  457. pMSPMessageData->messageType = SP_MSG_PrepareToAnswer;
  458. pMSPMessageData->pbEncodedBuf = m_prepareToAnswerMsgData.pbBuffer;
  459. pMSPMessageData->wLength = (WORD)m_prepareToAnswerMsgData.dwLength;
  460. pMSPMessageData->hReplacementCall = m_hdCall;
  461. m_prepareToAnswerMsgData.pbBuffer = NULL;
  462. QueueUserWorkItem( SendMSPMessageOnRelatedCall,
  463. pMSPMessageData, WT_EXECUTEDEFAULT );
  464. }
  465. else
  466. {
  467. // signal incoming call
  468. _ASSERTE(!m_htCall);
  469. PostLineEvent (
  470. LINE_NEWCALL,
  471. (DWORD_PTR)m_hdCall,
  472. (DWORD_PTR)&m_htCall, 0);
  473. _ASSERTE( m_htCall );
  474. if( m_htCall == NULL )
  475. {
  476. H323DBG(( DEBUG_LEVEL_ERROR, "tapi call handle NULL!!" ));
  477. CloseCall( 0 );
  478. return;
  479. }
  480. if( IsListEmpty(&m_IncomingU2U) == FALSE )
  481. {
  482. // signal incoming
  483. PostLineEvent (
  484. LINE_CALLINFO,
  485. (DWORD_PTR)LINECALLINFOSTATE_USERUSERINFO,
  486. 0, 0);
  487. }
  488. ChangeCallState( LINECALLSTATE_OFFERING, 0 );
  489. // send the new call message to the unspecified MSP
  490. SendMSPMessage( SP_MSG_PrepareToAnswer,
  491. m_prepareToAnswerMsgData.pbBuffer,
  492. m_prepareToAnswerMsgData.dwLength, NULL );
  493. }
  494. if( m_prepareToAnswerMsgData.pbBuffer )
  495. delete m_prepareToAnswerMsgData.pbBuffer;
  496. ZeroMemory( (PVOID)&m_prepareToAnswerMsgData, sizeof(BUFFERDESCR) );
  497. }
  498. }
  499. else if( m_dwRASCallState == RASCALL_STATE_ARQEXPIRED )
  500. {
  501. SendDRQ( forcedDrop_chosen, NOT_RESEND_SEQ_NUM, TRUE );
  502. }
  503. H323DBG(( DEBUG_LEVEL_TRACE, "OnAdmissionConfirm exited:%p.",this ));
  504. }
  505. //!!always called from a lock
  506. void
  507. CH323Call::OnAdmissionReject(
  508. IN AdmissionReject * ARJ
  509. )
  510. {
  511. H323DBG(( DEBUG_LEVEL_TRACE, "OnAdmissionReject entered:%p.",this ));
  512. if( ARJ -> requestSeqNum != m_wARQSeqNum )
  513. {
  514. return;
  515. }
  516. m_dwRASCallState = RASCALL_STATE_ARJRECVD;
  517. //If a forward consult call then enable the forwarding anyway.
  518. if( (m_dwCallType & CALLTYPE_FORWARDCONSULT )&&
  519. (m_dwOrigin == LINECALLORIGIN_OUTBOUND ) )
  520. {
  521. //Success of forwarding
  522. EnableCallForwarding();
  523. }
  524. //drop the call. shutdown the call and rlease the call.
  525. CloseCall( LINEDISCONNECTMODE_BADADDRESS );
  526. H323DBG(( DEBUG_LEVEL_TRACE, "OnAdmissionReject exited:%p.",this ));
  527. }
  528. HRESULT
  529. CH323Call::GetCallInfo (
  530. OUT GUID * ReturnCallID,
  531. OUT GUID * ReturnConferenceID )
  532. {
  533. //verify call state
  534. if( m_dwCallState == LINECALLSTATE_DISCONNECTED )
  535. {
  536. return E_FAIL;
  537. }
  538. *ReturnCallID = m_callIdentifier;
  539. *ReturnConferenceID = m_ConferenceID;
  540. return S_OK;
  541. }
  542. void
  543. NTAPI CH323Call::DRQExpiredCallback(
  544. IN PVOID ContextParameter, // pExpireContext
  545. IN BOOLEAN TimerFired // not used
  546. )
  547. {
  548. EXPIRE_CONTEXT * pExpireContext;
  549. HDRVCALL DriverCall;
  550. PH323_CALL pCall;
  551. _ASSERTE(ContextParameter);
  552. pExpireContext = (EXPIRE_CONTEXT *) ContextParameter;
  553. _ASSERTE( pExpireContext == m_pDRQExpireContext );
  554. __try
  555. {
  556. DriverCall = (HDRVCALL) pExpireContext -> DriverCallHandle;
  557. pCall = g_pH323Line -> FindH323CallAndLock (DriverCall);
  558. if (pCall)
  559. {
  560. pCall -> DRQExpired (pExpireContext -> seqNumber);
  561. delete pExpireContext;
  562. pCall -> Unlock();
  563. }
  564. else
  565. {
  566. H323DBG ((DEBUG_LEVEL_ERROR, "warning: DRQExpiredCallback failed to locate call object"));
  567. }
  568. }
  569. __except( 1 )
  570. {
  571. // The call has already been deleted and hence the pExpireContext
  572. // buffer is also deleted.
  573. return;
  574. }
  575. }
  576. void
  577. NTAPI CH323Call::ARQExpiredCallback(
  578. IN PVOID ContextParameter, // pExpireContext
  579. IN BOOLEAN TimerFired) // not used
  580. {
  581. EXPIRE_CONTEXT * pExpireContext;
  582. HDRVCALL DriverCall;
  583. PH323_CALL pCall;
  584. _ASSERTE(ContextParameter);
  585. pExpireContext = (EXPIRE_CONTEXT *) ContextParameter;
  586. _ASSERTE( pExpireContext == m_pARQExpireContext );
  587. __try
  588. {
  589. DriverCall = (HDRVCALL) pExpireContext -> DriverCallHandle;
  590. pCall = g_pH323Line -> FindH323CallAndLock (DriverCall);
  591. if (pCall)
  592. {
  593. pCall -> ARQExpired (pExpireContext -> seqNumber);
  594. delete pExpireContext;
  595. pCall -> Unlock();
  596. }
  597. else
  598. {
  599. H323DBG ((DEBUG_LEVEL_ERROR, "warning: ARQExpiredCallback failed to locate call object"));
  600. }
  601. }
  602. __except( 1 )
  603. {
  604. // The call has already been deleted and hence the pExpireContext
  605. // buffer is also deleted.
  606. return;
  607. }
  608. }
  609. //!!always called from a lock
  610. void CH323Call::ARQExpired (
  611. IN WORD seqNumber)
  612. {
  613. H323DBG(( DEBUG_LEVEL_TRACE, "ARQExpired entered:%p.",this ));
  614. m_pARQExpireContext = NULL;
  615. if( m_hARQTimer != NULL )
  616. {
  617. DeleteTimerQueueTimer( H323TimerQueue, m_hARQTimer, NULL );
  618. m_hARQTimer = NULL;
  619. }
  620. if( m_dwRASCallState == RASCALL_STATE_ARQSENT )
  621. {
  622. if( m_dwARQRetryCount < ARQ_RETRY_MAX )
  623. {
  624. if( !SendARQ( (long)seqNumber ) )
  625. {
  626. // drop call using disconnect mode
  627. DropCall(0);
  628. }
  629. }
  630. else
  631. {
  632. m_dwRASCallState = RASCALL_STATE_ARQEXPIRED;
  633. //Not able to register, shutdown the RAS client object
  634. CloseCall( 0 );
  635. }
  636. }
  637. H323DBG(( DEBUG_LEVEL_TRACE, "ARQExpired exited:%p.",this ));
  638. }
  639. //!!always called from a lock
  640. void
  641. CH323Call::DRQExpired(
  642. IN WORD seqNumber
  643. )
  644. {
  645. H323DBG(( DEBUG_LEVEL_TRACE, "DRQExpired entered:%p.", this ));
  646. m_pDRQExpireContext = NULL;
  647. if( m_hDRQTimer != NULL )
  648. {
  649. DeleteTimerQueueTimer( H323TimerQueue, m_hDRQTimer, NULL );
  650. m_hDRQTimer = NULL;
  651. }
  652. if( m_dwRASCallState == RASCALL_STATE_DRQSENT )
  653. {
  654. if( m_dwDRQRetryCount < DRQ_RETRY_MAX )
  655. {
  656. if( !SendDRQ( forcedDrop_chosen, (long)seqNumber, TRUE ) )
  657. {
  658. // drop call using disconnect mode
  659. DropCall(0);
  660. }
  661. }
  662. else
  663. {
  664. m_dwRASCallState = RASCALL_STATE_DRQEXPIRED;
  665. //Not able to register, shutdown the RAS client object
  666. CloseCall( 0 );
  667. }
  668. }
  669. H323DBG(( DEBUG_LEVEL_TRACE, "DRQExpired exited:%p.",this ));
  670. }