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

2506 lines
74 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\gkreg.cpv $
  13. * *
  14. * $Revision: 1.6 $
  15. * $Date: 26 Feb 1997 15:33:34 $
  16. * *
  17. * $Author: CHULME $
  18. * *
  19. * $Log: S:\sturgeon\src\gki\vcs\gkreg.cpv $
  20. //
  21. // Rev 1.6 26 Feb 1997 15:33:34 CHULME
  22. // Call Coder.Free in case of error - potential memory leak plugged
  23. //
  24. // Rev 1.5 14 Feb 1997 16:43:06 CHULME
  25. // Updated comments and removed inaccurate comments
  26. //
  27. // Rev 1.4 12 Feb 1997 01:12:52 CHULME
  28. // Redid thread synchronization to use Gatekeeper.Lock
  29. //
  30. // Rev 1.3 08 Feb 1997 12:15:48 CHULME
  31. // Terminate retry thread in destructor via semaphore
  32. //
  33. // Rev 1.2 21 Jan 1997 17:24:06 CHULME
  34. // Removed gatekeeper identifier from gatekeeper request
  35. //
  36. // Rev 1.1 17 Jan 1997 09:02:22 CHULME
  37. // Changed reg.h to gkreg.h to avoid name conflict with inc directory
  38. //
  39. // Rev 1.0 17 Jan 1997 08:48:08 CHULME
  40. // Initial revision.
  41. //
  42. // Rev 1.7 10 Jan 1997 16:15:58 CHULME
  43. // Removed MFC dependency
  44. //
  45. // Rev 1.6 20 Dec 1996 16:39:14 CHULME
  46. // Removed extraneous debug statements
  47. //
  48. // Rev 1.5 20 Dec 1996 01:27:24 CHULME
  49. // Fixed memory leak with gatekeeper identifier
  50. //
  51. // Rev 1.4 10 Dec 1996 11:26:36 CHULME
  52. // Fixed handling of IRQ to not require response address in PDU
  53. //
  54. // Rev 1.3 02 Dec 1996 23:49:58 CHULME
  55. // Added premptive synchronization code
  56. //
  57. // Rev 1.2 22 Nov 1996 15:22:16 CHULME
  58. // Added VCS log to the header
  59. *************************************************************************/
  60. // registration.cpp : Provides the implementation for the CRegistration class
  61. //
  62. #include "precomp.h"
  63. #include <process.h>
  64. #include <stdlib.h>
  65. #include <time.h>
  66. #include "GKICOM.H"
  67. #include "dspider.h"
  68. #include "dgkilit.h"
  69. #include "DGKIPROT.H"
  70. #include "gksocket.h"
  71. #include "GKREG.H"
  72. #include "GATEKPR.H"
  73. #include "h225asn.h"
  74. #include "coder.hpp"
  75. #include "dgkiext.h"
  76. #include "ccerror.h"
  77. #ifdef _DEBUG
  78. #undef THIS_FILE
  79. static char THIS_FILE[] = __FILE__;
  80. #endif
  81. /////////////////////////////////////////////////////////////////////////////
  82. // CLinkedList Implementation
  83. template <class T> CLinkedList<T>::CLinkedList()
  84. {
  85. pTail = NULL;
  86. iCount = 0;
  87. }
  88. template <class T> CLinkedList<T>::~CLinkedList()
  89. {
  90. RemoveAll();
  91. }
  92. template <class T> void CLinkedList<T>::AddTail (const T& NewItem)
  93. {
  94. AddTailPriv(new TItem<T>(NewItem));
  95. }
  96. template <class T> void CLinkedList<T>::AddTailPriv(TItem<T> *pNewItem)
  97. {
  98. if (pTail) // if the list is non-empty - add to tail
  99. {
  100. pNewItem->pPrev = pTail;
  101. pNewItem->pNext = pTail->pNext; // preserve the pointer to the head.
  102. pTail->pNext->pPrev = pNewItem;
  103. pTail->pNext = pNewItem; // insert the new element
  104. }
  105. else // insert first element
  106. { // new element is the tail
  107. pNewItem->pPrev = pNewItem->pNext = pNewItem;
  108. }
  109. pTail = pNewItem; // move tail to the new item
  110. iCount++;
  111. }
  112. template <class T> BOOL CLinkedList<T>::IsEmpty(void)
  113. {
  114. if (pTail == NULL)
  115. { return TRUE; }
  116. else
  117. { return FALSE; }
  118. }
  119. template <class T> POS CLinkedList<T>::GetFirstPos (void)
  120. {
  121. if (pTail)
  122. { return (POS) pTail->pNext;
  123. }
  124. else
  125. { return NULL;
  126. }
  127. }
  128. template <class T> T CLinkedList<T>::GetNext (POS &Position)
  129. {
  130. TItem<T> *pCurItem = (TItem<T> *)Position;
  131. T RetValue;
  132. if (Position)
  133. {
  134. RetValue = pCurItem->Value;
  135. if (pCurItem == pTail) // we are at the end of the list
  136. { Position = NULL;
  137. }
  138. else // move to the next position
  139. { Position = (POS)(pCurItem->pNext);
  140. }
  141. }
  142. return RetValue;
  143. }
  144. template <class T> POS CLinkedList<T>::Find (const T& Item)
  145. {
  146. TItem<T> *pCurItem;
  147. if (!pTail)
  148. { return NULL;
  149. }
  150. else
  151. {
  152. pCurItem = pTail;
  153. do
  154. {
  155. pCurItem = pCurItem->pNext; // starting with the head
  156. if (pCurItem->Value == Item)
  157. { return ((POS) pCurItem); }
  158. }
  159. while (pCurItem != pTail);
  160. }
  161. return NULL;
  162. }
  163. // It moves Position to the next item after removint the current one.
  164. template <class T> BOOL CLinkedList<T>::RemoveAt (POS &Position)
  165. {
  166. TItem<T> *pCurItem = (TItem<T> *)Position;
  167. if (!pCurItem)
  168. { return FALSE; }
  169. else if (pCurItem == pCurItem->pNext) // The only element
  170. {
  171. Position = NULL;
  172. pTail = NULL;
  173. delete pCurItem;
  174. }
  175. else
  176. {
  177. Position = (POS) pCurItem->pNext;
  178. pCurItem->pPrev->pNext = pCurItem->pNext;
  179. pCurItem->pNext->pPrev = pCurItem->pPrev;
  180. if (pCurItem == pTail)
  181. {
  182. pTail = pCurItem->pPrev;
  183. }
  184. delete pCurItem;
  185. }
  186. iCount--;
  187. return TRUE;
  188. }
  189. template <class T> T CLinkedList<T>::GetAt(const POS Position)
  190. {
  191. TItem<T> *pCurItem = (TItem<T> *)Position;
  192. T RetValue;
  193. if (Position)
  194. { RetValue = pCurItem->Value;
  195. }
  196. return RetValue;
  197. }
  198. template <class T> void CLinkedList<T>::RemoveAll(void)
  199. {
  200. TItem<T> *pCurItem;
  201. TItem<T> *pNextItem;
  202. if (pTail)
  203. {
  204. pCurItem = pTail->pNext; // Start with the head.
  205. pTail->pNext = NULL;
  206. while (pCurItem != NULL)
  207. {
  208. pNextItem = pCurItem->pNext;
  209. delete pCurItem;
  210. pCurItem = pNextItem;
  211. }
  212. }
  213. pTail = NULL;
  214. iCount = 0;
  215. }
  216. template <class T> int CLinkedList<T>::GetCount(void)
  217. {
  218. return iCount;
  219. }
  220. VOID CALLBACK RetryTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
  221. {
  222. #ifdef _DEBUG
  223. char szGKDebug[80];
  224. #endif
  225. HRESULT hResult = GKI_OK;
  226. ASSERT(g_pGatekeeper);
  227. if(g_pGatekeeper == NULL)
  228. return;
  229. g_pGatekeeper->Lock();
  230. if(g_pReg)
  231. {
  232. hResult = g_pReg->Retry();
  233. }
  234. if(hResult != GKI_OK)
  235. {
  236. SPIDER_TRACE(SP_NEWDEL, "del g_pReg = %X\n", g_pReg);
  237. delete g_pReg;
  238. g_pReg = 0;
  239. }
  240. g_pGatekeeper->Unlock();
  241. }
  242. /////////////////////////////////////////////////////////////////////////////
  243. // CRegistration construction
  244. CRegistration::CRegistration()
  245. {
  246. // ABSTRACT: The constructor for the CRegistration class will initialize
  247. // the member variables. Notably missing is the construction
  248. // of the pointed to socket object. This must be done after
  249. // constructing this object to allow for checking the error code.
  250. // AUTHOR: Colin Hulme
  251. #ifdef _DEBUG
  252. char szGKDebug[80];
  253. #endif
  254. SPIDER_TRACE(SP_CONDES, "CRegistration::CRegistration()\n", 0);
  255. m_pVendorInfo = NULL;
  256. m_pCallSignalAddress = 0;
  257. memset(&m_terminalType, 0, sizeof(EndpointType));
  258. m_pRgstrtnRqst_trmnlAls = 0;
  259. m_hWnd = 0;
  260. m_wBaseMessage = 0;
  261. m_usRegistrationTransport = 0;
  262. m_pLocationInfo = 0;
  263. memset(&m_Location[0], 0, sizeof(TransportAddress) * 2);
  264. memset(&m_RCm_gtkprIdntfr, 0, sizeof(GatekeeperIdentifier));
  265. memset(&m_endpointID, 0, sizeof(EndpointIdentifier));
  266. m_requestSeqNum = 0;
  267. m_pRASAddress = 0;
  268. m_State = GK_REG_PENDING;
  269. SPIDER_TRACE(SP_STATE, "m_State = GK_REG_PENDING (%X)\n", this);
  270. m_pRasMessage = 0;
  271. m_pSocket = 0;
  272. m_hRcvThread = 0;
  273. // m_hRetryThread = 0;
  274. m_uTimer = 0;
  275. m_uRetryResetCount = GKR_RETRY_INTERVAL_SECONDS * (1000/GKR_RETRY_TICK_MS);
  276. m_uRetryCountdown = GKR_RETRY_INTERVAL_SECONDS;
  277. m_uMaxRetryCount = GKR_RETRY_MAX;
  278. m_usRetryCount = 0;
  279. InitializeCriticalSection(&m_SocketCRS);
  280. #ifdef BROADCAST_DISCOVERY
  281. m_hDiscThread = 0;
  282. #endif
  283. // m_dwLockingThread = 0;
  284. // m_hRetrySemaphore = NULL;
  285. // InitializeCriticalSection(&m_CriticalSection);
  286. // Initialize the base call reference value to a random number
  287. srand( (unsigned)time( NULL ) );
  288. m_usCallReferenceValue = (unsigned short)rand();
  289. }
  290. /////////////////////////////////////////////////////////////////////////////
  291. // CRegistration destruction
  292. CRegistration::~CRegistration()
  293. {
  294. // ABSTRACT: The destructor for the CRegistration class must free the
  295. // memory allocated for the Transport addresses and Alias
  296. // addresses. It does this by deleting the structures and
  297. // walking the link list.
  298. // AUTHOR: Colin Hulme
  299. SeqTransportAddr *pTA1, *pTA2;
  300. SeqAliasAddr *pAA1, *pAA2;
  301. DWORD dwErrorCode;
  302. #ifdef _DEBUG
  303. char szGKDebug[80];
  304. #endif
  305. SPIDER_TRACE(SP_CONDES, "CRegistration::~CRegistration()\n", 0);
  306. #if(0)
  307. // Terminate the Retry Thread
  308. if(m_hRetryThread)
  309. {
  310. if(m_hRetrySemaphore)
  311. {
  312. SPIDER_TRACE(SP_THREAD, "Release retry thread %X\n", m_hRetryThread);
  313. // Signal the thread to shutdown
  314. ReleaseSemaphore(m_hRetrySemaphore,1,NULL);
  315. // Wait for the thread to terminate
  316. dwErrorCode = WaitForSingleObject(m_hRetryThread, TIMEOUT_THREAD);
  317. m_hRetryThread = NULL;
  318. }
  319. }
  320. #else
  321. // Stop retry timer
  322. if(m_uTimer)
  323. {
  324. KillTimer(m_hWnd, m_uTimer);
  325. }
  326. #endif
  327. if(m_pVendorInfo)
  328. FreeVendorInfo(m_pVendorInfo);
  329. // Delete allocated memory for sequence of call signal addresses
  330. pTA1 = m_pCallSignalAddress;
  331. while (pTA1 != 0)
  332. {
  333. pTA2 = pTA1->next;
  334. SPIDER_TRACE(SP_NEWDEL, "del pTA1 = %X\n", pTA1);
  335. delete pTA1;
  336. pTA1 = pTA2;
  337. }
  338. // Delete allocated memory for sequence of alias addresses
  339. pAA1 = m_pRgstrtnRqst_trmnlAls;
  340. while (pAA1 != 0)
  341. {
  342. pAA2 = pAA1->next;
  343. if (pAA1->value.choice == h323_ID_chosen)
  344. {
  345. SPIDER_TRACE(SP_NEWDEL, "del pAA1->value.u.h323_ID.value = %X\n", pAA1->value.u.h323_ID.value);
  346. delete pAA1->value.u.h323_ID.value;
  347. }
  348. SPIDER_TRACE(SP_NEWDEL, "del pAA1 = %X\n", pAA1);
  349. delete pAA1;
  350. pAA1 = pAA2;
  351. }
  352. // Delete allocated memory for sequence of location alias addresses
  353. pAA1 = m_pLocationInfo;
  354. while (pAA1 != 0)
  355. {
  356. pAA2 = pAA1->next;
  357. if (pAA1->value.choice == h323_ID_chosen)
  358. {
  359. SPIDER_TRACE(SP_NEWDEL, "del pAA1->value.u.h323_ID.value = %X\n", pAA1->value.u.h323_ID.value);
  360. delete pAA1->value.u.h323_ID.value;
  361. }
  362. SPIDER_TRACE(SP_NEWDEL, "del pAA1 = %X\n", pAA1);
  363. delete pAA1;
  364. pAA1 = pAA2;
  365. }
  366. // Delete allocated memory for identifiers
  367. if (m_RCm_gtkprIdntfr.length)
  368. {
  369. SPIDER_TRACE(SP_NEWDEL, "del m_RCm_gtkprIdntfr.value = %X\n", m_RCm_gtkprIdntfr.value);
  370. delete m_RCm_gtkprIdntfr.value;
  371. }
  372. if (m_endpointID.length)
  373. {
  374. SPIDER_TRACE(SP_NEWDEL, "del m_endpointID.value = %X\n", m_endpointID.value);
  375. delete m_endpointID.value;
  376. }
  377. // Delete allocated memory for sequence of RAS addresses
  378. pTA1 = m_pRASAddress;
  379. while (pTA1 != 0)
  380. {
  381. pTA2 = pTA1->next;
  382. SPIDER_TRACE(SP_NEWDEL, "del pTA1 = %X\n", pTA1);
  383. delete pTA1;
  384. pTA1 = pTA2;
  385. }
  386. if (!m_Calls.IsEmpty())
  387. {
  388. // Free up any call objects
  389. // on this registration object
  390. POS pos;
  391. for( pos = m_Calls.GetFirstPos(); pos != NULL; )
  392. {
  393. // Delete the call object
  394. CCall *pCall = m_Calls.GetNext(pos);
  395. SPIDER_TRACE(SP_NEWDEL, "del pCall = %X\n", pCall);
  396. delete pCall;
  397. }
  398. // Now remove all pointers from the list
  399. m_Calls.RemoveAll();
  400. }
  401. // Delete memory for last RAS message if still allocated
  402. if (m_pRasMessage)
  403. {
  404. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  405. delete m_pRasMessage;
  406. }
  407. // if (m_dwLockingThread)
  408. // Unlock();
  409. // DeleteCriticalSection(&m_CriticalSection);
  410. #if(0)
  411. if(m_hRetrySemaphore)
  412. {
  413. CloseHandle(m_hRetrySemaphore);
  414. m_hRetrySemaphore = NULL;
  415. }
  416. #endif
  417. m_pSocket->Close();
  418. LockSocket();
  419. // Close the socket and delete the socket object
  420. SPIDER_TRACE(SP_NEWDEL, "del m_pSocket = %X\n", m_pSocket);
  421. delete m_pSocket;
  422. UnlockSocket();
  423. DeleteCriticalSection(&m_SocketCRS);
  424. }
  425. UINT_PTR CRegistration::StartRetryTimer(void)
  426. {
  427. if(m_uTimer)
  428. {
  429. KillTimer(m_hWnd, m_uTimer);
  430. m_uTimer = 0;
  431. }
  432. m_uRetryResetCount = GKR_RETRY_INTERVAL_SECONDS * (1000/GKR_RETRY_TICK_MS);
  433. m_uRetryCountdown = GKR_RETRY_INTERVAL_SECONDS;
  434. m_uMaxRetryCount = GKR_RETRY_MAX;
  435. m_usRetryCount = 0;
  436. m_uTimer = SetTimer(NULL, NULL, GKR_RETRY_TICK_MS, RetryTimerProc);
  437. //m_uTimer = SetTimer(hWnd, GKREG_TIMER_ID, GKR_RETRY_TICK_MS, RetryTimerProc);
  438. return m_uTimer;
  439. }
  440. HRESULT
  441. CRegistration::AddVendorInfo(PCC_VENDORINFO pVendorInfo)
  442. {
  443. HRESULT hr = GKI_OK;
  444. if(m_pVendorInfo)
  445. {
  446. FreeVendorInfo(m_pVendorInfo);
  447. m_pVendorInfo = NULL;
  448. }
  449. if(pVendorInfo)
  450. {
  451. hr = CopyVendorInfo(&m_pVendorInfo, pVendorInfo);
  452. if(hr != CC_OK)
  453. {
  454. m_pVendorInfo = NULL;
  455. }
  456. }
  457. return hr;
  458. }
  459. HRESULT
  460. CRegistration::AddCallSignalAddr(TransportAddress& rvalue)
  461. {
  462. // ABSTRACT: This procedure is called to add a call signal address
  463. // to the link list of call signal addresses. This will
  464. // be called for each transport on receiving a GKI_RegistrationRequest.
  465. // A local copy is made to avoid reliance on the client
  466. // keeping the memory valid. This procedure returns 0 if
  467. // successful and non-zero for a failure.
  468. // AUTHOR: Colin Hulme
  469. SeqTransportAddr *pCSA;
  470. #ifdef _DEBUG
  471. char szGKDebug[80];
  472. #endif
  473. SPIDER_TRACE(SP_FUNC, "CRegistration::AddCallSignalAddr(%X)\n", rvalue.choice);
  474. if (m_pCallSignalAddress == 0) // First one in the list
  475. {
  476. m_pCallSignalAddress = new SeqTransportAddr;
  477. SPIDER_TRACE(SP_NEWDEL, "new m_pCallSignalAddress = %X\n", m_pCallSignalAddress);
  478. if (m_pCallSignalAddress == 0)
  479. return (GKI_NO_MEMORY);
  480. memset(m_pCallSignalAddress, 0, sizeof(SeqTransportAddr));
  481. pCSA = m_pCallSignalAddress;
  482. }
  483. else
  484. {
  485. for (pCSA = m_pCallSignalAddress; pCSA->next != 0; pCSA = pCSA->next)
  486. ; // walk the list til last entry
  487. pCSA->next = new SeqTransportAddr;
  488. SPIDER_TRACE(SP_NEWDEL, "new pCSA->next = %X\n", pCSA->next);
  489. if (pCSA->next == 0)
  490. return (GKI_NO_MEMORY);
  491. memset(pCSA->next, 0, sizeof(SeqTransportAddr));
  492. pCSA = pCSA->next;
  493. }
  494. pCSA->next = 0; // initialize new structure fields
  495. pCSA->value = rvalue;
  496. return (GKI_OK);
  497. }
  498. HRESULT
  499. CRegistration::AddRASAddr(TransportAddress& rvalue, unsigned short usPort)
  500. {
  501. // ABSTRACT: This procedure is called to add a RAS address
  502. // to the link list of RAS addresses. This will
  503. // be called only for the transport used for the registration
  504. // request. This procedure returns 0 if successful and non-zero
  505. // for a failure.
  506. // AUTHOR: Colin Hulme
  507. #ifdef _DEBUG
  508. char szGKDebug[80];
  509. #endif
  510. SPIDER_TRACE(SP_FUNC, "CRegistration::AddRASAddr(%X, usPort)\n", rvalue.choice);
  511. m_pRASAddress = new SeqTransportAddr;
  512. SPIDER_TRACE(SP_NEWDEL, "new m_pRASAddress = %X\n", m_pRASAddress);
  513. if (m_pRASAddress == 0)
  514. return (GKI_NO_MEMORY);
  515. memset(m_pRASAddress, 0, sizeof(SeqTransportAddr));
  516. m_pRASAddress->next = 0; // initialize new structure fields
  517. m_pRASAddress->value = rvalue;
  518. // Add actual RAS port to RAS address
  519. switch (m_pRASAddress->value.choice)
  520. {
  521. case ipAddress_chosen:
  522. m_pRASAddress->value.u.ipAddress.port = usPort;
  523. break;
  524. case ipxAddress_chosen:
  525. m_pRASAddress->value.u.ipxAddress.port.value[0] = HIBYTE(usPort);
  526. m_pRASAddress->value.u.ipxAddress.port.value[1] = LOBYTE(usPort);
  527. break;
  528. }
  529. return (GKI_OK);
  530. }
  531. HRESULT
  532. CRegistration::AddAliasAddr(AliasAddress& rvalue)
  533. {
  534. // ABSTRACT: This procedure is called to add an alias address
  535. // to the link list of alias addresses. This will
  536. // be called for each alias on receiving a GKI_RegistrationRequest.
  537. // A local copy is made to avoid reliance on the client
  538. // keeping the memory valid.
  539. // In the eventuality that the gatekeeper assigns alias
  540. // addresses, this procedure will be called for each alias
  541. // contained in the registrationConfirm message.
  542. // This procedure returns 0 if successful and non-zero
  543. // for a failure.
  544. // AUTHOR: Colin Hulme
  545. SeqAliasAddr *p1;
  546. unsigned short uIdx;
  547. unsigned short *pus;
  548. #ifdef _DEBUG
  549. char szGKDebug[80];
  550. #endif
  551. SPIDER_TRACE(SP_FUNC, "CRegistration::AddAliasAddr(%X)\n", rvalue.choice);
  552. if (m_pRgstrtnRqst_trmnlAls == 0) // First one in the list
  553. {
  554. m_pRgstrtnRqst_trmnlAls = new SeqAliasAddr;
  555. SPIDER_TRACE(SP_NEWDEL, "new m_pRgstrtnRqst_trmnlAls = %X\n", m_pRgstrtnRqst_trmnlAls);
  556. if (m_pRgstrtnRqst_trmnlAls == 0)
  557. return (GKI_NO_MEMORY);
  558. memset(m_pRgstrtnRqst_trmnlAls, 0, sizeof(SeqAliasAddr));
  559. p1 = m_pRgstrtnRqst_trmnlAls;
  560. }
  561. else
  562. {
  563. for (p1 = m_pRgstrtnRqst_trmnlAls; p1->next != 0; p1 = p1->next)
  564. ; // walk the list til last entry
  565. p1->next = new SeqAliasAddr;
  566. SPIDER_TRACE(SP_NEWDEL, "new p1->next = %X\n", p1->next);
  567. if (p1->next == 0)
  568. return (GKI_NO_MEMORY);
  569. memset(p1->next, 0, sizeof(SeqAliasAddr));
  570. p1 = p1->next;
  571. }
  572. p1->next = 0; // initialize new structure fields
  573. p1->value = rvalue;
  574. if (p1->value.choice == h323_ID_chosen)
  575. {
  576. pus = new unsigned short[p1->value.u.h323_ID.length];
  577. SPIDER_TRACE(SP_NEWDEL, "new pus = %X\n", pus);
  578. if (pus == 0)
  579. return (GKI_NO_MEMORY);
  580. memset(pus, 0, sizeof(unsigned short) * p1->value.u.h323_ID.length);
  581. for (uIdx = 0; uIdx < p1->value.u.h323_ID.length; uIdx++)
  582. *(pus + uIdx) = *(p1->value.u.h323_ID.value + uIdx);
  583. p1->value.u.h323_ID.value = pus;
  584. }
  585. return (GKI_OK);
  586. }
  587. HRESULT
  588. CRegistration::AddLocationInfo(AliasAddress& rvalue)
  589. {
  590. // ABSTRACT: This procedure is called to add an alias address
  591. // to the link list of alias addresses. This will
  592. // be called for each alias on receiving a GKI_RegistrationRequest.
  593. // A local copy is made to avoid reliance on the client
  594. // keeping the memory valid.
  595. // In the eventuality that the gatekeeper assigns alias
  596. // addresses, this procedure will be called for each alias
  597. // contained in the registrationConfirm message.
  598. // This procedure returns 0 if successful and non-zero
  599. // for a failure.
  600. // AUTHOR: Colin Hulme
  601. SeqAliasAddr *p1;
  602. unsigned short uIdx;
  603. unsigned short *pus;
  604. #ifdef _DEBUG
  605. char szGKDebug[80];
  606. #endif
  607. SPIDER_TRACE(SP_FUNC, "CRegistration::AddLocationInfo(%X)\n", rvalue.choice);
  608. if (m_pLocationInfo == 0) // First one in the list
  609. {
  610. m_pLocationInfo = new SeqAliasAddr;
  611. SPIDER_TRACE(SP_NEWDEL, "new m_pLocationInfo = %X\n", m_pLocationInfo);
  612. if (m_pLocationInfo == 0)
  613. return (GKI_NO_MEMORY);
  614. memset(m_pLocationInfo, 0, sizeof(SeqAliasAddr));
  615. p1 = m_pLocationInfo;
  616. }
  617. else
  618. {
  619. for (p1 = m_pLocationInfo; p1->next != 0; p1 = p1->next)
  620. ; // walk the list til last entry
  621. p1->next = new SeqAliasAddr;
  622. SPIDER_TRACE(SP_NEWDEL, "new p1->next = %X\n", p1->next);
  623. if (p1->next == 0)
  624. return (GKI_NO_MEMORY);
  625. memset(p1->next, 0, sizeof(SeqAliasAddr));
  626. p1 = p1->next;
  627. }
  628. p1->next = 0; // initialize new structure fields
  629. p1->value = rvalue;
  630. if (p1->value.choice == h323_ID_chosen)
  631. {
  632. pus = new unsigned short[p1->value.u.h323_ID.length];
  633. SPIDER_TRACE(SP_NEWDEL, "new pus = %X\n", pus);
  634. if (pus == 0)
  635. return (GKI_NO_MEMORY);
  636. memset(pus, 0, sizeof(unsigned short) * p1->value.u.h323_ID.length);
  637. for (uIdx = 0; uIdx < p1->value.u.h323_ID.length; uIdx++)
  638. *(pus + uIdx) = *(p1->value.u.h323_ID.value + uIdx);
  639. p1->value.u.h323_ID.value = pus;
  640. }
  641. return (GKI_OK);
  642. }
  643. TransportAddress *
  644. CRegistration::GetTransportAddress(unsigned short usCallTransport)
  645. {
  646. SeqTransportAddr *pCSA;
  647. for (pCSA = m_pCallSignalAddress; pCSA != 0; pCSA = pCSA->next)
  648. {
  649. if (pCSA->value.choice == usCallTransport)
  650. return (&pCSA->value);
  651. }
  652. return (NULL); // Didn't find it
  653. }
  654. HRESULT
  655. CRegistration::RegistrationRequest(BOOL fDiscovery)
  656. {
  657. // ABSTRACT: This procedure will create a RegistrationRequest structure
  658. // call the encoder and send the PDU. If it is successful, it
  659. // will return 0, else it will return an error code. Note: The
  660. // memory allocated for the RAS Message is not freed until either
  661. // a response from the gatekeeper or it times out. This allows
  662. // for retransmission without having to rebuild this message.
  663. // AUTHOR: Colin Hulme
  664. ASN1_BUF Asn1Buf;
  665. DWORD dwErrorCode;
  666. #ifdef _DEBUG
  667. char szGKDebug[80];
  668. #endif
  669. SPIDER_TRACE(SP_FUNC, "CRegistration::RegistrationRequest()\n", 0);
  670. ASSERT(g_pCoder);
  671. if (g_pCoder == NULL)
  672. return (GKI_NOT_INITIALIZED);
  673. // Allocate a RasMessage structure and initialized to 0
  674. m_usRetryCount = 0;
  675. m_uRetryCountdown = m_uRetryResetCount;
  676. m_pRasMessage = new RasMessage;
  677. SPIDER_TRACE(SP_NEWDEL, "new m_pRasMessage = %X\n", m_pRasMessage);
  678. if (m_pRasMessage == 0)
  679. return (GKI_NO_MEMORY);
  680. memset(m_pRasMessage, 0, sizeof(RasMessage));
  681. // Setup structure fields for RegistrationRequest
  682. m_pRasMessage->choice = registrationRequest_chosen;
  683. if (m_pRgstrtnRqst_trmnlAls != 0)
  684. m_pRasMessage->u.registrationRequest.bit_mask |= RgstrtnRqst_trmnlAls_present;
  685. if (m_RCm_gtkprIdntfr.length != 0)
  686. m_pRasMessage->u.registrationRequest.bit_mask |= RgstrtnRqst_gtkprIdntfr_present;
  687. m_pRasMessage->u.registrationRequest.requestSeqNum = ++m_requestSeqNum;
  688. // discoveryComplete is a ASN1_BOOL (char) and fDiscovery is a BOOL (int) so the
  689. // cast was added to remove a compiler warning. Since the value of fDiscovery
  690. // is always 0 or 1, no loss occurs in the cast. -- DLD
  691. m_pRasMessage->u.registrationRequest.discoveryComplete = (ASN1_BOOL)fDiscovery;
  692. m_pRasMessage->u.registrationRequest.callSignalAddress = (PRegistrationRequest_callSignalAddress)m_pCallSignalAddress;
  693. m_pRasMessage->u.registrationRequest.rasAddress = (PRegistrationRequest_rasAddress)m_pRASAddress;
  694. m_pRasMessage->u.registrationRequest.terminalType = m_terminalType;
  695. m_pRasMessage->u.registrationRequest.RgstrtnRqst_trmnlAls = (PRegistrationRequest_terminalAlias)m_pRgstrtnRqst_trmnlAls;
  696. m_pRasMessage->u.registrationRequest.RgstrtnRqst_gtkprIdntfr = m_RCm_gtkprIdntfr;
  697. m_pRasMessage->u.registrationRequest.endpointVendor.bit_mask = 0;
  698. if(m_pVendorInfo)
  699. {
  700. m_pRasMessage->u.registrationRequest.endpointVendor.vendor.t35CountryCode
  701. = m_pVendorInfo->bCountryCode;
  702. m_pRasMessage->u.registrationRequest.endpointVendor.vendor.t35Extension
  703. = m_pVendorInfo->bExtension;
  704. m_pRasMessage->u.registrationRequest.endpointVendor.vendor.manufacturerCode
  705. = m_pVendorInfo->wManufacturerCode;
  706. if(m_pVendorInfo->pProductNumber
  707. && m_pVendorInfo->pProductNumber->pOctetString
  708. && m_pVendorInfo->pProductNumber->wOctetStringLength)
  709. {
  710. UINT uSize = min(m_pVendorInfo->pProductNumber->wOctetStringLength,
  711. sizeof(m_pRasMessage->u.registrationRequest.endpointVendor.productId.value));
  712. m_pRasMessage->u.registrationRequest.endpointVendor.bit_mask |= productId_present;
  713. // truncate to fit size of registrationRequest.endpointVendor.productId.value
  714. m_pRasMessage->u.registrationRequest.endpointVendor.productId.length = uSize;
  715. memcpy(&m_pRasMessage->u.registrationRequest.endpointVendor.productId.value,
  716. m_pVendorInfo->pProductNumber->pOctetString, uSize);
  717. }
  718. if(m_pVendorInfo->pVersionNumber
  719. && m_pVendorInfo->pVersionNumber->pOctetString
  720. && m_pVendorInfo->pVersionNumber->wOctetStringLength)
  721. {
  722. UINT uSize = min(m_pVendorInfo->pVersionNumber->wOctetStringLength,
  723. sizeof(m_pRasMessage->u.registrationRequest.endpointVendor.versionId.value));
  724. m_pRasMessage->u.registrationRequest.endpointVendor.bit_mask |= versionId_present;
  725. // truncate to fit size of registrationRequest.endpointVendor.versionId.value
  726. m_pRasMessage->u.registrationRequest.endpointVendor.versionId.length = uSize;
  727. memcpy(&m_pRasMessage->u.registrationRequest.endpointVendor.versionId.value,
  728. m_pVendorInfo->pVersionNumber->pOctetString, uSize);
  729. }
  730. }
  731. #ifdef _DEBUG
  732. if (dwGKIDLLFlags & SP_DUMPMEM)
  733. DumpMem(m_pRasMessage, sizeof(RasMessage));
  734. #endif
  735. // Assign ProtocolIdentifier
  736. g_pCoder->SetProtocolIdentifier(*m_pRasMessage);
  737. // Encode the PDU & send it
  738. dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf);
  739. if (dwErrorCode)
  740. return (GKI_ENCODER_ERROR);
  741. // Create a backup copy of the encoded PDU if using debug echo support
  742. if (fGKIEcho)
  743. {
  744. pEchoBuff = new char[Asn1Buf.length];
  745. SPIDER_TRACE(SP_NEWDEL, "new pEchoBuff = %X\n", pEchoBuff);
  746. if (pEchoBuff == 0)
  747. return (GKI_NO_MEMORY);
  748. memcpy(pEchoBuff, (char *)Asn1Buf.value, Asn1Buf.length);
  749. nEchoLen = Asn1Buf.length;
  750. }
  751. SPIDER_TRACE(SP_PDU, "Send RRQ; g_pReg = %X\n", this);
  752. if (fGKIDontSend == FALSE)
  753. if (m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  754. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  755. // Free the encoder memory
  756. g_pCoder->Free(Asn1Buf);
  757. return (GKI_OK);
  758. }
  759. HRESULT
  760. CRegistration::UnregistrationRequest(void)
  761. {
  762. // ABSTRACT: This procedure will create an UnregistrationRequest structure
  763. // call the encoder and send the PDU. If it is successful, it
  764. // will return 0, else it will return an error code.
  765. // AUTHOR: Colin Hulme
  766. ASN1_BUF Asn1Buf;
  767. DWORD dwErrorCode;
  768. #ifdef _DEBUG
  769. char szGKDebug[80];
  770. #endif
  771. SPIDER_TRACE(SP_FUNC, "CRegistration::UnregistrationRequest()\n", 0);
  772. ASSERT(g_pCoder);
  773. if (g_pCoder == NULL)
  774. return (GKI_NOT_INITIALIZED);
  775. // Allocate a RasMessage structure and initialized to 0
  776. m_usRetryCount = 0;
  777. m_uRetryCountdown = m_uRetryResetCount;
  778. m_pRasMessage = new RasMessage;
  779. SPIDER_TRACE(SP_NEWDEL, "new m_pRasMessage = %X\n", m_pRasMessage);
  780. if (m_pRasMessage == 0)
  781. return (GKI_NO_MEMORY);
  782. memset(m_pRasMessage, 0, sizeof(RasMessage));
  783. // Setup structure fields for UnregistrationRequest
  784. m_pRasMessage->choice = unregistrationRequest_chosen;
  785. if (m_pRgstrtnRqst_trmnlAls != 0)
  786. m_pRasMessage->u.unregistrationRequest.bit_mask |= UnrgstrtnRqst_endpntAls_present;
  787. if (m_endpointID.length != 0)
  788. m_pRasMessage->u.unregistrationRequest.bit_mask |= URt_endpntIdntfr_present;
  789. m_pRasMessage->u.unregistrationRequest.requestSeqNum = ++m_requestSeqNum;
  790. m_pRasMessage->u.unregistrationRequest.callSignalAddress = (PUnregistrationRequest_callSignalAddress)m_pCallSignalAddress;
  791. m_pRasMessage->u.unregistrationRequest.UnrgstrtnRqst_endpntAls = (PUnregistrationRequest_endpointAlias)m_pRgstrtnRqst_trmnlAls;
  792. m_pRasMessage->u.unregistrationRequest.URt_endpntIdntfr = m_endpointID;
  793. #ifdef _DEBUG
  794. if (dwGKIDLLFlags & SP_DUMPMEM)
  795. DumpMem(m_pRasMessage, sizeof(RasMessage));
  796. #endif
  797. // Encode the PDU & send it
  798. dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf);
  799. if (dwErrorCode)
  800. return (GKI_ENCODER_ERROR);
  801. // Create a backup copy of the encoded PDU if using debug echo support
  802. if (fGKIEcho)
  803. {
  804. pEchoBuff = new char[Asn1Buf.length];
  805. SPIDER_TRACE(SP_NEWDEL, "new pEchoBuff = %X\n", pEchoBuff);
  806. if (pEchoBuff == 0)
  807. return (GKI_NO_MEMORY);
  808. memcpy(pEchoBuff, (char *)Asn1Buf.value, Asn1Buf.length);
  809. nEchoLen = Asn1Buf.length;
  810. }
  811. m_State = GK_UNREG_PENDING;
  812. SPIDER_TRACE(SP_STATE, "m_State = GK_UNREG_PENDING (%X)\n", this);
  813. SPIDER_TRACE(SP_PDU, "Send URQ; g_pReg = %X\n", this);
  814. if (fGKIDontSend == FALSE)
  815. if (m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  816. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  817. // Free the encoder memory
  818. g_pCoder->Free(Asn1Buf);
  819. return (GKI_OK);
  820. }
  821. HRESULT
  822. CRegistration::LocationRequest(void)
  823. {
  824. // ABSTRACT: This procedure will create a LocationRequest structure
  825. // call the encoder and send the PDU. If it is successful, it
  826. // will return 0, else it will return an error code. Note: The
  827. // memory allocated for the RAS Message is not freed until either
  828. // a response from the gatekeeper or it times out. This allows
  829. // for retransmission without having to rebuild this message.
  830. // AUTHOR: Colin Hulme
  831. ASN1_BUF Asn1Buf;
  832. DWORD dwErrorCode;
  833. #ifdef _DEBUG
  834. char szGKDebug[80];
  835. #endif
  836. SPIDER_TRACE(SP_FUNC, "CRegistration::LocationRequest()\n", 0);
  837. ASSERT(g_pCoder);
  838. if (g_pCoder == NULL)
  839. return (GKI_NOT_INITIALIZED);
  840. // Allocate a RasMessage structure and initialized to 0
  841. m_usRetryCount = 0;
  842. m_uRetryCountdown = m_uRetryResetCount;
  843. m_pRasMessage = new RasMessage;
  844. SPIDER_TRACE(SP_NEWDEL, "new m_pRasMessage = %X\n", m_pRasMessage);
  845. if (m_pRasMessage == 0)
  846. return (GKI_NO_MEMORY);
  847. memset(m_pRasMessage, 0, sizeof(RasMessage));
  848. // Setup structure fields for LocationRequest
  849. m_pRasMessage->choice = locationRequest_chosen;
  850. if (m_endpointID.length != 0)
  851. m_pRasMessage->u.locationRequest.bit_mask |= LctnRqst_endpntIdntfr_present;
  852. m_pRasMessage->u.locationRequest.requestSeqNum = ++m_requestSeqNum;
  853. m_pRasMessage->u.locationRequest.LctnRqst_endpntIdntfr = m_endpointID;
  854. m_pRasMessage->u.locationRequest.destinationInfo =
  855. (PLocationRequest_destinationInfo)m_pLocationInfo;
  856. m_pRasMessage->u.locationRequest.replyAddress = m_pRASAddress->value;
  857. #ifdef _DEBUG
  858. if (dwGKIDLLFlags & SP_DUMPMEM)
  859. DumpMem(m_pRasMessage, sizeof(RasMessage));
  860. #endif
  861. // Encode the PDU & send it
  862. dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf);
  863. if (dwErrorCode)
  864. return (GKI_ENCODER_ERROR);
  865. // Create a backup copy of the encoded PDU if using debug echo support
  866. if (fGKIEcho)
  867. {
  868. pEchoBuff = new char[Asn1Buf.length];
  869. SPIDER_TRACE(SP_NEWDEL, "new pEchoBuff = %X\n", pEchoBuff);
  870. if (pEchoBuff == 0)
  871. return (GKI_NO_MEMORY);
  872. memcpy(pEchoBuff, (char *)Asn1Buf.value, Asn1Buf.length);
  873. nEchoLen = Asn1Buf.length;
  874. }
  875. m_State = GK_LOC_PENDING;
  876. SPIDER_TRACE(SP_STATE, "m_State = GK_LOC_PENDING (%X)\n", this);
  877. SPIDER_TRACE(SP_PDU, "Send LRQ; g_pReg = %X\n", this);
  878. if (fGKIDontSend == FALSE)
  879. if (m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  880. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  881. // Free the encoder memory
  882. g_pCoder->Free(Asn1Buf);
  883. return (GKI_OK);
  884. }
  885. HRESULT
  886. CRegistration::GatekeeperRequest(void)
  887. {
  888. // ABSTRACT: This procedure will create a GatekeeperRequest structure
  889. // call the encoder and send the PDU. If it is successful, it
  890. // will return 0, else it will return an error code.
  891. // AUTHOR: Colin Hulme
  892. ASN1_BUF Asn1Buf;
  893. DWORD dwErrorCode;
  894. #ifdef _DEBUG
  895. char szGKDebug[80];
  896. #endif
  897. SPIDER_TRACE(SP_FUNC, "CRegistration::GatekeeperRequest()\n", 0);
  898. ASSERT(g_pCoder);
  899. if (g_pCoder == NULL)
  900. return (GKI_NOT_INITIALIZED);
  901. // Allocate a RasMessage structure and initialized to 0
  902. m_usRetryCount = 0;
  903. m_uRetryCountdown = m_uRetryResetCount;
  904. m_pRasMessage = new RasMessage;
  905. SPIDER_TRACE(SP_NEWDEL, "new m_pRasMessage = %X\n", m_pRasMessage);
  906. if (m_pRasMessage == 0)
  907. return (GKI_NO_MEMORY);
  908. memset(m_pRasMessage, 0, sizeof(RasMessage));
  909. // Setup structure fields for GatekeeperRequest
  910. m_pRasMessage->choice = gatekeeperRequest_chosen;
  911. if (m_pRgstrtnRqst_trmnlAls != 0)
  912. m_pRasMessage->u.gatekeeperRequest.bit_mask |= GtkprRqst_endpointAlias_present;
  913. m_pRasMessage->u.gatekeeperRequest.requestSeqNum = ++m_requestSeqNum;
  914. m_pRasMessage->u.gatekeeperRequest.rasAddress = m_pRASAddress->value;
  915. m_pRasMessage->u.gatekeeperRequest.endpointType = m_terminalType;
  916. m_pRasMessage->u.gatekeeperRequest.GtkprRqst_endpointAlias = (PGatekeeperRequest_endpointAlias)m_pRgstrtnRqst_trmnlAls;
  917. // Assign ProtocolIdentifier
  918. g_pCoder->SetProtocolIdentifier(*m_pRasMessage);
  919. // Encode the PDU & send it
  920. dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf);
  921. if (dwErrorCode)
  922. return (GKI_ENCODER_ERROR);
  923. // Create a backup copy of the encoded PDU if using debug echo support
  924. if (fGKIEcho)
  925. {
  926. pEchoBuff = new char[Asn1Buf.length];
  927. SPIDER_TRACE(SP_NEWDEL, "new pEchoBuff = %X\n", pEchoBuff);
  928. if (pEchoBuff == 0)
  929. return (GKI_NO_MEMORY);
  930. memcpy(pEchoBuff, (char *)Asn1Buf.value, Asn1Buf.length);
  931. nEchoLen = Asn1Buf.length;
  932. }
  933. SPIDER_TRACE(SP_PDU, "Send GRQ; g_pReg = %X\n", this);
  934. if (fGKIDontSend == FALSE)
  935. {
  936. if (m_pSocket->SendBroadcast((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  937. {
  938. g_pCoder->Free(Asn1Buf);
  939. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  940. }
  941. }
  942. // Free the encoder memory
  943. g_pCoder->Free(Asn1Buf);
  944. return (GKI_OK);
  945. }
  946. HRESULT
  947. CRegistration::PDUHandler(RasMessage *pRasMessage)
  948. {
  949. // ABSTRACT: This procedure will interpret the received PDU and dispatch
  950. // to the appropriate handler.
  951. // AUTHOR: Colin Hulme
  952. #ifdef _DEBUG
  953. char szGKDebug[80];
  954. #endif
  955. HRESULT hResult = GKI_OK;
  956. SPIDER_TRACE(SP_FUNC, "CRegistration::PDUHandler(%X)\n", pRasMessage);
  957. ASSERT(g_pCoder);
  958. if (g_pCoder == NULL)
  959. return (GKI_NOT_INITIALIZED);
  960. switch (pRasMessage->choice)
  961. {
  962. // Incoming response PDUs
  963. case gatekeeperConfirm_chosen:
  964. SPIDER_TRACE(SP_PDU, "Rcv GCF; g_pReg = %X\n", this);
  965. break;
  966. case gatekeeperReject_chosen:
  967. SPIDER_TRACE(SP_PDU, "Rcv GRJ; g_pReg = %X\n", this);
  968. break;
  969. case registrationConfirm_chosen:
  970. SPIDER_TRACE(SP_PDU, "Rcv RCF; g_pReg = %X\n", this);
  971. if ((m_State == GK_REG_PENDING) &&
  972. (pRasMessage->u.registrationConfirm.requestSeqNum ==
  973. m_pRasMessage->u.registrationRequest.requestSeqNum))
  974. hResult = RegistrationConfirm(pRasMessage);
  975. else
  976. hResult = UnknownMessage(pRasMessage);
  977. break;
  978. case registrationReject_chosen:
  979. SPIDER_TRACE(SP_PDU, "Rcv RRJ; g_pReg = %X\n", this);
  980. if ((m_State == GK_REG_PENDING) &&
  981. (pRasMessage->u.registrationReject.requestSeqNum ==
  982. m_pRasMessage->u.registrationRequest.requestSeqNum))
  983. hResult = RegistrationReject(pRasMessage);
  984. else
  985. hResult = UnknownMessage(pRasMessage);
  986. break;
  987. case unregistrationConfirm_chosen:
  988. SPIDER_TRACE(SP_PDU, "Rcv UCF; g_pReg = %X\n", this);
  989. if ((m_State == GK_UNREG_PENDING) &&
  990. (pRasMessage->u.unregistrationConfirm.requestSeqNum ==
  991. m_pRasMessage->u.unregistrationRequest.requestSeqNum))
  992. hResult = UnregistrationConfirm(pRasMessage);
  993. else
  994. hResult = UnknownMessage(pRasMessage);
  995. break;
  996. case unregistrationReject_chosen:
  997. SPIDER_TRACE(SP_PDU, "Rcv URJ; g_pReg = %X\n", this);
  998. if ((m_State == GK_UNREG_PENDING) &&
  999. (pRasMessage->u.unregistrationReject.requestSeqNum ==
  1000. m_pRasMessage->u.unregistrationRequest.requestSeqNum))
  1001. hResult = UnregistrationReject(pRasMessage);
  1002. else
  1003. hResult = UnknownMessage(pRasMessage);
  1004. break;
  1005. case admissionConfirm_chosen:
  1006. {
  1007. // The sequence number of this RAS message seems to be the
  1008. // only thing we can link back to the ARQ so we use it
  1009. // to look up the call that this ACF is associated with
  1010. RequestSeqNum seqNum = pRasMessage->u.admissionConfirm.requestSeqNum;
  1011. CCall *pCall = FindCallBySeqNum(seqNum);
  1012. if ((m_State == GK_REGISTERED) && (pCall))
  1013. {
  1014. SPIDER_TRACE(SP_PDU, "Rcv ACF; pCall = %X\n", pCall);
  1015. hResult = pCall->AdmissionConfirm(pRasMessage);
  1016. }
  1017. else
  1018. {
  1019. SPIDER_TRACE(SP_PDU, "Rcv ACF; g_pReg = %X\n", this);
  1020. hResult = UnknownMessage(pRasMessage);
  1021. }
  1022. }
  1023. break;
  1024. case admissionReject_chosen:
  1025. {
  1026. // The sequence number of this RAS message seems to be the
  1027. // only thing we can link back to the ARQ so we use it
  1028. // to look up the call that this ARJ is associated with
  1029. RequestSeqNum seqNum = pRasMessage->u.admissionReject.requestSeqNum;
  1030. CCall *pCall = FindCallBySeqNum(seqNum);
  1031. if ((m_State == GK_REGISTERED) && (pCall))
  1032. {
  1033. SPIDER_TRACE(SP_PDU, "Rcv ARJ; pCall = %X\n", pCall);
  1034. hResult = pCall->AdmissionReject(pRasMessage);
  1035. if (hResult == GKI_DELETE_CALL)
  1036. {
  1037. DeleteCall(pCall);
  1038. hResult = GKI_OK; // Don't want to exit PostReceive loop
  1039. }
  1040. }
  1041. else
  1042. {
  1043. SPIDER_TRACE(SP_PDU, "Rcv ARJ; g_pReg = %X\n", this);
  1044. hResult = UnknownMessage(pRasMessage);
  1045. }
  1046. }
  1047. break;
  1048. case bandwidthConfirm_chosen:
  1049. {
  1050. // The sequence number of this RAS message seems to be the
  1051. // only thing we can link back to the BRQ so we use it
  1052. // to look up the call that this BCF is associated with
  1053. RequestSeqNum seqNum = pRasMessage->u.bandwidthConfirm.requestSeqNum;
  1054. CCall *pCall = FindCallBySeqNum(seqNum);
  1055. if ((m_State == GK_REGISTERED) && (pCall))
  1056. {
  1057. SPIDER_TRACE(SP_PDU, "Rcv BCF; pCall = %X\n", pCall);
  1058. hResult = pCall->BandwidthConfirm(pRasMessage);
  1059. }
  1060. else
  1061. {
  1062. SPIDER_TRACE(SP_PDU, "Rcv BCF; g_pReg = %X\n", this);
  1063. hResult = UnknownMessage(pRasMessage);
  1064. }
  1065. }
  1066. break;
  1067. case bandwidthReject_chosen:
  1068. {
  1069. // The sequence number of this RAS message seems to be the
  1070. // only thing we can link back to the BRQ so we use it
  1071. // to look up the call that this BCF is associated with
  1072. RequestSeqNum seqNum = pRasMessage->u.bandwidthReject.requestSeqNum;
  1073. CCall *pCall = FindCallBySeqNum(seqNum);
  1074. if ((m_State == GK_REGISTERED) && (pCall))
  1075. {
  1076. SPIDER_TRACE(SP_PDU, "Rcv BRJ; pCall = %X\n", pCall);
  1077. hResult = pCall->BandwidthReject(pRasMessage);
  1078. }
  1079. else
  1080. {
  1081. SPIDER_TRACE(SP_PDU, "Rcv BRJ; g_pReg = %X\n", this);
  1082. hResult = UnknownMessage(pRasMessage);
  1083. }
  1084. }
  1085. break;
  1086. case disengageConfirm_chosen:
  1087. {
  1088. // The sequence number of this RAS message seems to be the
  1089. // only thing we can link back to the DRQ so we use it
  1090. // to look up the call that this DCF is associated with
  1091. RequestSeqNum seqNum = pRasMessage->u.disengageConfirm.requestSeqNum;
  1092. CCall *pCall = FindCallBySeqNum(seqNum);
  1093. if ((m_State == GK_REGISTERED) && (pCall))
  1094. {
  1095. SPIDER_TRACE(SP_PDU, "Rcv DCF; pCall = %X\n", pCall);
  1096. hResult = pCall->DisengageConfirm(pRasMessage);
  1097. if (hResult == GKI_DELETE_CALL)
  1098. {
  1099. DeleteCall(pCall);
  1100. hResult = GKI_OK; // Don't want to exit PostReceive loop
  1101. }
  1102. }
  1103. else
  1104. {
  1105. SPIDER_TRACE(SP_PDU, "Rcv DCF; g_pReg = %X\n", this);
  1106. hResult = UnknownMessage(pRasMessage);
  1107. }
  1108. }
  1109. break;
  1110. case disengageReject_chosen:
  1111. {
  1112. // The sequence number of this RAS message seems to be the
  1113. // only thing we can link back to the DRQ so we use it
  1114. // to look up the call that this DRJ is associated with
  1115. RequestSeqNum seqNum = pRasMessage->u.disengageReject.requestSeqNum;
  1116. CCall *pCall = FindCallBySeqNum(seqNum);
  1117. if ((m_State == GK_REGISTERED) && (pCall))
  1118. {
  1119. SPIDER_TRACE(SP_PDU, "Rcv DRJ; pCall = %X\n", pCall);
  1120. hResult = pCall->DisengageReject(pRasMessage);
  1121. if (hResult == GKI_DELETE_CALL)
  1122. {
  1123. DeleteCall(pCall);
  1124. hResult = GKI_OK; // Don't want to exit PostReceive loop
  1125. }
  1126. }
  1127. else
  1128. {
  1129. SPIDER_TRACE(SP_PDU, "Rcv DRJ; g_pReg = %X\n", this);
  1130. hResult = UnknownMessage(pRasMessage);
  1131. }
  1132. }
  1133. break;
  1134. case locationConfirm_chosen:
  1135. SPIDER_TRACE(SP_PDU, "Rcv LCF; g_pReg = %X\n", this);
  1136. if ((m_State == GK_LOC_PENDING) &&
  1137. (pRasMessage->u.locationConfirm.requestSeqNum ==
  1138. m_pRasMessage->u.locationRequest.requestSeqNum))
  1139. hResult = LocationConfirm(pRasMessage);
  1140. else
  1141. hResult = UnknownMessage(pRasMessage);
  1142. break;
  1143. case locationReject_chosen:
  1144. SPIDER_TRACE(SP_PDU, "Rcv LRJ; g_pReg = %X\n", this);
  1145. if ((m_State == GK_LOC_PENDING) &&
  1146. (pRasMessage->u.locationReject.requestSeqNum ==
  1147. m_pRasMessage->u.locationRequest.requestSeqNum))
  1148. hResult = LocationReject(pRasMessage);
  1149. else
  1150. hResult = UnknownMessage(pRasMessage);
  1151. break;
  1152. case nonStandardMessage_chosen:
  1153. SPIDER_TRACE(SP_PDU, "Rcv NSM; g_pReg = %X\n", this);
  1154. hResult = UnknownMessage(pRasMessage);
  1155. break;
  1156. case unknownMessageResponse_chosen:
  1157. SPIDER_TRACE(SP_PDU, "Rcv XRS; g_pReg = %X\n", this);
  1158. break;
  1159. // Incoming Request PDUs
  1160. case unregistrationRequest_chosen:
  1161. SPIDER_TRACE(SP_PDU, "Rcv URQ; g_pReg = %X\n", this);
  1162. if (m_State == GK_REGISTERED)
  1163. {
  1164. WORD wReason;
  1165. // Notify user of received unregistration request and reason
  1166. if(pRasMessage->u.unregistrationRequest.bit_mask
  1167. & UnregistrationRequest_reason_present)
  1168. {
  1169. wReason = pRasMessage->u.unregistrationRequest.reason.choice;
  1170. }
  1171. else
  1172. wReason = 0;
  1173. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_UNREG_REQUEST, 0, 0)\n", 0);
  1174. PostMessage(m_hWnd, m_wBaseMessage + GKI_UNREG_REQUEST, wReason, 0);
  1175. hResult = SendUnregistrationConfirm(pRasMessage);
  1176. if (hResult == GKI_OK)
  1177. hResult = GKI_EXIT_THREAD;
  1178. }
  1179. else
  1180. hResult = UnknownMessage(pRasMessage);
  1181. break;
  1182. case bandwidthRequest_chosen:
  1183. {
  1184. // Check the CRV in this BRQ and see if we have a call
  1185. // that corresponds to it.
  1186. CallReferenceValue crv = pRasMessage->u.bandwidthRequest.callReferenceValue;
  1187. CCall *pCall = FindCallByCRV(crv);
  1188. if ((m_State == GK_REGISTERED) && (pCall))
  1189. {
  1190. SPIDER_TRACE(SP_PDU, "Rcv BRQ; pCall = %X\n", pCall);
  1191. hResult = pCall->SendBandwidthConfirm(pRasMessage);
  1192. }
  1193. else
  1194. {
  1195. SPIDER_TRACE(SP_PDU, "Rcv BRQ; g_pReg = %X\n", this);
  1196. hResult = UnknownMessage(pRasMessage);
  1197. }
  1198. }
  1199. break;
  1200. case disengageRequest_chosen:
  1201. {
  1202. // Check the CRV in this DRQ and see if we have a call
  1203. // that corresponds to it.
  1204. CallReferenceValue crv = pRasMessage->u.disengageRequest.callReferenceValue;
  1205. CCall *pCall = FindCallByCRV(crv);
  1206. if ((m_State == GK_REGISTERED) && (pCall))
  1207. {
  1208. SPIDER_TRACE(SP_PDU, "Rcv DRQ; pCall = %X\n", pCall);
  1209. hResult = pCall->SendDisengageConfirm(pRasMessage);
  1210. if (hResult == GKI_DELETE_CALL)
  1211. {
  1212. DeleteCall(pCall);
  1213. hResult = GKI_OK; // Don't want to exit PostReceive loop
  1214. }
  1215. }
  1216. else
  1217. {
  1218. SPIDER_TRACE(SP_PDU, "Rcv DRQ; g_pReg = %X\n", this);
  1219. hResult = UnknownMessage(pRasMessage);
  1220. }
  1221. }
  1222. break;
  1223. case infoRequest_chosen:
  1224. SPIDER_TRACE(SP_PDU, "Rcv IRQ; g_pReg = %X\n", this);
  1225. if ((m_State != GK_UNREGISTERED) && (m_State != GK_REG_PENDING))
  1226. {
  1227. // Check the CRV in this DRQ and see if we have a call
  1228. // that corresponds to it.
  1229. CallReferenceValue crv = pRasMessage->u.infoRequest.callReferenceValue;
  1230. CCall *pCall = NULL;
  1231. // A zero in the CRV means provide info for all calls, so we start
  1232. // the chain with the first one.
  1233. if (crv == 0)
  1234. {
  1235. if (m_Calls.IsEmpty())
  1236. hResult = SendInfoRequestResponse(0, pRasMessage);
  1237. else
  1238. {
  1239. POS pos = m_Calls.GetFirstPos();
  1240. pCall = m_Calls.GetAt(pos);
  1241. hResult = pCall->SendInfoRequestResponse(0, pRasMessage, FALSE);
  1242. }
  1243. }
  1244. else
  1245. {
  1246. // This is a call specific request so if we don't find
  1247. // a matching call, we'll send an XRS
  1248. pCall = FindCallByCRV(crv);
  1249. if (pCall)
  1250. hResult = pCall->SendInfoRequestResponse(0, pRasMessage, TRUE);
  1251. else
  1252. hResult = UnknownMessage(pRasMessage);
  1253. }
  1254. }
  1255. break;
  1256. // Should never see these PDUs
  1257. case gatekeeperRequest_chosen:
  1258. case registrationRequest_chosen:
  1259. case admissionRequest_chosen:
  1260. case locationRequest_chosen:
  1261. case infoRequestResponse_chosen:
  1262. SPIDER_TRACE(SP_PDU, "Rcv unexpected PDU; g_pReg = %X\n", this);
  1263. SPIDER_TRACE(SP_PDU, "pRasMessage->choice = %X\n", pRasMessage->choice);
  1264. hResult = UnknownMessage(pRasMessage);
  1265. break;
  1266. // Everything else - probably a bad PDU
  1267. default:
  1268. SPIDER_TRACE(SP_PDU, "Rcv unrecognized PDU; g_pReg = %X\n", this);
  1269. SPIDER_TRACE(SP_PDU, "pRasMessage->choice = %X\n", pRasMessage->choice);
  1270. hResult = UnknownMessage(pRasMessage);
  1271. break;
  1272. }
  1273. return (hResult);
  1274. }
  1275. HRESULT
  1276. CRegistration::RegistrationConfirm(RasMessage *pRasMessage)
  1277. {
  1278. // ABSTRACT: This function is called if a registrationConfirm is
  1279. // received and matches an outstanding registrationRequest.
  1280. // It will delete the memory used for the registrationRequest
  1281. // change the state and notify the user by posting a message.
  1282. // Additional information contained in the registrationConfirm
  1283. // is stored in the CRegistration class.
  1284. // AUTHOR: Colin Hulme
  1285. SeqAliasAddr *pAA;
  1286. #ifdef _DEBUG
  1287. char szGKDebug[80];
  1288. #endif
  1289. SPIDER_TRACE(SP_FUNC, "CRegistration::RegistrationConfirm(%X)\n", pRasMessage);
  1290. ASSERT(g_pCoder);
  1291. if (g_pCoder == NULL)
  1292. return (GKI_NOT_INITIALIZED);
  1293. // Delete allocated RasMessage storage
  1294. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  1295. delete m_pRasMessage;
  1296. m_pRasMessage = 0;
  1297. // Update member variables
  1298. m_State = GK_REGISTERED;
  1299. SPIDER_TRACE(SP_STATE, "m_State = GK_REGISTERED (%X)\n", this);
  1300. if (pRasMessage->u.registrationConfirm.bit_mask & RgstrtnCnfrm_trmnlAls_present)
  1301. {
  1302. // Copy alias addresses
  1303. for (pAA = (SeqAliasAddr *)pRasMessage->u.registrationConfirm.RgstrtnCnfrm_trmnlAls;
  1304. pAA != 0; pAA = pAA->next)
  1305. AddAliasAddr(pAA->value);
  1306. }
  1307. if ((pRasMessage->u.registrationConfirm.bit_mask & RCm_gtkprIdntfr_present) &&
  1308. (m_RCm_gtkprIdntfr.value == 0))
  1309. {
  1310. // Copy gatekeeper identifier
  1311. m_RCm_gtkprIdntfr.length = pRasMessage->u.registrationConfirm.RCm_gtkprIdntfr.length;
  1312. m_RCm_gtkprIdntfr.value = new unsigned short[m_RCm_gtkprIdntfr.length];
  1313. SPIDER_TRACE(SP_NEWDEL, "new m_RCm_gtkprIdntfr.value = %X\n", m_RCm_gtkprIdntfr.value);
  1314. if (m_RCm_gtkprIdntfr.value == 0)
  1315. return (GKI_NO_MEMORY);
  1316. memcpy(m_RCm_gtkprIdntfr.value,
  1317. pRasMessage->u.registrationConfirm.RCm_gtkprIdntfr.value,
  1318. m_RCm_gtkprIdntfr.length * sizeof(unsigned short));
  1319. }
  1320. // Copy endpoint identifier
  1321. m_endpointID.length = pRasMessage->u.registrationConfirm.endpointIdentifier.length;
  1322. m_endpointID.value = new unsigned short[m_endpointID.length];
  1323. SPIDER_TRACE(SP_NEWDEL, "new m_endpointID.value = %X\n", m_endpointID.value);
  1324. if (m_endpointID.value == 0)
  1325. return (GKI_NO_MEMORY);
  1326. memcpy(m_endpointID.value,
  1327. pRasMessage->u.registrationConfirm.endpointIdentifier.value,
  1328. m_endpointID.length * sizeof(unsigned short));
  1329. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_REG_CONFIRM, 0, 0)\n", 0);
  1330. PostMessage(m_hWnd, m_wBaseMessage + GKI_REG_CONFIRM, 0, 0);
  1331. return (GKI_OK);
  1332. }
  1333. HRESULT
  1334. CRegistration::RegistrationReject(RasMessage *pRasMessage)
  1335. {
  1336. // ABSTRACT: This function is called if a registrationReject is
  1337. // received and matches an outstanding registrationRequest.
  1338. // It will delete the memory used for the registrationRequest
  1339. // change the state and notify the user by posting a message
  1340. // Returning a non-zero value, indicates that the PostReceive
  1341. // loop should terminate, delete the registration object
  1342. // and exit the thread. If the rejectReason is discovery
  1343. // required, this function execs the discovery thread and
  1344. // notifies PostReceive to exit the thread without deleting
  1345. // the registration object and socket.
  1346. // AUTHOR: Colin Hulme
  1347. HANDLE hThread;
  1348. SeqTransportAddr *pTA1, *pTA2;
  1349. int nRet;
  1350. HRESULT hResult;
  1351. #ifdef _DEBUG
  1352. char szGKDebug[80];
  1353. #endif
  1354. SPIDER_TRACE(SP_FUNC, "CRegistration::RegistrationReject(%X)\n", pRasMessage);
  1355. ASSERT(g_pCoder);
  1356. if (g_pCoder == NULL)
  1357. return (GKI_NOT_INITIALIZED);
  1358. #ifdef BROADCAST_DISCOVERY
  1359. if (pRasMessage->u.registrationReject.rejectReason.choice == discoveryRequired_chosen)
  1360. {
  1361. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  1362. delete m_pRasMessage;
  1363. m_pRasMessage = 0;
  1364. // Close socket and reopen in non-connected state to allow sendto
  1365. if ((nRet = m_pSocket->Close()) != 0)
  1366. return (GKI_WINSOCK2_ERROR(nRet));
  1367. if ((nRet = m_pSocket->Create(m_pSocket->GetAddrFam(), 0)) != 0)
  1368. return (GKI_WINSOCK2_ERROR(nRet));
  1369. // Delete allocated memory for sequence of RAS addresses
  1370. pTA1 = m_pRASAddress;
  1371. while (pTA1 != 0)
  1372. {
  1373. pTA2 = pTA1->next;
  1374. SPIDER_TRACE(SP_NEWDEL, "del pTA1 = %X\n", pTA1);
  1375. delete pTA1;
  1376. pTA1 = pTA2;
  1377. }
  1378. // Update RAS Address in CRegistration
  1379. for (pTA1 = m_pCallSignalAddress; pTA1 != 0; pTA1 = pTA1->next)
  1380. {
  1381. if (pTA1->value.choice == m_usRegistrationTransport)
  1382. if ((hResult = AddRASAddr(pTA1->value, m_pSocket->GetPort())) != GKI_OK)
  1383. return (hResult);
  1384. }
  1385. hThread = (HANDLE)_beginthread(GKDiscovery, 0, 0);
  1386. SPIDER_TRACE(SP_THREAD, "_beginthread(GKDiscovery, 0, 0); <%X>\n", hThread);
  1387. if (hThread == (HANDLE)-1)
  1388. return (GKI_NO_THREAD);
  1389. SetDiscThread(hThread);
  1390. return (GKI_REDISCOVER);
  1391. }
  1392. #endif // BROADCAST_DISCOVERY
  1393. m_State = GK_UNREGISTERED;
  1394. SPIDER_TRACE(SP_STATE, "m_State = GK_UNREGISTERED (%X)\n", this);
  1395. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_REG_REJECT, %X, 0)\n",
  1396. pRasMessage->u.registrationReject.rejectReason.choice);
  1397. PostMessage(m_hWnd, m_wBaseMessage + GKI_REG_REJECT,
  1398. (WORD)pRasMessage->u.registrationReject.rejectReason.choice, 0L);
  1399. return (GKI_EXIT_THREAD);
  1400. }
  1401. HRESULT
  1402. CRegistration::UnregistrationConfirm(RasMessage *pRasMessage)
  1403. {
  1404. // ABSTRACT: This function is called if an unregistrationConfirm is
  1405. // received and matches an outstanding unregistrationRequest.
  1406. // It will delete the memory used for the unregistrationRequest
  1407. // change the state and notify the user by posting a message.
  1408. // Returning a non-zero value, indicates that the PostReceive
  1409. // loop should terminate, delete the registration object
  1410. // and exit the thread.
  1411. // AUTHOR: Colin Hulme
  1412. #ifdef _DEBUG
  1413. char szGKDebug[80];
  1414. #endif
  1415. SPIDER_TRACE(SP_FUNC, "CRegistration::UnregistrationConfirm(%X)\n", pRasMessage);
  1416. // We deliberately don't free the RasMessage memory. Let the registration
  1417. // destructor do it - this provides protection from other requests.
  1418. // Update member variables
  1419. m_State = GK_UNREGISTERED;
  1420. SPIDER_TRACE(SP_STATE, "m_State = GK_UNREGISTERED (%X)\n", this);
  1421. // Notify user application
  1422. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_UNREG_CONFIRM, 0, 0)\n", 0);
  1423. PostMessage(m_hWnd, m_wBaseMessage + GKI_UNREG_CONFIRM, 0, 0L);
  1424. return (GKI_EXIT_THREAD);
  1425. }
  1426. HRESULT
  1427. CRegistration::UnregistrationReject(RasMessage *pRasMessage)
  1428. {
  1429. // ABSTRACT: This function is called if an unregistrationReject is
  1430. // received and matches an outstanding unregistrationRequest.
  1431. // It will delete the memory used for the unregistrationRequest
  1432. // change the state and notify the user by posting a message
  1433. // Returning a non-zero value, indicates that the PostReceive
  1434. // loop should terminate, delete the registration object
  1435. // and exit the thread.
  1436. // AUTHOR: Colin Hulme
  1437. #ifdef _DEBUG
  1438. char szGKDebug[80];
  1439. #endif
  1440. HRESULT hResult = GKI_OK;
  1441. SPIDER_TRACE(SP_FUNC, "CRegistration::UnregistrationReject(%X)\n", pRasMessage);
  1442. // Update member variables
  1443. switch (pRasMessage->u.unregistrationReject.rejectReason.choice)
  1444. {
  1445. case callInProgress_chosen: // return to registered state
  1446. // Delete allocate RasMessage storage
  1447. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  1448. delete m_pRasMessage;
  1449. m_pRasMessage = 0;
  1450. m_State = GK_REGISTERED;
  1451. SPIDER_TRACE(SP_STATE, "m_State = GK_REGISTERED (%X)\n", this);
  1452. break;
  1453. case notCurrentlyRegistered_chosen:
  1454. default:
  1455. m_State = GK_UNREGISTERED;
  1456. SPIDER_TRACE(SP_STATE, "m_State = GK_UNREGISTERED (%X)\n", this);
  1457. hResult = GKI_EXIT_THREAD; // kill registration and PostReceive thread
  1458. break;
  1459. }
  1460. // Notify user application
  1461. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_UNREG_REJECT, %X, 0)\n",
  1462. pRasMessage->u.unregistrationReject.rejectReason.choice);
  1463. PostMessage(m_hWnd, m_wBaseMessage + GKI_UNREG_REJECT,
  1464. (WORD)pRasMessage->u.unregistrationReject.rejectReason.choice, 0L);
  1465. return (hResult);
  1466. }
  1467. HRESULT
  1468. CRegistration::LocationConfirm(RasMessage *pRasMessage)
  1469. {
  1470. // ABSTRACT: This function is called if a locationConfirm is
  1471. // received and matches an outstanding locationRequest.
  1472. // It will delete the memory used for the locationRequest
  1473. // change the state and notify the user by posting a message.
  1474. // AUTHOR: Colin Hulme
  1475. SeqAliasAddr *pAA1, *pAA2;
  1476. #ifdef _DEBUG
  1477. char szGKDebug[80];
  1478. #endif
  1479. SPIDER_TRACE(SP_FUNC, "CRegistration::LocationConfirm(%X)\n", pRasMessage);
  1480. // Delete allocated RasMessage storage
  1481. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  1482. delete m_pRasMessage;
  1483. m_pRasMessage = 0;
  1484. // Delete allocated memory for sequence of location alias addresses
  1485. pAA1 = m_pLocationInfo;
  1486. while (pAA1 != 0)
  1487. {
  1488. pAA2 = pAA1->next;
  1489. if (pAA1->value.choice == h323_ID_chosen)
  1490. {
  1491. SPIDER_TRACE(SP_NEWDEL, "del pAA1->value.u.h323_ID.value = %X\n", pAA1->value.u.h323_ID.value);
  1492. delete pAA1->value.u.h323_ID.value;
  1493. }
  1494. SPIDER_TRACE(SP_NEWDEL, "del pAA1 = %X\n", pAA1);
  1495. delete pAA1;
  1496. pAA1 = pAA2;
  1497. }
  1498. m_pLocationInfo = 0;
  1499. // Update member variables
  1500. m_State = GK_REGISTERED;
  1501. SPIDER_TRACE(SP_STATE, "m_State = GK_REGISTERED (%X)\n", this);
  1502. m_Location[0] = pRasMessage->u.locationConfirm.callSignalAddress;
  1503. m_Location[1] = pRasMessage->u.locationConfirm.rasAddress;
  1504. // Notify user application
  1505. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_LOCATION_CONFIRM, 0, &m_Location[0])\n", 0);
  1506. PostMessage(m_hWnd, m_wBaseMessage + GKI_LOCATION_CONFIRM,
  1507. 0, (LPARAM)&m_Location[0]);
  1508. return (GKI_OK);
  1509. }
  1510. HRESULT
  1511. CRegistration::LocationReject(RasMessage *pRasMessage)
  1512. {
  1513. // ABSTRACT: This function is called if a locationReject is
  1514. // received and matches an outstanding locationRequest.
  1515. // It will delete the memory used for the locationRequest
  1516. // change the state and notify the user by posting a message
  1517. // AUTHOR: Colin Hulme
  1518. SeqAliasAddr *pAA1, *pAA2;
  1519. #ifdef _DEBUG
  1520. char szGKDebug[80];
  1521. #endif
  1522. SPIDER_TRACE(SP_FUNC, "CRegistration::LocationReject(%X)\n", pRasMessage);
  1523. // Delete allocate RasMessage storage
  1524. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  1525. delete m_pRasMessage;
  1526. m_pRasMessage = 0;
  1527. // Delete allocated memory for sequence of location alias addresses
  1528. pAA1 = m_pLocationInfo;
  1529. while (pAA1 != 0)
  1530. {
  1531. pAA2 = pAA1->next;
  1532. if (pAA1->value.choice == h323_ID_chosen)
  1533. {
  1534. SPIDER_TRACE(SP_NEWDEL, "del pAA1->value.u.h323_ID.value = %X\n", pAA1->value.u.h323_ID.value);
  1535. delete pAA1->value.u.h323_ID.value;
  1536. }
  1537. SPIDER_TRACE(SP_NEWDEL, "del pAA1 = %X\n", pAA1);
  1538. delete pAA1;
  1539. pAA1 = pAA2;
  1540. }
  1541. m_pLocationInfo = 0;
  1542. // Update member variables
  1543. m_State = GK_REGISTERED;
  1544. SPIDER_TRACE(SP_STATE, "m_State = GK_REGISTERED (%X)\n", this);
  1545. // Notify user application
  1546. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_LOCATION_REJECT, %X, 0)\n",
  1547. pRasMessage->u.locationReject.rejectReason.choice);
  1548. PostMessage(m_hWnd, m_wBaseMessage + GKI_LOCATION_REJECT,
  1549. (WORD)pRasMessage->u.locationReject.rejectReason.choice, 0L);
  1550. return (GKI_OK);
  1551. }
  1552. HRESULT
  1553. CRegistration::UnknownMessage(RasMessage *pRasMessage)
  1554. {
  1555. // ABSTRACT: This member function is called to respond to the gatekeeper
  1556. // with an XRS PDU indicated that the received PDU is an unknown
  1557. // message
  1558. // AUTHOR: Colin Hulme
  1559. ASN1_BUF Asn1Buf;
  1560. DWORD dwErrorCode;
  1561. RasMessage *pOutRasMessage;
  1562. #ifdef _DEBUG
  1563. char szGKDebug[80];
  1564. #endif
  1565. SPIDER_TRACE(SP_FUNC, "CRegistration::UnknownMessage(%X)\n", pRasMessage);
  1566. ASSERT(g_pCoder);
  1567. if (g_pCoder == NULL)
  1568. return (GKI_NOT_INITIALIZED);
  1569. // Allocate a RasMessage structure and initialized to 0
  1570. pOutRasMessage = new RasMessage;
  1571. SPIDER_TRACE(SP_NEWDEL, "new pOutRasMessage = %X\n", pOutRasMessage);
  1572. if (pOutRasMessage == 0)
  1573. return (GKI_NO_MEMORY);
  1574. memset(pOutRasMessage, 0, sizeof(RasMessage));
  1575. // Setup structure fields for UnregistrationRequest
  1576. pOutRasMessage->choice = unknownMessageResponse_chosen;
  1577. pOutRasMessage->u.unknownMessageResponse.requestSeqNum =
  1578. pRasMessage->u.registrationRequest.requestSeqNum; // can use from
  1579. // from any RAS Message, since SeqNum
  1580. // is always in same position.
  1581. // Encode the PDU & send it
  1582. dwErrorCode = g_pCoder->Encode(pOutRasMessage, &Asn1Buf);
  1583. if (dwErrorCode)
  1584. return (GKI_ENCODER_ERROR);
  1585. SPIDER_TRACE(SP_PDU, "Send XRS; g_pReg = %X\n", this);
  1586. if (fGKIDontSend == FALSE)
  1587. if (m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  1588. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  1589. // Free the encoder memory
  1590. g_pCoder->Free(Asn1Buf);
  1591. SPIDER_TRACE(SP_NEWDEL, "del pOutRasMessage = %X\n", pOutRasMessage);
  1592. delete pOutRasMessage;
  1593. pOutRasMessage = 0;
  1594. return (GKI_OK);
  1595. }
  1596. HRESULT
  1597. CRegistration::GatekeeperConfirm(RasMessage *pRasMessage)
  1598. {
  1599. // ABSTRACT: This function is called if a gatekeeperConfirm is
  1600. // received. Note this member function must first ascertain
  1601. // that the supplied confirmation sequence number matches
  1602. // the outstanding request sequence number, if not - it
  1603. // will send an XRS response.
  1604. // AUTHOR: Colin Hulme
  1605. char szBuffer[80];
  1606. HRESULT hResult;
  1607. #ifdef _DEBUG
  1608. char szGKDebug[80];
  1609. #endif
  1610. SPIDER_TRACE(SP_FUNC, "CRegistration::GatekeeperConfirm(%X)\n", pRasMessage);
  1611. ASSERT(g_pGatekeeper);
  1612. if(g_pGatekeeper == NULL)
  1613. return (GKI_NOT_INITIALIZED);
  1614. if (m_pRasMessage == 0)
  1615. return (0);
  1616. if (pRasMessage->u.gatekeeperConfirm.requestSeqNum !=
  1617. m_pRasMessage->u.gatekeeperRequest.requestSeqNum)
  1618. {
  1619. hResult = g_pReg->UnknownMessage(pRasMessage);
  1620. return (hResult);
  1621. }
  1622. // Delete allocated RasMessage storage
  1623. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  1624. delete m_pRasMessage;
  1625. m_pRasMessage = 0;
  1626. // Update member variables
  1627. if ((pRasMessage->u.gatekeeperConfirm.bit_mask & GtkprCnfrm_gtkprIdntfr_present) &&
  1628. (m_RCm_gtkprIdntfr.value == 0))
  1629. {
  1630. // Copy gatekeeper identifier
  1631. m_RCm_gtkprIdntfr.length = pRasMessage->u.gatekeeperConfirm.GtkprCnfrm_gtkprIdntfr.length;
  1632. m_RCm_gtkprIdntfr.value = new unsigned short[m_RCm_gtkprIdntfr.length];
  1633. SPIDER_TRACE(SP_NEWDEL, "new m_RCm_gtkprIdntfr.value = %X\n", m_RCm_gtkprIdntfr.value);
  1634. if (m_RCm_gtkprIdntfr.value == 0)
  1635. return (GKI_NO_MEMORY);
  1636. memcpy(m_RCm_gtkprIdntfr.value,
  1637. pRasMessage->u.gatekeeperConfirm.GtkprCnfrm_gtkprIdntfr.value,
  1638. m_RCm_gtkprIdntfr.length * sizeof(unsigned short));
  1639. }
  1640. // Copy gatekeeper RAS Address
  1641. ASSERT((pRasMessage->u.gatekeeperConfirm.rasAddress.choice == ipAddress_chosen) ||
  1642. (pRasMessage->u.gatekeeperConfirm.rasAddress.choice == ipxAddress_chosen));
  1643. switch (pRasMessage->u.gatekeeperConfirm.rasAddress.choice)
  1644. {
  1645. case ipAddress_chosen:
  1646. wsprintf(szBuffer, "%d.%d.%d.%d",
  1647. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipAddress.ip.value[0],
  1648. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipAddress.ip.value[1],
  1649. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipAddress.ip.value[2],
  1650. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipAddress.ip.value[3]);
  1651. g_pGatekeeper->SetIPAddress(szBuffer);
  1652. break;
  1653. #if(0)
  1654. case ipxAddress_chosen:
  1655. wsprintf(szBuffer, "%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X",
  1656. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipxAddress.netnum.value[0],
  1657. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipxAddress.netnum.value[1],
  1658. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipxAddress.netnum.value[2],
  1659. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipxAddress.netnum.value[3],
  1660. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipxAddress.node.value[0],
  1661. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipxAddress.node.value[1],
  1662. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipxAddress.node.value[2],
  1663. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipxAddress.node.value[3],
  1664. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipxAddress.node.value[4],
  1665. pRasMessage->u.gatekeeperConfirm.rasAddress.u.ipxAddress.node.value[5]);
  1666. g_pGatekeeper->SetIPXAddress(szBuffer);
  1667. break;
  1668. #endif // if(0)
  1669. default:
  1670. break;
  1671. }
  1672. g_pGatekeeper->Write();
  1673. return (GKI_OK);
  1674. }
  1675. HRESULT
  1676. CRegistration::GatekeeperReject(RasMessage *pRasMessage)
  1677. {
  1678. // ABSTRACT: This function is called if a gatekeeperReject is
  1679. // received. Note this member function must first ascertain
  1680. // that the supplied rejection sequence number matches
  1681. // the outstanding request sequence number, if not - it
  1682. // will send an XRS response.
  1683. // AUTHOR: Colin Hulme
  1684. HRESULT hResult;
  1685. #ifdef _DEBUG
  1686. char szGKDebug[80];
  1687. #endif
  1688. SPIDER_TRACE(SP_FUNC, "CRegistration::GatekeeperReject(%X)\n", pRasMessage);
  1689. ASSERT(g_pGatekeeper);
  1690. if(g_pGatekeeper == NULL)
  1691. return (GKI_NOT_INITIALIZED);
  1692. if (m_pRasMessage == 0)
  1693. return (GKI_OK);
  1694. if (pRasMessage->u.gatekeeperReject.requestSeqNum !=
  1695. m_pRasMessage->u.gatekeeperRequest.requestSeqNum)
  1696. {
  1697. hResult = g_pReg->UnknownMessage(pRasMessage);
  1698. return (hResult);
  1699. }
  1700. g_pGatekeeper->SetRejectFlag(TRUE); // Indicate that atleast one GRJ was received
  1701. return (GKI_OK);
  1702. }
  1703. HRESULT
  1704. CRegistration::SendUnregistrationConfirm(RasMessage *pRasMessage)
  1705. {
  1706. // ABSTRACT: This function is called when an unregistrationRequest is
  1707. // received from the gatekeeper. It will create the
  1708. // unregistrationConfirm structure, encode it and send
  1709. // it on the net. It posts a message to the user
  1710. // notifying them.
  1711. // AUTHOR: Colin Hulme
  1712. ASN1_BUF Asn1Buf;
  1713. DWORD dwErrorCode;
  1714. RasMessage *pRespRasMessage;
  1715. #ifdef _DEBUG
  1716. char szGKDebug[80];
  1717. #endif
  1718. SPIDER_TRACE(SP_FUNC, "CRegistration::UnregistrationConfirm(%X)\n", pRasMessage);
  1719. ASSERT(g_pCoder);
  1720. if (g_pCoder == NULL)
  1721. return (GKI_NOT_INITIALIZED);
  1722. // Allocate a RasMessage structure and initialized to 0
  1723. pRespRasMessage = new RasMessage;
  1724. SPIDER_TRACE(SP_NEWDEL, "new pRespRasMessage = %X\n", pRespRasMessage);
  1725. if (pRespRasMessage == 0)
  1726. return (GKI_NO_MEMORY);
  1727. memset(pRespRasMessage, 0, sizeof(RasMessage));
  1728. // Setup structure fields for UnregistrationConfirm
  1729. pRespRasMessage->choice = unregistrationConfirm_chosen;
  1730. pRespRasMessage->u.unregistrationConfirm.requestSeqNum =
  1731. pRasMessage->u.unregistrationRequest.requestSeqNum;
  1732. #ifdef _DEBUG
  1733. if (dwGKIDLLFlags & SP_DUMPMEM)
  1734. DumpMem(pRespRasMessage, sizeof(RasMessage));
  1735. #endif
  1736. // Encode the PDU & send it
  1737. dwErrorCode = g_pCoder->Encode(pRespRasMessage, &Asn1Buf);
  1738. if (dwErrorCode)
  1739. return (GKI_ENCODER_ERROR);
  1740. m_State = GK_UNREGISTERED;
  1741. SPIDER_TRACE(SP_STATE, "m_State = GK_UNREGISTERED (%X)\n", this);
  1742. SPIDER_TRACE(SP_PDU, "Send UCF; g_pReg = %X\n", this);
  1743. if (fGKIDontSend == FALSE)
  1744. if (m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  1745. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  1746. // Free the encoder memory
  1747. g_pCoder->Free(Asn1Buf);
  1748. // Delete allocated RasMessage storage
  1749. SPIDER_TRACE(SP_NEWDEL, "del pRespRasMessage = %X\n", pRespRasMessage);
  1750. delete pRespRasMessage;
  1751. // fake "received unregistration confirm" because the upper
  1752. // state machine code depends on it
  1753. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_UNREG_CONFIRM, 0, 0)\n", 0);
  1754. PostMessage(m_hWnd, m_wBaseMessage + GKI_UNREG_CONFIRM, 0, 0);
  1755. return (GKI_OK);
  1756. }
  1757. HRESULT
  1758. CRegistration::Retry(void)
  1759. {
  1760. // ABSTRACT: This function is called by the background Retry thread
  1761. // at the configured time interval. It will check if there
  1762. // are any outstanding PDUs for the Registration object
  1763. // If so, they will be retransmitted. If the maximum number of
  1764. // retries has expired, the memory will be cleaned up.
  1765. // This function will return 0 to the background thread unless
  1766. // it wants the thread to terminate.
  1767. // AUTHOR: Colin Hulme
  1768. ASN1_BUF Asn1Buf;
  1769. DWORD dwErrorCode;
  1770. HANDLE hThread;
  1771. SeqTransportAddr *pTA1, *pTA2;
  1772. SeqAliasAddr *pAA1, *pAA2;
  1773. int nRet;
  1774. #ifdef _DEBUG
  1775. char szGKDebug[80];
  1776. #endif
  1777. HRESULT hResult = GKI_OK;
  1778. // SPIDER_TRACE(SP_FUNC, "CRegistration::Retry() %X\n", m_pCall);
  1779. ASSERT(g_pCoder);
  1780. if ((g_pCoder == NULL) && (g_pGatekeeper == NULL))
  1781. return (GKI_NOT_INITIALIZED);
  1782. // Allow calls to do retry processing
  1783. if (!m_Calls.IsEmpty())
  1784. {
  1785. // Loop through and let each call do it's retry processing
  1786. // It should be safe to call DeleteCall() from within the
  1787. // iteration since pos1 should still be valid after the
  1788. // removal.
  1789. POS pos1;
  1790. for( pos1 = m_Calls.GetFirstPos(); pos1 != NULL; )
  1791. {
  1792. // Call Retry() for this call
  1793. CCall *pCall = m_Calls.GetNext(pos1);
  1794. ASSERT (pCall);
  1795. hResult = pCall->Retry();
  1796. if (hResult == GKI_DELETE_CALL)
  1797. {
  1798. DeleteCall(pCall);
  1799. hResult = GKI_OK;
  1800. }
  1801. }
  1802. }
  1803. // Check if any outstanding registration PDUs
  1804. if (m_pRasMessage && (--m_uRetryCountdown == 0))
  1805. {
  1806. // going to retry, reset countdown
  1807. m_uRetryCountdown = m_uRetryResetCount;
  1808. if (m_usRetryCount <= m_uMaxRetryCount)
  1809. {
  1810. // Encode the PDU & resend it
  1811. dwErrorCode = g_pCoder->Encode(m_pRasMessage, &Asn1Buf);
  1812. if (dwErrorCode)
  1813. return (GKI_ENCODER_ERROR);
  1814. SPIDER_TRACE(SP_PDU, "RESend PDU; g_pReg = %X\n", this);
  1815. if (fGKIDontSend == FALSE)
  1816. {
  1817. if (m_pRasMessage->choice == gatekeeperRequest_chosen)
  1818. {
  1819. if (m_pSocket->SendBroadcast((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  1820. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  1821. }
  1822. else
  1823. {
  1824. if (m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  1825. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  1826. }
  1827. }
  1828. // Free the encoder memory
  1829. g_pCoder->Free(Asn1Buf);
  1830. m_usRetryCount++;
  1831. }
  1832. else // Retries expired - clean up
  1833. {
  1834. switch (m_pRasMessage->choice)
  1835. {
  1836. case gatekeeperRequest_chosen:
  1837. #ifdef BROADCAST_DISCOVERY
  1838. m_State = GK_UNREGISTERED;
  1839. SPIDER_TRACE(SP_STATE, "m_State = GK_UNREGISTERED (%X)\n", this);
  1840. // We deliberately don't free the RasMessage memory. Let the
  1841. // registration destructor do it - this provides protection
  1842. // from other requests.
  1843. // Close socket - this will terminate the Discovery thread
  1844. if ((nRet = m_pSocket->Close()) != 0)
  1845. return (GKI_WINSOCK2_ERROR(nRet));
  1846. // Delete cached address from the registry
  1847. g_pGatekeeper->DeleteCachedAddresses();
  1848. if (g_pGatekeeper->GetRejectFlag() == FALSE)
  1849. {
  1850. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_REG_BYPASS, 0, 0)\n", 0);
  1851. PostMessage(m_hWnd, m_wBaseMessage + GKI_REG_BYPASS,
  1852. 0, 0);
  1853. return (GKI_EXIT_THREAD);
  1854. }
  1855. else
  1856. hResult = GKI_EXIT_THREAD;
  1857. #else
  1858. ASSERT(0);
  1859. hResult = GKI_EXIT_THREAD;
  1860. #endif //BROADCAST_DISCOVERY
  1861. break;
  1862. case registrationRequest_chosen:
  1863. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  1864. delete m_pRasMessage;
  1865. m_pRasMessage = 0;
  1866. #ifdef BROADCAST_DISCOVERY
  1867. // Need to attempt gatekeeper discovery
  1868. // Close socket and reopen in non-connected state to allow sendto
  1869. // This will also terminate the PostRecv thread
  1870. if ((nRet = m_pSocket->Close()) != 0)
  1871. return (GKI_WINSOCK2_ERROR(nRet));
  1872. if ((nRet = m_pSocket->Create(m_pSocket->GetAddrFam(), 0)) != 0)
  1873. return (GKI_WINSOCK2_ERROR(nRet));
  1874. // Delete allocated memory for sequence of RAS addresses
  1875. pTA1 = m_pRASAddress;
  1876. while (pTA1 != 0)
  1877. {
  1878. pTA2 = pTA1->next;
  1879. SPIDER_TRACE(SP_NEWDEL, "del pTA1 = %X\n", pTA1);
  1880. delete pTA1;
  1881. pTA1 = pTA2;
  1882. }
  1883. // Update RAS Address in CRegistration
  1884. for (pTA1 = m_pCallSignalAddress; pTA1 != 0; pTA1 = pTA1->next)
  1885. {
  1886. if (pTA1->value.choice == m_usRegistrationTransport)
  1887. if ((hResult = AddRASAddr(pTA1->value, m_pSocket->GetPort())) != GKI_OK)
  1888. return (hResult);
  1889. }
  1890. // Start the discovery thread
  1891. hThread = (HANDLE)_beginthread(GKDiscovery, 0, 0);
  1892. SPIDER_TRACE(SP_THREAD, "_beginthread(GKDiscovery, 0, 0); <%X>\n", hThread);
  1893. if (hThread == (HANDLE)-1)
  1894. return (GKI_NO_THREAD);
  1895. SetDiscThread(hThread);
  1896. hResult = GKI_REDISCOVER;
  1897. break;
  1898. #else // not BROADCAST_DISCOVERY
  1899. hResult = GKI_EXIT_THREAD;
  1900. #endif // BROADCAST_DISCOVERY
  1901. case unregistrationRequest_chosen:
  1902. m_State = GK_UNREGISTERED;
  1903. SPIDER_TRACE(SP_STATE, "m_State = GK_UNREGISTERED (%X)\n", this);
  1904. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  1905. delete m_pRasMessage;
  1906. m_pRasMessage = 0;
  1907. // Close socket - this will terminate the Receive thread
  1908. if ((nRet = m_pSocket->Close()) != 0)
  1909. return (GKI_WINSOCK2_ERROR(nRet));
  1910. hResult = GKI_EXIT_THREAD;
  1911. break;
  1912. case locationRequest_chosen:
  1913. m_State = GK_REGISTERED;
  1914. SPIDER_TRACE(SP_STATE, "m_State = GK_REGISTERED (%X)\n", this);
  1915. SPIDER_TRACE(SP_NEWDEL, "del m_pRasMessage = %X\n", m_pRasMessage);
  1916. delete m_pRasMessage;
  1917. m_pRasMessage = 0;
  1918. // Delete allocated memory for sequence of location alias addresses
  1919. pAA1 = m_pLocationInfo;
  1920. while (pAA1 != 0)
  1921. {
  1922. pAA2 = pAA1->next;
  1923. if (pAA1->value.choice == h323_ID_chosen)
  1924. {
  1925. SPIDER_TRACE(SP_NEWDEL, "del pAA1->value.u.h323_ID.value = %X\n", pAA1->value.u.h323_ID.value);
  1926. delete pAA1->value.u.h323_ID.value;
  1927. }
  1928. SPIDER_TRACE(SP_NEWDEL, "del pAA1 = %X\n", pAA1);
  1929. delete pAA1;
  1930. pAA1 = pAA2;
  1931. }
  1932. break;
  1933. }
  1934. // Notify user that gatekeeper didn't respond
  1935. if (hResult != GKI_REDISCOVER)
  1936. {
  1937. SPIDER_TRACE(SP_GKI, "PostMessage(m_hWnd, m_wBaseMessage + GKI_ERROR, 0, GKI_NO_RESPONSE)\n", 0);
  1938. PostMessage(m_hWnd, m_wBaseMessage + GKI_ERROR,
  1939. 0, GKI_NO_RESPONSE);
  1940. }
  1941. else
  1942. hResult = GKI_OK; // Don't exit retry thread
  1943. }
  1944. }
  1945. return (hResult);
  1946. }
  1947. HRESULT
  1948. CRegistration::SendInfoRequestResponse(CallInfoStruct *pCallInfo, RasMessage *pRasMessage)
  1949. {
  1950. // ABSTRACT: This function is called from one or more call object
  1951. // to create an IRR RasMessage, encapsulate the supplied
  1952. // call information and send the message to the
  1953. // gatekeeper.
  1954. // AUTHOR: Colin Hulme
  1955. ASN1_BUF Asn1Buf;
  1956. DWORD dwErrorCode;
  1957. RasMessage *pRespRasMessage;
  1958. struct sockaddr_in sAddrIn;
  1959. #ifdef _DEBUG
  1960. char szGKDebug[80];
  1961. #endif
  1962. SPIDER_TRACE(SP_FUNC, "CRegistration::SendInfoRequestResponse()\n", 0);
  1963. ASSERT(g_pCoder);
  1964. if (g_pCoder == NULL)
  1965. return (GKI_NOT_INITIALIZED);
  1966. // Allocate a RasMessage structure and initialized to 0
  1967. pRespRasMessage = new RasMessage;
  1968. SPIDER_TRACE(SP_NEWDEL, "new pRespRasMessage = %X\n", pRespRasMessage);
  1969. if (pRespRasMessage == 0)
  1970. return (GKI_NO_MEMORY);
  1971. memset(pRespRasMessage, 0, sizeof(RasMessage));
  1972. // Setup structure fields for InfoRequestResponse
  1973. pRespRasMessage->choice = infoRequestResponse_chosen;
  1974. if (m_pRgstrtnRqst_trmnlAls != 0)
  1975. pRespRasMessage->u.infoRequestResponse.bit_mask |= InfRqstRspns_endpntAls_present;
  1976. if (pCallInfo != 0)
  1977. pRespRasMessage->u.infoRequestResponse.bit_mask |= perCallInfo_present;
  1978. if (pRasMessage)
  1979. {
  1980. pRespRasMessage->u.infoRequestResponse.requestSeqNum =
  1981. pRasMessage->u.infoRequest.requestSeqNum;
  1982. if (pRasMessage->u.infoRequest.bit_mask & replyAddress_present)
  1983. {
  1984. switch (pRasMessage->u.infoRequest.replyAddress.choice)
  1985. {
  1986. case ipAddress_chosen:
  1987. sAddrIn.sin_family = AF_INET;
  1988. sAddrIn.sin_port = htons(pRasMessage->u.infoRequest.replyAddress.u.ipAddress.port);
  1989. break;
  1990. case ipxAddress_chosen:
  1991. sAddrIn.sin_family = AF_IPX;
  1992. sAddrIn.sin_port = htons(GKIPX_RAS_PORT); //Need to use reply port
  1993. break;
  1994. }
  1995. memcpy(&sAddrIn.sin_addr,
  1996. &pRasMessage->u.infoRequest.replyAddress.u.ipAddress.ip.value[0], 4);
  1997. }
  1998. }
  1999. else
  2000. // unsolicited IRRs must have a sequence number of 1!!!! (H.225 says so)
  2001. pRespRasMessage->u.infoRequestResponse.requestSeqNum = 1;
  2002. pRespRasMessage->u.infoRequestResponse.endpointType = m_terminalType;
  2003. pRespRasMessage->u.infoRequestResponse.endpointIdentifier = m_endpointID;
  2004. pRespRasMessage->u.infoRequestResponse.rasAddress = m_pRASAddress->value;
  2005. pRespRasMessage->u.infoRequestResponse.callSignalAddress =
  2006. (PInfoRequestResponse_callSignalAddress)m_pCallSignalAddress;
  2007. pRespRasMessage->u.infoRequestResponse.InfRqstRspns_endpntAls =
  2008. (PInfoRequestResponse_endpointAlias)m_pRgstrtnRqst_trmnlAls;
  2009. pRespRasMessage->u.infoRequestResponse.perCallInfo =
  2010. (PInfoRequestResponse_perCallInfo)pCallInfo;
  2011. #ifdef _DEBUG
  2012. if (dwGKIDLLFlags & SP_DUMPMEM)
  2013. DumpMem(pRespRasMessage, sizeof(RasMessage));
  2014. #endif
  2015. // Encode the PDU & send it
  2016. dwErrorCode = g_pCoder->Encode(pRespRasMessage, &Asn1Buf);
  2017. if (dwErrorCode)
  2018. return (GKI_ENCODER_ERROR);
  2019. SPIDER_TRACE(SP_PDU, "Send IRR; g_pReg = %X\n", this);
  2020. if (fGKIDontSend == FALSE)
  2021. {
  2022. if (pRasMessage && (pRasMessage->u.infoRequest.bit_mask & replyAddress_present))
  2023. {
  2024. if (g_pReg->m_pSocket->SendTo((char *)Asn1Buf.value, Asn1Buf.length,
  2025. (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn)) == SOCKET_ERROR)
  2026. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  2027. }
  2028. else
  2029. {
  2030. if (g_pReg->m_pSocket->Send((char *)Asn1Buf.value, Asn1Buf.length) == SOCKET_ERROR)
  2031. return (GKI_WINSOCK2_ERROR(SOCKET_ERROR));
  2032. }
  2033. }
  2034. // Free the encoder memory
  2035. g_pCoder->Free(Asn1Buf);
  2036. // Delete allocated RasMessage storage
  2037. SPIDER_TRACE(SP_NEWDEL, "del pRespRasMessage = %X\n", pRespRasMessage);
  2038. delete pRespRasMessage;
  2039. return (GKI_OK);
  2040. }
  2041. //
  2042. // FindCallBySeqNum()
  2043. //
  2044. // ABSTRACT:
  2045. // This function attempts to locate a call within the list of calls
  2046. // in the registration object that has an outstanding RAS request that has this
  2047. // sequence number.
  2048. //
  2049. // RETURNS:
  2050. // Pointer to call associated with the sequence number or
  2051. // NULL if no call is found.
  2052. //
  2053. // NOTES:
  2054. // This function is usually called by the CRegistration::PDUHandler()
  2055. // when it receives a reply message that needs to be associated with a
  2056. // particular call.
  2057. //
  2058. // ASSUMPTIONS:
  2059. // Each call object holds on to the sequence numbers for RAS
  2060. // requests that it has not received replies for.
  2061. //
  2062. // AUTHOR: Dan Dexter
  2063. CCall *
  2064. CRegistration::FindCallBySeqNum(RequestSeqNum seqNum)
  2065. {
  2066. // If there are no calls, we can just return now
  2067. if (m_Calls.IsEmpty())
  2068. return(NULL);
  2069. // Initialize return value to "call not found"
  2070. CCall *RetVal = NULL;
  2071. // Otherwise, iterate through the calls and ask them
  2072. // if this sequence number belongs to them
  2073. POS pos;
  2074. for( pos = m_Calls.GetFirstPos(); pos != NULL; )
  2075. {
  2076. // Ask call if sequence number is theirs
  2077. CCall *pCall = m_Calls.GetNext(pos);
  2078. if (pCall->MatchSeqNum(seqNum))
  2079. {
  2080. RetVal = pCall;
  2081. break;
  2082. }
  2083. }
  2084. return(RetVal);
  2085. }
  2086. //
  2087. // FindCallByCRV()
  2088. //
  2089. // ABSTRACT:
  2090. // This function attempts to locate a call within the list of calls
  2091. // in the registration object that is associated with the passed in
  2092. // CallReferenceValue.
  2093. //
  2094. // RETURNS:
  2095. // Pointer to call associated with the CRV or
  2096. // NULL if no call is found.
  2097. //
  2098. // NOTES:
  2099. // This function is usually called by the CRegistration::PDUHandler()
  2100. // when it receives a reply message that needs to be associated with a
  2101. // particular call.
  2102. //
  2103. // AUTHOR: Dan Dexter
  2104. CCall *
  2105. CRegistration::FindCallByCRV(CallReferenceValue crv)
  2106. {
  2107. // If there are no calls, we can just return now
  2108. if (m_Calls.IsEmpty())
  2109. return(NULL);
  2110. // Initialize return value to "call not found"
  2111. CCall *RetVal = NULL;
  2112. // Otherwise, iterate through the calls and ask them
  2113. // if this CRV number belongs to them
  2114. POS pos;
  2115. for( pos = m_Calls.GetFirstPos(); pos != NULL; )
  2116. {
  2117. // Ask call if sequence number is theirs
  2118. CCall *pCall = m_Calls.GetNext(pos);
  2119. if (pCall->MatchCRV(crv))
  2120. {
  2121. RetVal = pCall;
  2122. break;
  2123. }
  2124. }
  2125. return(RetVal);
  2126. }
  2127. void
  2128. CRegistration::DeleteCall(CCall *pCall)
  2129. {
  2130. #ifdef _DEBUG
  2131. char szGKDebug[80];
  2132. #endif
  2133. POS pos = m_Calls.Find(pCall);
  2134. // We don't expect to be asked to delete
  2135. // calls that aren't in the list, so ASSERT
  2136. ASSERT(pos);
  2137. if (pos)
  2138. {
  2139. CCall *pCallObject = m_Calls.GetAt(pos);
  2140. m_Calls.RemoveAt(pos);
  2141. SPIDER_TRACE(SP_NEWDEL, "del pCallObject = %X\n", pCallObject);
  2142. delete pCallObject;
  2143. }
  2144. }
  2145. void
  2146. CRegistration::AddCall(CCall *pCall)
  2147. {
  2148. m_Calls.AddTail(pCall);
  2149. }
  2150. CCall *
  2151. CRegistration::GetNextCall(CCall *pCall)
  2152. {
  2153. CCall *RetVal = NULL;
  2154. if (pCall)
  2155. {
  2156. // The call list should never be empty
  2157. // if we're called with a non-NULL call pointer
  2158. ASSERT(!m_Calls.IsEmpty());
  2159. POS pos = m_Calls.Find(pCall);
  2160. // The call passed in better have been found
  2161. ASSERT(pos);
  2162. if (pos)
  2163. {
  2164. // This actually gets the existing call, but sets
  2165. // pos to point to the next call.
  2166. CCall *pNextCall = m_Calls.GetNext(pos);
  2167. if (pos)
  2168. {
  2169. // This call sets up the return value
  2170. RetVal = m_Calls.GetAt(pos);
  2171. }
  2172. }
  2173. }
  2174. return(RetVal);
  2175. }
  2176. #if 0
  2177. void
  2178. CRegistration::Lock(void)
  2179. {
  2180. EnterCriticalSection(&m_CriticalSection);
  2181. m_dwLockingThread = GetCurrentThreadId();
  2182. }
  2183. void
  2184. CRegistration::Unlock(void)
  2185. {
  2186. // Assert that the unlock is done by the
  2187. // thread that holds the lock
  2188. ASSERT(m_dwLockingThread == GetCurrentThreadId());
  2189. m_dwLockingThread = 0;
  2190. LeaveCriticalSection(&m_CriticalSection);
  2191. }
  2192. #endif
  2193.