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.

1529 lines
50 KiB

  1. /************************************************************************
  2. * *
  3. * INTEL CORPORATION PROPRIETARY INFORMATION *
  4. * *
  5. * This software is supplied under the terms of a license *
  6. * agreement or non-disclosure agreement with Intel Corporation *
  7. * and may not be copied or disclosed except in accordance *
  8. * with the terms of that agreement. *
  9. * *
  10. * Copyright (C) 1997 Intel Corp. All Rights Reserved *
  11. * *
  12. * $Archive: S:\sturgeon\src\gki\vcs\dcall.cpv $
  13. * *
  14. * $Revision: 1.12 $
  15. * $Date: 25 Feb 1997 11:46:24 $
  16. * *
  17. * $Author: CHULME $
  18. * *
  19. * $Log: S:\sturgeon\src\gki\vcs\dcall.cpv $
  20. //
  21. // Rev 1.12 25 Feb 1997 11:46:24 CHULME
  22. // Memset CallInfo structure to zero to avoid unwanted data
  23. //
  24. // Rev 1.11 17 Jan 1997 15:53:50 CHULME
  25. // Put debug variables on conditional compile to avoid release warnings
  26. //
  27. // Rev 1.10 17 Jan 1997 09:01:22 CHULME
  28. // Changed reg.h to gkreg.h to avoid name conflict with inc directory
  29. //
  30. // Rev 1.9 10 Jan 1997 17:42:04 CHULME
  31. // Added CRV and conferenceID to CallReturnInfo structure
  32. //
  33. // Rev 1.8 10 Jan 1997 16:13:36 CHULME
  34. // Removed MFC dependency
  35. //
  36. // Rev 1.7 20 Dec 1996 16:38:58 CHULME
  37. // Removed extraneous debug statements
  38. //
  39. // Rev 1.6 20 Dec 1996 14:08:32 CHULME
  40. // Swapped send and recv addresses in infoRequestResponse
  41. //
  42. // Rev 1.5 19 Dec 1996 19:11:54 CHULME
  43. // Set originator bit in IRR
  44. //
  45. // Rev 1.4 19 Dec 1996 17:59:52 CHULME
  46. // Use dest addr from ACF in IRR if call made with just Alias
  47. //
  48. // Rev 1.3 17 Dec 1996 18:22:24 CHULME
  49. // Switch src and destination fields on ARQ for Callee
  50. //
  51. // Rev 1.2 02 Dec 1996 23:50:52 CHULME
  52. // Added premptive synchronization code
  53. //
  54. // Rev 1.1 22 Nov 1996 15:21:20 CHULME
  55. // Added VCS log to the header
  56. *************************************************************************/
  57. // dcall.cpp : Provides the implementation for the CCall class
  58. //
  59. #include "precomp.h"
  60. #include <process.h>
  61. #include "GKICOM.H"
  62. #include "dspider.h"
  63. #include "dgkilit.h"
  64. #include "DGKIPROT.H"
  65. #include "gksocket.h"
  66. #include "GKREG.H"
  67. #include "dcall.h"
  68. #include "GATEKPR.H"
  69. #include "h225asn.h"
  70. #include "coder.hpp"
  71. #include "dgkiext.h"
  72. #include <objbase.h>
  73. #include "iras.h"
  74. #ifdef _DEBUG
  75. #undef THIS_FILE
  76. static char THIS_FILE[] = __FILE__;
  77. #endif
  78. /////////////////////////////////////////////////////////////////////////////
  79. // CCall construction
  80. CCall::CCall()
  81. {
  82. // ABSTRACT: The constructor for the CCall class will initialize
  83. // the member variables.
  84. // AUTHOR: Colin Hulme
  85. #ifdef _DEBUG
  86. char szGKDebug[80];
  87. #endif
  88. SPIDER_TRACE(SP_CONDES, "CCall::CCall()\n", 0);
  89. memset(&m_CallIdentifier, 0, sizeof(m_CallIdentifier));
  90. memset(&m_callType, 0, sizeof(CallType));
  91. m_pRemoteInfo = 0;
  92. memset(&m_RemoteCallSignalAddress, 0, sizeof(TransportAddress));
  93. m_pDestExtraCallInfo = 0;
  94. memset(&m_LocalCallSignalAddress, 0, sizeof(TransportAddress));
  95. m_bandWidth = 0;
  96. m_callReferenceValue = 0;
  97. memset(&m_conferenceID, 0, sizeof(ConferenceIdentifier));
  98. m_activeMC = 0;
  99. m_answerCall = 0;
  100. m_usTimeTilStatus = DEFAULT_STATUS_PERIOD; // Reset on ACF
  101. m_uRetryResetCount = GKCALL_RETRY_INTERVAL_SECONDS;
  102. m_uRetryCountdown =GKCALL_RETRY_INTERVAL_SECONDS;
  103. m_uMaxRetryCount = GKCALL_RETRY_MAX;
  104. m_CFbandWidth = 0;
  105. m_CallReturnInfo.hCall = 0;
  106. memset(&m_CallReturnInfo.callModel, 0, sizeof(CallModel));
  107. memset(&m_CallReturnInfo.destCallSignalAddress, 0, sizeof(TransportAddress));
  108. m_CallReturnInfo.bandWidth = 0;
  109. m_CallReturnInfo.callReferenceValue = 0;
  110. memset(&m_CallReturnInfo.conferenceID, 0, sizeof(ConferenceIdentifier));
  111. m_CallReturnInfo.wError = 0;
  112. m_CFirrFrequency = 0;
  113. m_State = GK_ADM_PENDING;
  114. SPIDER_TRACE(SP_STATE, "m_State = GK_ADM_PENDING (%X)\n", this);
  115. m_pRasMessage = 0;
  116. m_usRetryCount = 0;
  117. }
  118. /////////////////////////////////////////////////////////////////////////////
  119. // CCall destruction
  120. CCall::~CCall()
  121. {
  122. // ABSTRACT: The destructor for the CCall class must free the
  123. // memory allocated for the Alias addresses. It does this by
  124. // deleting the structures and walking the link list.
  125. // AUTHOR: Colin Hulme
  126. SeqAliasAddr *pAA1, *pAA2;
  127. #ifdef _DEBUG
  128. char szGKDebug[80];
  129. #endif
  130. SPIDER_TRACE(SP_CONDES, "CCall::~CCall()\n", 0);
  131. m_CallReturnInfo.hCall = 0; // Delete self reference
  132. // Delete allocated memory for sequence of alias addresses
  133. pAA1 = m_pRemoteInfo;
  134. while (pAA1 != 0)
  135. {
  136. pAA2 = pAA1->next;
  137. if (pAA1->value.choice == h323_ID_chosen)
  138. {
  139. SPIDER_TRACE(SP_NEWDEL, "del pAA1->value.u.h323_ID.value = %X\n", pAA1->value.u.h323_ID.value);
  140. delete pAA1->value.u.h323_ID.value;
  141. }
  142. SPIDER_TRACE(SP_NEWDEL, "del pAA1 = %X\n", pAA1);
  143. delete pAA1;
  144. pAA1 = pAA2;
  145. }
  146. pAA1 = m_pDestExtraCallInfo;
  147. while (pAA1 != 0)
  148. {
  149. pAA2 = pAA1->next;
  150. if (pAA1->value.choice == h323_ID_chosen)
  151. {
  152. SPIDER_TRACE(SP_NEWDEL, "del pAA1->value.u.h323_ID.value = %X\n", pAA1->value.u.h323_ID.value);
  153. delete pAA1->value.u.h323_ID.value;
  154. }
  155. SPIDER_TRACE(SP_NEWDEL, "del pAA1 = %X\n", pAA1);
  156. delete pAA1;
  157. pAA1 = pAA2;
  158. }
  159. // Delete memory for last RAS message if still allocated
  160. if (m_pRasMessage)
  161. {
  162. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  163. delete m_pRasMessage;
  164. m_pRasMessage = 0;
  165. }
  166. }
  167. HRESULT
  168. CCall::AddRemoteInfo(AliasAddress& rvalue)
  169. {
  170. // ABSTRACT: This procedure is called to add an alias address
  171. // to the link list of alias addresses. This will
  172. // be called for each alias on receiving a GKI_AdmissionRequest.
  173. // A local copy is made to avoid reliance on the client
  174. // keeping the memory valid.
  175. // This procedure returns 0 if successful and non-zero
  176. // for a failure.
  177. // AUTHOR: Colin Hulme
  178. SeqAliasAddr *p1;
  179. unsigned short uIdx;
  180. unsigned short *pus;
  181. #ifdef _DEBUG
  182. char szGKDebug[80];
  183. #endif
  184. SPIDER_TRACE(SP_FUNC, "CRegistration::AddRemoteInfo(%X)\n", rvalue.choice);
  185. if (m_pRemoteInfo == 0) // First one in the list
  186. {
  187. m_pRemoteInfo = new SeqAliasAddr;
  188. SPIDER_TRACE(SP_NEWDEL, "new m_pRemoteInfo = %X\n", m_pRemoteInfo);
  189. if (m_pRemoteInfo == 0)
  190. return (GKI_NO_MEMORY);
  191. memset(m_pRemoteInfo, 0, sizeof(SeqAliasAddr));
  192. p1 = m_pRemoteInfo;
  193. }
  194. else
  195. {
  196. for (p1 = m_pRemoteInfo; p1->next != 0; p1 = p1->next)
  197. ; // walk the list til last entry
  198. p1->next = new SeqAliasAddr;
  199. SPIDER_TRACE(SP_NEWDEL, "new p1->next = %X\n", p1->next);
  200. if (p1->next == 0)
  201. return (GKI_NO_MEMORY);
  202. memset(p1->next, 0, sizeof(SeqAliasAddr));
  203. p1 = p1->next;
  204. }
  205. p1->next = 0; // initialize new structure fields
  206. p1->value = rvalue;
  207. if (p1->value.choice == h323_ID_chosen)
  208. {
  209. pus = new unsigned short[p1->value.u.h323_ID.length];
  210. SPIDER_TRACE(SP_NEWDEL, "new pus = %X\n", pus);
  211. if (pus == 0)
  212. return (GKI_NO_MEMORY);
  213. memset(pus, 0, sizeof(unsigned short) * p1->value.u.h323_ID.length);
  214. for (uIdx = 0; uIdx < p1->value.u.h323_ID.length; uIdx++)
  215. *(pus + uIdx) = *(p1->value.u.h323_ID.value + uIdx);
  216. p1->value.u.h323_ID.value = pus;
  217. }
  218. return (GKI_OK);
  219. }
  220. HRESULT
  221. CCall::AddDestExtraCallInfo(AliasAddress& rvalue)
  222. {
  223. // ABSTRACT: This procedure is called to add an alias address
  224. // to the link list of alias addresses. This will
  225. // be called for each alias on receiving a GKI_AdmissionRequest.
  226. // A local copy is made to avoid reliance on the client
  227. // keeping the memory valid.
  228. // This procedure returns 0 if successful and non-zero
  229. // for a failure.
  230. // AUTHOR: Colin Hulme
  231. SeqAliasAddr *p1;
  232. unsigned short uIdx;
  233. unsigned short *pus;
  234. #ifdef _DEBUG
  235. char szGKDebug[80];
  236. #endif
  237. SPIDER_TRACE(SP_FUNC, "CRegistration::AddDestExtraCallInfo(%X)\n", rvalue.choice);
  238. if (m_pDestExtraCallInfo == 0) // First one in the list
  239. {
  240. m_pDestExtraCallInfo = new SeqAliasAddr;
  241. SPIDER_TRACE(SP_NEWDEL, "new m_pDestExtraCallInfo = %X\n", m_pDestExtraCallInfo);
  242. if (m_pDestExtraCallInfo == 0)
  243. return (GKI_NO_MEMORY);
  244. memset(m_pDestExtraCallInfo, 0, sizeof(SeqAliasAddr));
  245. p1 = m_pDestExtraCallInfo;
  246. }
  247. else
  248. {
  249. for (p1 = m_pDestExtraCallInfo; p1->next != 0; p1 = p1->next)
  250. ; // walk the list til last entry
  251. p1->next = new SeqAliasAddr;
  252. SPIDER_TRACE(SP_NEWDEL, "new p1->next = %X\n", p1->next);
  253. if (p1->next == 0)
  254. return (GKI_NO_MEMORY);
  255. memset(p1->next, 0, sizeof(SeqAliasAddr));
  256. p1 = p1->next;
  257. }
  258. p1->next = 0; // initialize new structure fields
  259. p1->value = rvalue;
  260. if (p1->value.choice == h323_ID_chosen)
  261. {
  262. pus = new unsigned short[p1->value.u.h323_ID.length];
  263. SPIDER_TRACE(SP_NEWDEL, "new pus = %X\n", pus);
  264. if (pus == 0)
  265. return (GKI_NO_MEMORY);
  266. memset(pus, 0, sizeof(unsigned short) * p1->value.u.h323_ID.length);
  267. for (uIdx = 0; uIdx < p1->value.u.h323_ID.length; uIdx++)
  268. *(pus + uIdx) = *(p1->value.u.h323_ID.value + uIdx);
  269. p1->value.u.h323_ID.value = pus;
  270. }
  271. return (GKI_OK);
  272. }
  273. HRESULT
  274. CCall::SetLocalCallSignalAddress(unsigned short usCallTransport)
  275. {
  276. TransportAddress *pTA;
  277. pTA = g_pReg->GetTransportAddress(usCallTransport);
  278. if (pTA == NULL)
  279. return (GKI_NO_TA_ERROR);
  280. m_LocalCallSignalAddress = *pTA;
  281. return (GKI_OK);
  282. }
  283. void
  284. CCall::SetConferenceID(ConferenceIdentifier *pCID)
  285. {
  286. if ((pCID == NULL) || (pCID->length == 0))
  287. GenerateConferenceID();
  288. else
  289. m_conferenceID = *pCID;
  290. }
  291. void
  292. CCall::GenerateConferenceID(void)
  293. {
  294. CoCreateGuid((struct _GUID *)m_conferenceID.value);
  295. m_conferenceID.length = 16;
  296. }
  297. HRESULT
  298. CCall::AdmissionRequest(void)
  299. {
  300. // ABSTRACT: This procedure will create an AdmissionRequest structure
  301. // call the encoder and send the PDU. If it is successful, it
  302. // will return 0, else it will return an error code. Note: The
  303. // memory allocated for the RAS Message is not freed until either
  304. // a response from the gatekeeper or it times out. This allows
  305. // for retransmission without having to rebuild this message.
  306. // AUTHOR: Colin Hulme
  307. ASN1_BUF Asn1Buf;
  308. DWORD dwErrorCode;
  309. #ifdef _DEBUG
  310. char szGKDebug[80];
  311. #endif
  312. SPIDER_TRACE(SP_FUNC, "CCall::AdmissionRequest()\n", 0);
  313. ASSERT(g_pCoder);
  314. if (g_pCoder == NULL)
  315. return (GKI_NOT_INITIALIZED);
  316. // Copy call reference value and CRV into the return info structure
  317. m_CallReturnInfo.callReferenceValue = m_callReferenceValue;
  318. m_CallReturnInfo.conferenceID = m_conferenceID;
  319. // Allocate a RasMessage structure and initialized to 0
  320. m_usRetryCount = 0;
  321. m_uRetryCountdown = m_uRetryResetCount;
  322. m_pRasMessage = new RasMessage;
  323. SPIDER_TRACE(SP_NEWDEL, "new m_pRasMessage = %X\n", m_pRasMessage);
  324. if (m_pRasMessage == 0)
  325. return (GKI_NO_MEMORY);
  326. memset(m_pRasMessage, 0, sizeof(RasMessage));
  327. // Setup structure fields for AdmissionRequest
  328. m_pRasMessage->choice = admissionRequest_chosen;
  329. if (m_pDestExtraCallInfo != 0)
  330. m_pRasMessage->u.admissionRequest.bit_mask |= AdmissionRequest_destExtraCallInfo_present;
  331. m_pRasMessage->u.admissionRequest.requestSeqNum = g_pReg->GetNextSeqNum();
  332. m_pRasMessage->u.admissionRequest.callType = m_callType;
  333. m_pRasMessage->u.admissionRequest.endpointIdentifier = g_pReg->GetEndpointIdentifier();
  334. memcpy(&m_pRasMessage->u.admissionRequest.callIdentifier.guid.value,
  335. &m_CallIdentifier, sizeof(GUID));
  336. m_pRasMessage->u.admissionRequest.callIdentifier.guid.length = sizeof(GUID);
  337. m_pRasMessage->u.admissionRequest.bit_mask |= AdmissionRequest_callIdentifier_present;
  338. if (m_answerCall) // Src & Dest are swapped in callee
  339. {
  340. if (g_pReg->GetAlias() != NULL)
  341. {
  342. m_pRasMessage->u.admissionRequest.bit_mask
  343. |= AdmissionRequest_destinationInfo_present;
  344. }
  345. if (m_LocalCallSignalAddress.choice != 0)
  346. {
  347. m_pRasMessage->u.admissionRequest.bit_mask
  348. |= AdmissionRequest_destCallSignalAddress_present;
  349. }
  350. m_pRasMessage->u.admissionRequest.destinationInfo = (PAdmissionRequest_destinationInfo)g_pReg->GetAlias();
  351. m_pRasMessage->u.admissionRequest.destCallSignalAddress = m_LocalCallSignalAddress;
  352. m_pRasMessage->u.admissionRequest.srcInfo = (PAdmissionRequest_srcInfo)m_pRemoteInfo;
  353. if (m_RemoteCallSignalAddress.choice != 0)
  354. {
  355. m_pRasMessage->u.admissionRequest.bit_mask |= srcCallSignalAddress_present;
  356. m_pRasMessage->u.admissionRequest.srcCallSignalAddress = m_RemoteCallSignalAddress;
  357. }
  358. }
  359. else
  360. {
  361. if (m_pRemoteInfo != 0)
  362. {
  363. m_pRasMessage->u.admissionRequest.bit_mask
  364. |= AdmissionRequest_destinationInfo_present;
  365. }
  366. else if (m_RemoteCallSignalAddress.choice != 0)
  367. {
  368. m_pRasMessage->u.admissionRequest.bit_mask
  369. |= AdmissionRequest_destCallSignalAddress_present;
  370. m_pRasMessage->u.admissionRequest.destCallSignalAddress = m_RemoteCallSignalAddress;
  371. }
  372. m_pRasMessage->u.admissionRequest.destinationInfo = (PAdmissionRequest_destinationInfo)m_pRemoteInfo;
  373. m_pRasMessage->u.admissionRequest.srcInfo = (PAdmissionRequest_srcInfo)g_pReg->GetAlias();
  374. }
  375. m_pRasMessage->u.admissionRequest.destExtraCallInfo = (PAdmissionRequest_destExtraCallInfo)m_pDestExtraCallInfo;
  376. m_pRasMessage->u.admissionRequest.bandWidth = m_bandWidth;
  377. m_pRasMessage->u.admissionRequest.callReferenceValue = m_callReferenceValue;
  378. m_pRasMessage->u.admissionRequest.conferenceID = m_conferenceID;
  379. // The following casts are because ASN1_BOOL is a char and BOOL is an int
  380. // since the values of m_activeMC and m_answerCall are always 0 or 1, the
  381. // cast to char causes no loss of data
  382. m_pRasMessage->u.admissionRequest.activeMC = (ASN1_BOOL)m_activeMC;
  383. m_pRasMessage->u.admissionRequest.answerCall = (ASN1_BOOL)m_answerCall;
  384. #ifdef _DEBUG
  385. if (dwGKIDLLFlags & SP_DUMPMEM)
  386. DumpMem(m_pRasMessage, sizeof(RasMessage));
  387. #endif
  388. // Encode the PDU & send it
  389. dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf);
  390. if (dwErrorCode)
  391. return (GKI_ENCODER_ERROR);
  392. // Create a backup copy of the encoded PDU if using debug echo support
  393. if (fGKIEcho)
  394. {
  395. pEchoBuff = new char[Asn1Buf.length];
  396. SPIDER_TRACE(SP_NEWDEL, "new pEchoBuff = %X\n", pEchoBuff);
  397. if (pEchoBuff == 0)
  398. return (GKI_NO_MEMORY);
  399. memcpy(pEchoBuff, (char *)Asn1Buf.value, Asn1Buf.length);
  400. nEchoLen = Asn1Buf.length;
  401. }
  402. SPIDER_TRACE(SP_PDU, "Send ARQ; pCall = %X\n", this);
  403. if (fGKIDontSend == FALSE)
  404. if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  405. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  406. // Free the encoder memory
  407. g_pCoder->Free(Asn1Buf);
  408. return (GKI_OK);
  409. }
  410. HRESULT
  411. CCall::BandwidthRequest(void)
  412. {
  413. // ABSTRACT: This procedure will create a bandwidthRequest structure
  414. // call the encoder and send the PDU. If it is successful, it
  415. // will return 0, else it will return an error code.
  416. // AUTHOR: Colin Hulme
  417. ASN1_BUF Asn1Buf;
  418. DWORD dwErrorCode;
  419. #ifdef _DEBUG
  420. char szGKDebug[80];
  421. #endif
  422. SPIDER_TRACE(SP_FUNC, "CCall::BandwidthRequest()\n", 0);
  423. ASSERT(g_pCoder);
  424. if (g_pCoder == NULL)
  425. return (GKI_NOT_INITIALIZED);
  426. // Allocate a RasMessage structure and initialized to 0
  427. m_usRetryCount = 0;
  428. m_uRetryCountdown = m_uRetryResetCount;
  429. m_pRasMessage = new RasMessage;
  430. SPIDER_TRACE(SP_NEWDEL, "new m_pRasMessage = %X\n", m_pRasMessage);
  431. if (m_pRasMessage == 0)
  432. return (GKI_NO_MEMORY);
  433. memset(m_pRasMessage, 0, sizeof(RasMessage));
  434. // Setup structure fields for BandwidthRequest
  435. m_pRasMessage->choice = bandwidthRequest_chosen;
  436. m_pRasMessage->u.bandwidthRequest.bit_mask = callType_present;
  437. m_pRasMessage->u.bandwidthRequest.requestSeqNum = g_pReg->GetNextSeqNum();
  438. m_pRasMessage->u.bandwidthRequest.endpointIdentifier = g_pReg->GetEndpointIdentifier();
  439. m_pRasMessage->u.bandwidthRequest.conferenceID = m_conferenceID;
  440. m_pRasMessage->u.bandwidthRequest.callReferenceValue = m_callReferenceValue;
  441. m_pRasMessage->u.bandwidthRequest.callType = m_callType;
  442. m_pRasMessage->u.bandwidthRequest.bandWidth = m_bandWidth;
  443. memcpy(&m_pRasMessage->u.bandwidthRequest.callIdentifier.guid.value,
  444. &m_CallIdentifier, sizeof(GUID));
  445. m_pRasMessage->u.bandwidthRequest.callIdentifier.guid.length = sizeof(GUID);
  446. m_pRasMessage->u.bandwidthRequest.bit_mask
  447. |= BandwidthRequest_callIdentifier_present;
  448. #ifdef _DEBUG
  449. if (dwGKIDLLFlags & SP_DUMPMEM)
  450. DumpMem(m_pRasMessage, sizeof(RasMessage));
  451. #endif
  452. // Encode the PDU & send it
  453. dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf);
  454. if (dwErrorCode)
  455. return (GKI_ENCODER_ERROR);
  456. // Create a backup copy of the encoded PDU if using debug echo support
  457. if (fGKIEcho)
  458. {
  459. pEchoBuff = new char[Asn1Buf.length];
  460. SPIDER_TRACE(SP_NEWDEL, "new pEchoBuff = %X\n", pEchoBuff);
  461. if (pEchoBuff == 0)
  462. return (GKI_NO_MEMORY);
  463. memcpy(pEchoBuff, (char *)Asn1Buf.value, Asn1Buf.length);
  464. nEchoLen = Asn1Buf.length;
  465. }
  466. m_State = GK_BW_PENDING;
  467. SPIDER_TRACE(SP_STATE, "m_State = GK_BW_PENDING (%X)\n", this);
  468. SPIDER_TRACE(SP_PDU, "Send BRQ; pCall = %X\n", this);
  469. if (fGKIDontSend == FALSE)
  470. if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  471. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  472. // Free the encoder memory
  473. g_pCoder->Free(Asn1Buf);
  474. return (GKI_OK);
  475. }
  476. HRESULT
  477. CCall::DisengageRequest(void)
  478. {
  479. // ABSTRACT: This procedure will create a disengageRequest structure
  480. // call the encoder and send the PDU. If it is successful, it
  481. // will return 0, else it will return an error code.
  482. // AUTHOR: Colin Hulme
  483. ASN1_BUF Asn1Buf;
  484. DWORD dwErrorCode;
  485. #ifdef _DEBUG
  486. char szGKDebug[80];
  487. #endif
  488. SPIDER_TRACE(SP_FUNC, "CCall::DisengageRequest()\n", 0);
  489. ASSERT(g_pCoder);
  490. if (g_pCoder == NULL)
  491. return (GKI_NOT_INITIALIZED);
  492. // Allocate a RasMessage structure and initialized to 0
  493. m_usRetryCount = 0;
  494. m_uRetryCountdown = m_uRetryResetCount;
  495. m_pRasMessage = new RasMessage;
  496. SPIDER_TRACE(SP_NEWDEL, "new m_pRasMessage = %X\n", m_pRasMessage);
  497. if (m_pRasMessage == 0)
  498. return (GKI_NO_MEMORY);
  499. memset(m_pRasMessage, 0, sizeof(RasMessage));
  500. // Setup structure fields for DisengageRequest
  501. m_pRasMessage->choice = disengageRequest_chosen;
  502. m_pRasMessage->u.disengageRequest.bit_mask = 0;
  503. m_pRasMessage->u.disengageRequest.requestSeqNum = g_pReg->GetNextSeqNum();
  504. m_pRasMessage->u.disengageRequest.endpointIdentifier = g_pReg->GetEndpointIdentifier();
  505. m_pRasMessage->u.disengageRequest.conferenceID = m_conferenceID;
  506. m_pRasMessage->u.disengageRequest.callReferenceValue = m_callReferenceValue;
  507. m_pRasMessage->u.disengageRequest.disengageReason.choice = normalDrop_chosen;
  508. memcpy(&m_pRasMessage->u.disengageRequest.callIdentifier.guid.value,
  509. &m_CallIdentifier, sizeof(GUID));
  510. m_pRasMessage->u.disengageRequest.callIdentifier.guid.length = sizeof(GUID);
  511. m_pRasMessage->u.disengageRequest.bit_mask
  512. |= DisengageRequest_callIdentifier_present;
  513. #ifdef _DEBUG
  514. if (dwGKIDLLFlags & SP_DUMPMEM)
  515. DumpMem(m_pRasMessage, sizeof(RasMessage));
  516. #endif
  517. // Encode the PDU & send it
  518. dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf);
  519. if (dwErrorCode)
  520. return (GKI_ENCODER_ERROR);
  521. // Create a backup copy of the encoded PDU if using debug echo support
  522. if (fGKIEcho)
  523. {
  524. pEchoBuff = new char[Asn1Buf.length];
  525. SPIDER_TRACE(SP_NEWDEL, "new pEchoBuff = %X\n", pEchoBuff);
  526. if (pEchoBuff == 0)
  527. return (GKI_NO_MEMORY);
  528. memcpy(pEchoBuff, (char *)Asn1Buf.value, Asn1Buf.length);
  529. nEchoLen = Asn1Buf.length;
  530. }
  531. m_State = GK_DISENG_PENDING;
  532. SPIDER_TRACE(SP_STATE, "m_State = GK_DISENG_PENDING (%X)\n", this);
  533. SPIDER_TRACE(SP_PDU, "Send DRQ; pCall = %X\n", this);
  534. if (fGKIDontSend == FALSE)
  535. if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  536. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  537. // Free the encoder memory
  538. g_pCoder->Free(Asn1Buf);
  539. return (GKI_OK);
  540. }
  541. HRESULT
  542. CCall::AdmissionConfirm(RasMessage *pRasMessage)
  543. {
  544. // ABSTRACT: This function is called if an admissionConfirm is
  545. // received. We must ensure that this matches an outstanding
  546. // admissionRequest.
  547. // It will delete the memory used for the admissionRequest
  548. // change the state and notify the user by posting a message.
  549. // Additional information contained in the admissionConfirm
  550. // is stored in the CCall class.
  551. // AUTHOR: Colin Hulme
  552. #ifdef _DEBUG
  553. unsigned int nIdx;
  554. char szGKDebug[80];
  555. #endif
  556. SPIDER_TRACE(SP_FUNC, "CCall::AdmissionConfirm(%X)\n", pRasMessage);
  557. ASSERT(g_pCoder && g_pGatekeeper);
  558. if ((g_pCoder == NULL) && (g_pGatekeeper == NULL))
  559. return (GKI_NOT_INITIALIZED);
  560. // Verify we are in the correct state, have an outstanding admissionRequest
  561. // and the sequence numbers match
  562. if ((m_State != GK_ADM_PENDING) ||
  563. (pRasMessage->u.admissionConfirm.requestSeqNum !=
  564. m_pRasMessage->u.admissionRequest.requestSeqNum))
  565. return (g_pReg->UnknownMessage(pRasMessage));
  566. // Delete allocated RasMessage storage
  567. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  568. delete m_pRasMessage;
  569. m_pRasMessage = 0;
  570. // Update member variables
  571. m_State = GK_CALL;
  572. SPIDER_TRACE(SP_STATE, "m_State = GK_CALL (%X)\n", this);
  573. if (pRasMessage->u.admissionConfirm.bit_mask & irrFrequency_present)
  574. {
  575. m_CFirrFrequency = pRasMessage->u.admissionConfirm.irrFrequency;
  576. m_usTimeTilStatus =
  577. (unsigned short)(((DWORD)m_CFirrFrequency * 1000) / GKR_RETRY_TICK_MS);
  578. SPIDER_DEBUG(m_usTimeTilStatus);
  579. }
  580. else
  581. m_usTimeTilStatus = 0; // Don't auto-send status datagrams
  582. m_CFbandWidth = pRasMessage->u.admissionConfirm.bandWidth;
  583. m_CallReturnInfo.hCall = this;
  584. m_CallReturnInfo.callModel = pRasMessage->u.admissionConfirm.callModel;
  585. m_CallReturnInfo.destCallSignalAddress = pRasMessage->u.admissionConfirm.destCallSignalAddress;
  586. m_CallReturnInfo.bandWidth = m_CFbandWidth;
  587. m_CallReturnInfo.wError = 0;
  588. #ifdef _DEBUG
  589. SPIDER_TRACE(SP_GKI, "PostMessage(hWnd, wBaseMessage + GKI_ADM_CONFIRM, 0, %X)\n", &m_CallReturnInfo);
  590. wsprintf(szGKDebug, "\thCall=%p\n", m_CallReturnInfo.hCall);
  591. OutputDebugString(szGKDebug);
  592. wsprintf(szGKDebug, "\tcallModel=%X\n", m_CallReturnInfo.callModel.choice);
  593. OutputDebugString(szGKDebug);
  594. wsprintf(szGKDebug, "\tbandWidth=%X\n", m_CallReturnInfo.bandWidth);
  595. OutputDebugString(szGKDebug);
  596. wsprintf(szGKDebug, "\tcallReferenceValue=%X\n", m_CallReturnInfo.callReferenceValue);
  597. OutputDebugString(szGKDebug);
  598. OutputDebugString("\tconferenceID=");
  599. for (nIdx = 0; nIdx < m_CallReturnInfo.conferenceID.length; nIdx++)
  600. {
  601. wsprintf(szGKDebug, "%02X", m_CallReturnInfo.conferenceID.value[nIdx]);
  602. OutputDebugString(szGKDebug);
  603. }
  604. wsprintf(szGKDebug, "\n\twError=%X\n", m_CallReturnInfo.wError);
  605. OutputDebugString(szGKDebug);
  606. #endif
  607. PostMessage(g_pReg->GetHWnd(),
  608. g_pReg->GetBaseMessage() + GKI_ADM_CONFIRM,
  609. 0, (LPARAM)&m_CallReturnInfo);
  610. return (GKI_OK);
  611. }
  612. HRESULT
  613. CCall::AdmissionReject(RasMessage *pRasMessage)
  614. {
  615. // ABSTRACT: This function is called if an admissionReject is
  616. // received. We must ensure that this matches an outstanding
  617. // admissionRequest.
  618. // It will delete the memory used for the admissionRequest
  619. // change the state and notify the user by posting a message
  620. // If this function returns GKI_DELETE_CALL, the calling function
  621. // will delete the CCall object.
  622. // AUTHOR: Colin Hulme
  623. #ifdef _DEBUG
  624. char szGKDebug[80];
  625. #endif
  626. SPIDER_TRACE(SP_FUNC, "CCall::AdmissionReject(%X)\n", pRasMessage);
  627. // Verify we are in the correct state, have an outstanding admissionRequest
  628. // and the sequence numbers match
  629. if ((m_State != GK_ADM_PENDING) ||
  630. (pRasMessage->u.admissionReject.requestSeqNum !=
  631. m_pRasMessage->u.admissionRequest.requestSeqNum))
  632. return (g_pReg->UnknownMessage(pRasMessage));
  633. // We deliberately don't free the RasMessage memory. Let the call destructor
  634. // do it - this provides protection from other requests for this hCall.
  635. m_State = GK_DISENGAGED;
  636. SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this);
  637. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_ADM_REJECT, %X, 0)\n",
  638. pRasMessage->u.admissionReject.rejectReason.choice);
  639. PostMessage(g_pReg->GetHWnd(),
  640. g_pReg->GetBaseMessage() + GKI_ADM_REJECT,
  641. (WORD)pRasMessage->u.admissionReject.rejectReason.choice, 0L);
  642. return (GKI_DELETE_CALL);
  643. }
  644. HRESULT
  645. CCall::BandwidthConfirm(RasMessage *pRasMessage)
  646. {
  647. // ABSTRACT: This function is called if a bandwidthConfirm is
  648. // received. We must ensure that this matches an outstanding
  649. // bandwidthRequest.
  650. // It will delete the memory used for the bandwidthRequest,
  651. // change the state and notify the user by posting a message.
  652. // AUTHOR: Colin Hulme
  653. #ifdef _DEBUG
  654. unsigned int nIdx;
  655. char szGKDebug[80];
  656. #endif
  657. SPIDER_TRACE(SP_FUNC, "CCall::BandwidthConfirm(%X)\n", pRasMessage);
  658. // Verify we are in the correct state, have an outstanding admissionRequest
  659. // and the sequence numbers match
  660. if ((m_State != GK_BW_PENDING) ||
  661. (pRasMessage->u.bandwidthConfirm.requestSeqNum !=
  662. m_pRasMessage->u.bandwidthRequest.requestSeqNum))
  663. return (g_pReg->UnknownMessage(pRasMessage));
  664. // Delete allocated RasMessage storage
  665. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  666. delete m_pRasMessage;
  667. m_pRasMessage = 0;
  668. // Update member variables
  669. m_State = GK_CALL;
  670. SPIDER_TRACE(SP_STATE, "m_State = GK_CALL (%X)\n", this);
  671. m_CFbandWidth = pRasMessage->u.bandwidthConfirm.bandWidth;
  672. m_CallReturnInfo.bandWidth = m_CFbandWidth;
  673. // Notify user application
  674. #ifdef _DEBUG
  675. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_BW_CONFIRM, 0, %X)\n", &m_CallReturnInfo);
  676. wsprintf(szGKDebug, "\thCall=%p\n", m_CallReturnInfo.hCall);
  677. OutputDebugString(szGKDebug);
  678. wsprintf(szGKDebug, "\tcallModel=%X\n", m_CallReturnInfo.callModel.choice);
  679. OutputDebugString(szGKDebug);
  680. wsprintf(szGKDebug, "\tbandWidth=%X\n", m_CallReturnInfo.bandWidth);
  681. OutputDebugString(szGKDebug);
  682. wsprintf(szGKDebug, "\tcallReferenceValue=%X\n", m_CallReturnInfo.callReferenceValue);
  683. OutputDebugString(szGKDebug);
  684. OutputDebugString("\tconferenceID=");
  685. for (nIdx = 0; nIdx < m_CallReturnInfo.conferenceID.length; nIdx++)
  686. {
  687. wsprintf(szGKDebug, "%02X", m_CallReturnInfo.conferenceID.value[nIdx]);
  688. OutputDebugString(szGKDebug);
  689. }
  690. wsprintf(szGKDebug, "\n\twError=%X\n", m_CallReturnInfo.wError);
  691. OutputDebugString(szGKDebug);
  692. #endif
  693. PostMessage(g_pReg->GetHWnd(),
  694. g_pReg->GetBaseMessage() + GKI_BW_CONFIRM, 0, (LPARAM)&m_CallReturnInfo);
  695. return (GKI_OK);
  696. }
  697. HRESULT
  698. CCall::BandwidthReject(RasMessage *pRasMessage)
  699. {
  700. // ABSTRACT: This function is called if a bandwidthReject is
  701. // received. We must ensure that this matches an outstanding
  702. // bandwidthRequest.
  703. // It will delete the memory used for the bandwidthRequest
  704. // change the state and notify the user by posting a message
  705. // AUTHOR: Colin Hulme
  706. #ifdef _DEBUG
  707. unsigned int nIdx;
  708. char szGKDebug[80];
  709. #endif
  710. SPIDER_TRACE(SP_FUNC, "CCall::BandwidthReject(%X)\n", pRasMessage);
  711. // Verify we are in the correct state, have an outstanding admissionRequest
  712. // and the sequence numbers match
  713. if ((m_State != GK_BW_PENDING) ||
  714. (pRasMessage->u.bandwidthReject.requestSeqNum !=
  715. m_pRasMessage->u.bandwidthRequest.requestSeqNum))
  716. return (g_pReg->UnknownMessage(pRasMessage));
  717. // Delete allocate RasMessage storage
  718. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  719. delete m_pRasMessage;
  720. m_pRasMessage = 0;
  721. // Update member variables
  722. m_State = GK_CALL;
  723. SPIDER_TRACE(SP_STATE, "m_State = GK_CALL (%X)\n", this);
  724. m_CFbandWidth = pRasMessage->u.bandwidthReject.allowedBandWidth;
  725. m_CallReturnInfo.bandWidth = m_CFbandWidth;
  726. // Notify user application
  727. #ifdef _DEBUG
  728. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_BW_REJECT, %X, &m_CallReturnInfo)\n",
  729. pRasMessage->u.bandwidthReject.rejectReason.choice);
  730. wsprintf(szGKDebug, "\thCall=%p\n", m_CallReturnInfo.hCall);
  731. OutputDebugString(szGKDebug);
  732. wsprintf(szGKDebug, "\tcallModel=%X\n", m_CallReturnInfo.callModel.choice);
  733. OutputDebugString(szGKDebug);
  734. wsprintf(szGKDebug, "\tbandWidth=%X\n", m_CallReturnInfo.bandWidth);
  735. OutputDebugString(szGKDebug);
  736. wsprintf(szGKDebug, "\tcallReferenceValue=%X\n", m_CallReturnInfo.callReferenceValue);
  737. OutputDebugString(szGKDebug);
  738. OutputDebugString("\tconferenceID=");
  739. for (nIdx = 0; nIdx < m_CallReturnInfo.conferenceID.length; nIdx++)
  740. {
  741. wsprintf(szGKDebug, "%02X", m_CallReturnInfo.conferenceID.value[nIdx]);
  742. OutputDebugString(szGKDebug);
  743. }
  744. wsprintf(szGKDebug, "\n\twError=%X\n", m_CallReturnInfo.wError);
  745. OutputDebugString(szGKDebug);
  746. #endif
  747. PostMessage(g_pReg->GetHWnd(),
  748. g_pReg->GetBaseMessage() + GKI_BW_REJECT,
  749. (WORD)pRasMessage->u.bandwidthReject.rejectReason.choice,
  750. (LPARAM)&m_CallReturnInfo);
  751. return (GKI_OK);
  752. }
  753. HRESULT
  754. CCall::SendBandwidthConfirm(RasMessage *pRasMessage)
  755. {
  756. // ABSTRACT: This function is called when a bandwidthRequest is
  757. // received from the gatekeeper. It will create the
  758. // bandwidthConfirm structure, encode it and send
  759. // it on the net. It posts a message to the user
  760. // notifying them.
  761. // AUTHOR: Colin Hulme
  762. ASN1_BUF Asn1Buf;
  763. DWORD dwErrorCode;
  764. RasMessage *pRespRasMessage;
  765. #ifdef _DEBUG
  766. unsigned int nIdx;
  767. char szGKDebug[80];
  768. #endif
  769. SPIDER_TRACE(SP_FUNC, "CCall::SendBandwidthConfirm(%X)\n", pRasMessage);
  770. // Verify we are in the correct state
  771. if (m_State != GK_CALL)
  772. return (g_pReg->UnknownMessage(pRasMessage));
  773. // Update member variables
  774. m_CFbandWidth = pRasMessage->u.bandwidthRequest.bandWidth;
  775. m_CallReturnInfo.bandWidth = m_CFbandWidth;
  776. // Allocate a RasMessage structure and initialized to 0
  777. pRespRasMessage = new RasMessage;
  778. SPIDER_TRACE(SP_NEWDEL, "new pRespRasMessage = %X\n", pRespRasMessage);
  779. if (pRespRasMessage == 0)
  780. return (GKI_NO_MEMORY);
  781. memset(pRespRasMessage, 0, sizeof(RasMessage));
  782. // Setup structure fields for BandwidthConfirm
  783. pRespRasMessage->choice = bandwidthConfirm_chosen;
  784. pRespRasMessage->u.bandwidthConfirm.requestSeqNum =
  785. pRasMessage->u.bandwidthRequest.requestSeqNum;
  786. pRespRasMessage->u.bandwidthConfirm.bandWidth =
  787. pRasMessage->u.bandwidthRequest.bandWidth;
  788. #ifdef _DEBUG
  789. if (dwGKIDLLFlags & SP_DUMPMEM)
  790. DumpMem(pRespRasMessage, sizeof(RasMessage));
  791. #endif
  792. // Encode the PDU & send it
  793. dwErrorCode = g_pCoder->Encode(pRespRasMessage, &Asn1Buf);
  794. if (dwErrorCode)
  795. return (GKI_ENCODER_ERROR);
  796. SPIDER_TRACE(SP_PDU, "Send BCF; pCall = %X\n", this);
  797. if (fGKIDontSend == FALSE)
  798. if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  799. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  800. // Free the encoder memory
  801. g_pCoder->Free(Asn1Buf);
  802. // Delete allocated RasMessage storage
  803. SPIDER_TRACE(SP_NEWDEL, "del pRespRasMessage = %X\n", pRespRasMessage);
  804. delete pRespRasMessage;
  805. // Notify user of received bandwidth request
  806. #ifdef _DEBUG
  807. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_BW_CONFIRM, 0, %X)\n",
  808. &m_CallReturnInfo);
  809. wsprintf(szGKDebug, "\thCall=%p\n", m_CallReturnInfo.hCall);
  810. OutputDebugString(szGKDebug);
  811. wsprintf(szGKDebug, "\tcallModel=%X\n", m_CallReturnInfo.callModel.choice);
  812. OutputDebugString(szGKDebug);
  813. wsprintf(szGKDebug, "\tbandWidth=%X\n", m_CallReturnInfo.bandWidth);
  814. OutputDebugString(szGKDebug);
  815. wsprintf(szGKDebug, "\tcallReferenceValue=%X\n", m_CallReturnInfo.callReferenceValue);
  816. OutputDebugString(szGKDebug);
  817. OutputDebugString("\tconferenceID=");
  818. for (nIdx = 0; nIdx < m_CallReturnInfo.conferenceID.length; nIdx++)
  819. {
  820. wsprintf(szGKDebug, "%02X", m_CallReturnInfo.conferenceID.value[nIdx]);
  821. OutputDebugString(szGKDebug);
  822. }
  823. wsprintf(szGKDebug, "\n\twError=%X\n", m_CallReturnInfo.wError);
  824. OutputDebugString(szGKDebug);
  825. #endif
  826. PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_BW_CONFIRM,
  827. 0, (LPARAM)&m_CallReturnInfo);
  828. return (GKI_OK);
  829. }
  830. HRESULT
  831. CCall::DisengageConfirm(RasMessage *pRasMessage)
  832. {
  833. // ABSTRACT: This function is called if a disengageConfirm is
  834. // received. We must ensure that this matches an outstanding
  835. // disengageRequest.
  836. // It will delete the memory used for the disengageRequest,
  837. // change the state and notify the user by posting a message.
  838. // If this function returns GKI_DELETE_CALL, the calling function
  839. // will delete the CCall object.
  840. // AUTHOR: Colin Hulme
  841. #ifdef _DEBUG
  842. char szGKDebug[80];
  843. #endif
  844. SPIDER_TRACE(SP_FUNC, "CCall::DisengageConfirm(%X)\n", pRasMessage);
  845. // Verify we are in the correct state, have an outstanding disengageRequest
  846. // and the sequence numbers match
  847. if ((m_State != GK_DISENG_PENDING) ||
  848. (pRasMessage->u.disengageConfirm.requestSeqNum !=
  849. m_pRasMessage->u.disengageRequest.requestSeqNum))
  850. return (g_pReg->UnknownMessage(pRasMessage));
  851. // We deliberately don't free the RasMessage memory. Let the call destructor
  852. // do it - this provides protection from other requests for this hCall.
  853. // Update member variables
  854. m_State = GK_DISENGAGED;
  855. SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this);
  856. // Notify user application
  857. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_DISENG_CONFIRM, 0, %X)\n",
  858. this);
  859. PostMessage(g_pReg->GetHWnd(),
  860. g_pReg->GetBaseMessage() + GKI_DISENG_CONFIRM, 0, (LPARAM)this);
  861. return (GKI_DELETE_CALL);
  862. }
  863. HRESULT
  864. CCall::DisengageReject(RasMessage *pRasMessage)
  865. {
  866. // ABSTRACT: This function is called if a disengageReject is
  867. // received. We must ensure that this matches an outstanding
  868. // disengageRequest.
  869. // It will delete the memory used for the disengageRequest
  870. // change the state and notify the user by posting a message
  871. // If this function returns GKI_DELETE_CALL, the calling function
  872. // will delete the CCall object.
  873. // AUTHOR: Colin Hulme
  874. #ifdef _DEBUG
  875. char szGKDebug[80];
  876. #endif
  877. HRESULT hResult = GKI_OK;
  878. SPIDER_TRACE(SP_FUNC, "CCall::DisengageReject(%X)\n", pRasMessage);
  879. // Verify we are in the correct state, have an outstanding disengageRequest
  880. // and the sequence numbers match
  881. if ((m_State != GK_DISENG_PENDING) ||
  882. (pRasMessage->u.disengageReject.requestSeqNum !=
  883. m_pRasMessage->u.disengageRequest.requestSeqNum))
  884. return (g_pReg->UnknownMessage(pRasMessage));
  885. // Update member variables
  886. switch (pRasMessage->u.disengageReject.rejectReason.choice)
  887. {
  888. case requestToDropOther_chosen: // return to GK_CALL state
  889. m_State = GK_CALL;
  890. SPIDER_TRACE(SP_STATE, "m_State = GK_CALL (%X)\n", this);
  891. // Delete allocate RasMessage storage
  892. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  893. delete m_pRasMessage;
  894. m_pRasMessage = 0;
  895. break;
  896. case DsnggRjctRsn_ntRgstrd_chosen:
  897. default:
  898. m_State = GK_DISENGAGED;
  899. SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this);
  900. hResult = GKI_DELETE_CALL;
  901. // We deliberately don't free the RasMessage memory. Let the call destructor
  902. // do it - this provides protection from other requests for this hCall.
  903. break;
  904. }
  905. // Notify user application
  906. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_DISENG_REJECT, %X, hCall)\n",
  907. pRasMessage->u.disengageReject.rejectReason.choice);
  908. PostMessage(g_pReg->GetHWnd(),
  909. g_pReg->GetBaseMessage() + GKI_DISENG_REJECT,
  910. (WORD)pRasMessage->u.disengageReject.rejectReason.choice,
  911. (LPARAM)this);
  912. return (hResult);
  913. }
  914. HRESULT
  915. CCall::SendDisengageConfirm(RasMessage *pRasMessage)
  916. {
  917. // ABSTRACT: This function is called when a disengageRequest is
  918. // received from the gatekeeper. It will create the
  919. // disengageConfirm structure, encode it and send
  920. // it on the net. It posts a message to the user
  921. // notifying them.
  922. // AUTHOR: Colin Hulme
  923. ASN1_BUF Asn1Buf;
  924. DWORD dwErrorCode;
  925. RasMessage *pRespRasMessage;
  926. #ifdef _DEBUG
  927. char szGKDebug[80];
  928. #endif
  929. SPIDER_TRACE(SP_FUNC, "CCall::SendDisengageConfirm(%X)\n", pRasMessage);
  930. ASSERT(g_pCoder);
  931. if (g_pCoder == NULL)
  932. return (GKI_NOT_INITIALIZED);
  933. // Verify we are in the correct state
  934. if (m_State != GK_CALL)
  935. return (g_pReg->UnknownMessage(pRasMessage));
  936. // Allocate a RasMessage structure and initialized to 0
  937. pRespRasMessage = new RasMessage;
  938. SPIDER_TRACE(SP_NEWDEL, "new pRespRasMessage = %X\n", pRespRasMessage);
  939. if (pRespRasMessage == 0)
  940. return (GKI_NO_MEMORY);
  941. memset(pRespRasMessage, 0, sizeof(RasMessage));
  942. // Setup structure fields for DisengageConfirm
  943. pRespRasMessage->choice = disengageConfirm_chosen;
  944. pRespRasMessage->u.disengageConfirm.requestSeqNum =
  945. pRasMessage->u.disengageRequest.requestSeqNum;
  946. #ifdef _DEBUG
  947. if (dwGKIDLLFlags & SP_DUMPMEM)
  948. DumpMem(pRespRasMessage, sizeof(RasMessage));
  949. #endif
  950. // Encode the PDU & send it
  951. dwErrorCode = g_pCoder->Encode(pRespRasMessage, &Asn1Buf);
  952. if (dwErrorCode)
  953. return (GKI_ENCODER_ERROR);
  954. m_State = GK_DISENGAGED;
  955. SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this);
  956. SPIDER_TRACE(SP_PDU, "Send DCF; pCall = %X\n", this);
  957. if (fGKIDontSend == FALSE)
  958. if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  959. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  960. // Free the encoder memory
  961. g_pCoder->Free(Asn1Buf);
  962. // Delete allocated RasMessage storage
  963. SPIDER_TRACE(SP_NEWDEL, "del pRespRasMessage = %X\n", pRespRasMessage);
  964. delete pRespRasMessage;
  965. // Notify user of received disengage request
  966. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_DISENG_CONFIRM, 0, %X)\n",
  967. this);
  968. PostMessage(g_pReg->GetHWnd(), g_pReg->GetBaseMessage() + GKI_DISENG_CONFIRM,
  969. 0, (LPARAM)this);
  970. return (GKI_DELETE_CALL);
  971. }
  972. HRESULT
  973. CCall::Retry(void)
  974. {
  975. // ABSTRACT: This function is called by the CRegistration Retry function
  976. // at the configured time interval. It will check if there
  977. // are any outstanding PDUs for the Call object
  978. // If so, they will be retransmitted. If the maximum number of
  979. // retries has expired, the memory will be cleaned up.
  980. // This function will return 0 to the background thread unless
  981. // it wants the thread to terminate. This function will
  982. // also send the IRR status datagram for the conference
  983. // if the time period has expired.
  984. // AUTHOR: Colin Hulme
  985. ASN1_BUF Asn1Buf;
  986. DWORD dwErrorCode;
  987. #ifdef _DEBUG
  988. char szGKDebug[80];
  989. #endif
  990. HRESULT hResult = GKI_OK;
  991. // SPIDER_TRACE(SP_FUNC, "CCall::Retry()\n", 0);
  992. ASSERT(g_pCoder && g_pGatekeeper);
  993. if ((g_pCoder == NULL) && (g_pGatekeeper == NULL))
  994. return (GKI_NOT_INITIALIZED);
  995. // Check to see if status datagram is required
  996. if (m_usTimeTilStatus) // No auto-status if 0
  997. {
  998. if (--m_usTimeTilStatus == 0)
  999. {
  1000. // Reset timer
  1001. m_usTimeTilStatus =
  1002. (unsigned short)(((DWORD)m_CFirrFrequency * 1000) / GKR_RETRY_TICK_MS);
  1003. hResult = SendInfoRequestResponse(0, 0, TRUE); // send unsolicited status datagram
  1004. if (hResult != GKI_OK)
  1005. return (hResult);
  1006. }
  1007. }
  1008. // Check to see if PDU retransmission is required
  1009. if (m_pRasMessage && (--m_uRetryCountdown == 0))
  1010. {
  1011. // going to retry, reset countdown
  1012. m_uRetryCountdown = m_uRetryResetCount;
  1013. if (m_usRetryCount <= m_uMaxRetryCount)
  1014. {
  1015. // Encode the PDU & resend it
  1016. dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf);
  1017. if (dwErrorCode)
  1018. return (GKI_ENCODER_ERROR);
  1019. SPIDER_TRACE(SP_PDU, "RESend PDU; pCall = %X\n", this);
  1020. if (fGKIDontSend == FALSE)
  1021. if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  1022. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  1023. // Free the encoder memory
  1024. g_pCoder->Free(Asn1Buf);
  1025. m_usRetryCount++;
  1026. }
  1027. else // Retries expired - clean up
  1028. {
  1029. switch (m_pRasMessage->choice)
  1030. {
  1031. case admissionRequest_chosen:
  1032. m_State = GK_DISENGAGED;
  1033. SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this);
  1034. hResult = GKI_DELETE_CALL;
  1035. break;
  1036. case bandwidthRequest_chosen:
  1037. m_State = GK_CALL;
  1038. SPIDER_TRACE(SP_STATE, "m_State = GK_CALL (%X)\n", this);
  1039. break;
  1040. case disengageRequest_chosen:
  1041. m_State = GK_DISENGAGED;
  1042. SPIDER_TRACE(SP_STATE, "m_State = GK_DISENGAGED (%X)\n", this);
  1043. hResult = GKI_DELETE_CALL;
  1044. break;
  1045. }
  1046. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  1047. delete m_pRasMessage;
  1048. m_pRasMessage = 0;
  1049. // Notify user that gatekeeper didn't respond
  1050. #ifdef RETRY_REREG_FOREVER
  1051. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_ERROR, 0, GKI_NO_RESPONSE)\n", 0);
  1052. PostMessage(g_pReg->GetHWnd(),
  1053. g_pReg->GetBaseMessage() + GKI_ERROR,
  1054. 0, GKI_NO_RESPONSE);
  1055. #else
  1056. // end the call as if ARJ occurred
  1057. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_ADM_REJECT, ARJ_TIMEOUT, 0)\n", 0);
  1058. PostMessage(g_pReg->GetHWnd(),
  1059. g_pReg->GetBaseMessage() + GKI_ADM_REJECT,
  1060. ARJ_TIMEOUT, 0L);
  1061. #endif
  1062. }
  1063. }
  1064. return (hResult);
  1065. }
  1066. HRESULT
  1067. CCall::SendInfoRequestResponse(CallInfoStruct *pCallInfo, RasMessage *pRasMessage, BOOL fThisCallOnly)
  1068. {
  1069. // ABSTRACT: This function is called by the Retry thread if this call
  1070. // is due to report an unsolicited status to the gatekeeper.
  1071. // It is also called in response to a received IRQ. In the
  1072. // case of an IRQ, each active call should chain call the
  1073. // next active call. This allows construction of a link
  1074. // list of conference information that is then passed to the
  1075. // CRegistration::SendInfoRequestResponse function for
  1076. // encapsulation into the IRR message.
  1077. //
  1078. // The fThisCallOnly flag determines whether or not to walk the
  1079. // chain of calls in generating the response message.
  1080. //
  1081. // If fThisCallOnly == TRUE, the chain will not be walked, and
  1082. // this routine will call the CRegistration::SendInfoRequestResponse().
  1083. // AUTHOR: Colin Hulme, Dan Dexter
  1084. CallInfoStruct CallInfo;
  1085. CallInfoStruct *pCI;
  1086. #ifdef _DEBUG
  1087. char szGKDebug[80];
  1088. #endif
  1089. HRESULT hResult = GKI_OK;
  1090. SPIDER_TRACE(SP_FUNC, "CCall::SendInfoRequestResponse(%X)\n", pCallInfo);
  1091. memset(&CallInfo, 0, sizeof(CallInfo));
  1092. CallInfo.next = 0;
  1093. CallInfo.value.bit_mask = 0;
  1094. CallInfo.value.callReferenceValue = m_callReferenceValue;
  1095. CallInfo.value.conferenceID = m_conferenceID;
  1096. memcpy(&CallInfo.value.callIdentifier.guid.value,
  1097. &m_CallIdentifier, sizeof(GUID));
  1098. CallInfo.value.callIdentifier.guid.length = sizeof(GUID);
  1099. CallInfo.value.bit_mask
  1100. |= InfoRequestResponse_perCallInfo_Seq_callIdentifier_present;
  1101. CallInfo.value.bit_mask |= originator_present;
  1102. CallInfo.value.callSignaling.bit_mask = recvAddress_present;
  1103. CallInfo.value.callSignaling.recvAddress = m_LocalCallSignalAddress;
  1104. if (m_answerCall) // If I am the callee
  1105. {
  1106. // look out! if there has not been an ACF, m_CallReturnInfo.destCallSignalAddress
  1107. // is uninitialized. m_CallReturnInfo.hCall is set only after ACF
  1108. if(m_CallReturnInfo.hCall)
  1109. {
  1110. if (m_RemoteCallSignalAddress.choice)
  1111. {
  1112. CallInfo.value.callSignaling.sendAddress = m_RemoteCallSignalAddress;
  1113. CallInfo.value.callSignaling.bit_mask |= sendAddress_present;
  1114. }
  1115. CallInfo.value.originator = FALSE;
  1116. CallInfo.value.callModel = m_CallReturnInfo.callModel;
  1117. }
  1118. else
  1119. {
  1120. // we are typically in this path because we got an IRQ after
  1121. // sending an ARQ.
  1122. CallInfo.value.callModel.choice = direct_chosen;
  1123. }
  1124. }
  1125. else // I am the caller
  1126. {
  1127. // look out! if there has not been an ACF, m_CallReturnInfo.destCallSignalAddress
  1128. // is uninitialized. m_CallReturnInfo.hCall is set only after ACF
  1129. if(m_CallReturnInfo.hCall)
  1130. {
  1131. CallInfo.value.callSignaling.sendAddress = m_CallReturnInfo.destCallSignalAddress;
  1132. CallInfo.value.callSignaling.bit_mask |= sendAddress_present;
  1133. CallInfo.value.originator = TRUE;
  1134. CallInfo.value.callModel = m_CallReturnInfo.callModel;
  1135. }
  1136. else
  1137. {
  1138. // we are typically in this path because we got an IRQ after
  1139. // sending an ARQ.
  1140. CallInfo.value.callModel.choice = direct_chosen;
  1141. }
  1142. }
  1143. CallInfo.value.callType = m_callType;
  1144. CallInfo.value.bandWidth = m_CFbandWidth;
  1145. if (pCallInfo) // Add to chain of CallInfo structures
  1146. {
  1147. for (pCI = pCallInfo; pCI->next != 0; pCI = pCI->next)
  1148. ;
  1149. pCI->next = &CallInfo;
  1150. }
  1151. else // We're alone - just point to ours
  1152. pCallInfo = &CallInfo;
  1153. // If the IRR is not just for this call, then get the next call
  1154. // and call it's SendInfoRequestResponse() function. If there are no
  1155. // more calls, or this IRR was only for this call, call
  1156. // g_pReg->SendInfoRequestResponse()
  1157. CCall *pNextCall = NULL;
  1158. if (!fThisCallOnly)
  1159. {
  1160. pNextCall = g_pReg->GetNextCall(this);
  1161. }
  1162. if (pNextCall)
  1163. hResult = pNextCall->SendInfoRequestResponse(pCallInfo, pRasMessage, fThisCallOnly);
  1164. else
  1165. hResult = g_pReg->SendInfoRequestResponse(pCallInfo, pRasMessage);
  1166. return (hResult);
  1167. }
  1168. //
  1169. // MatchSeqNum()
  1170. //
  1171. // ABSTRACT:
  1172. // This function checks to see if the outstanding RAS request(s) it has
  1173. // match the sequence number passed in.
  1174. //
  1175. // RETURNS:
  1176. // TRUE if sequence number matches, FALSE otherwise
  1177. //
  1178. // AUTHOR: Dan Dexter
  1179. BOOL
  1180. CCall::MatchSeqNum(RequestSeqNum seqNum)
  1181. {
  1182. BOOL bRet = FALSE;
  1183. // If there is no RAS message, this sequence
  1184. // number can't be ours...
  1185. if (!m_pRasMessage)
  1186. return(FALSE);
  1187. // Look at the sequence number in the RAS message and see
  1188. // if it matches.
  1189. switch(m_pRasMessage->choice)
  1190. {
  1191. case gatekeeperRequest_chosen:
  1192. if (m_pRasMessage->u.gatekeeperRequest.requestSeqNum == seqNum)
  1193. bRet = TRUE;
  1194. break;
  1195. case gatekeeperConfirm_chosen:
  1196. if (m_pRasMessage->u.gatekeeperConfirm.requestSeqNum == seqNum)
  1197. bRet = TRUE;
  1198. break;
  1199. case gatekeeperReject_chosen:
  1200. if (m_pRasMessage->u.gatekeeperReject.requestSeqNum == seqNum)
  1201. bRet = TRUE;
  1202. break;
  1203. case registrationRequest_chosen:
  1204. if (m_pRasMessage->u.registrationRequest.requestSeqNum == seqNum)
  1205. bRet = TRUE;
  1206. break;
  1207. case registrationConfirm_chosen:
  1208. if (m_pRasMessage->u.registrationConfirm.requestSeqNum == seqNum)
  1209. bRet = TRUE;
  1210. break;
  1211. case registrationReject_chosen:
  1212. if (m_pRasMessage->u.registrationReject.requestSeqNum == seqNum)
  1213. bRet = TRUE;
  1214. break;
  1215. case unregistrationRequest_chosen:
  1216. if (m_pRasMessage->u.unregistrationRequest.requestSeqNum == seqNum)
  1217. bRet = TRUE;
  1218. break;
  1219. case unregistrationConfirm_chosen:
  1220. if (m_pRasMessage->u.unregistrationConfirm.requestSeqNum == seqNum)
  1221. bRet = TRUE;
  1222. break;
  1223. case unregistrationReject_chosen:
  1224. if (m_pRasMessage->u.unregistrationReject.requestSeqNum == seqNum)
  1225. bRet = TRUE;
  1226. break;
  1227. case admissionRequest_chosen:
  1228. if (m_pRasMessage->u.admissionRequest.requestSeqNum == seqNum)
  1229. bRet = TRUE;
  1230. break;
  1231. case admissionConfirm_chosen:
  1232. if (m_pRasMessage->u.admissionConfirm.requestSeqNum == seqNum)
  1233. bRet = TRUE;
  1234. break;
  1235. case admissionReject_chosen:
  1236. if (m_pRasMessage->u.admissionReject.requestSeqNum == seqNum)
  1237. bRet = TRUE;
  1238. break;
  1239. case bandwidthRequest_chosen:
  1240. if (m_pRasMessage->u.bandwidthRequest.requestSeqNum == seqNum)
  1241. bRet = TRUE;
  1242. break;
  1243. case bandwidthConfirm_chosen:
  1244. if (m_pRasMessage->u.bandwidthConfirm.requestSeqNum == seqNum)
  1245. bRet = TRUE;
  1246. break;
  1247. case bandwidthReject_chosen:
  1248. if (m_pRasMessage->u.bandwidthReject.requestSeqNum == seqNum)
  1249. bRet = TRUE;
  1250. break;
  1251. case disengageRequest_chosen:
  1252. if (m_pRasMessage->u.disengageRequest.requestSeqNum == seqNum)
  1253. bRet = TRUE;
  1254. break;
  1255. case disengageConfirm_chosen:
  1256. if (m_pRasMessage->u.disengageConfirm.requestSeqNum == seqNum)
  1257. bRet = TRUE;
  1258. break;
  1259. case disengageReject_chosen:
  1260. if (m_pRasMessage->u.disengageReject.requestSeqNum == seqNum)
  1261. bRet = TRUE;
  1262. break;
  1263. case locationRequest_chosen:
  1264. if (m_pRasMessage->u.locationRequest.requestSeqNum == seqNum)
  1265. bRet = TRUE;
  1266. break;
  1267. case locationConfirm_chosen:
  1268. if (m_pRasMessage->u.locationConfirm.requestSeqNum == seqNum)
  1269. bRet = TRUE;
  1270. break;
  1271. case locationReject_chosen:
  1272. if (m_pRasMessage->u.locationReject.requestSeqNum == seqNum)
  1273. bRet = TRUE;
  1274. break;
  1275. case infoRequest_chosen:
  1276. if (m_pRasMessage->u.infoRequest.requestSeqNum == seqNum)
  1277. bRet = TRUE;
  1278. break;
  1279. case infoRequestResponse_chosen:
  1280. if (m_pRasMessage->u.infoRequestResponse.requestSeqNum == seqNum)
  1281. bRet = TRUE;
  1282. break;
  1283. case nonStandardMessage_chosen:
  1284. if (m_pRasMessage->u.nonStandardMessage.requestSeqNum == seqNum)
  1285. bRet = TRUE;
  1286. break;
  1287. case unknownMessageResponse_chosen:
  1288. if (m_pRasMessage->u.unknownMessageResponse.requestSeqNum == seqNum)
  1289. bRet = TRUE;
  1290. break;
  1291. case requestInProgress_chosen:
  1292. if (m_pRasMessage->u.requestInProgress.requestSeqNum == seqNum)
  1293. bRet = TRUE;
  1294. break;
  1295. case resourcesAvailableIndicate_chosen:
  1296. if (m_pRasMessage->u.resourcesAvailableIndicate.requestSeqNum == seqNum)
  1297. bRet = TRUE;
  1298. break;
  1299. case resourcesAvailableConfirm_chosen:
  1300. if (m_pRasMessage->u.resourcesAvailableConfirm.requestSeqNum == seqNum)
  1301. bRet = TRUE;
  1302. break;
  1303. case infoRequestAck_chosen:
  1304. if (m_pRasMessage->u.infoRequestAck.requestSeqNum == seqNum)
  1305. bRet = TRUE;
  1306. break;
  1307. case infoRequestNak_chosen:
  1308. if (m_pRasMessage->u.infoRequestNak.requestSeqNum == seqNum)
  1309. bRet = TRUE;
  1310. break;
  1311. default:
  1312. break;
  1313. }
  1314. return bRet;
  1315. }
  1316. //
  1317. // MatchCRV()
  1318. //
  1319. // ABSTRACT:
  1320. // This function checks to see if the CallReferenceValue associated
  1321. // with this call object matches the CRV passed in.
  1322. //
  1323. // RETURNS:
  1324. // TRUE if CRV number matches, FALSE otherwise
  1325. //
  1326. // AUTHOR: Dan Dexter
  1327. BOOL
  1328. CCall::MatchCRV(CallReferenceValue crv)
  1329. {
  1330. return(crv == m_callReferenceValue);
  1331. }