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.

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