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.

1335 lines
36 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_APP_ROSTER);
  3. /*
  4. * arostmgr.cpp
  5. *
  6. * Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
  7. *
  8. * Abstract:
  9. * This is the implementation file for the Application Roster
  10. * Manager Class.
  11. *
  12. * SEE THE INTERFACE FILE FOR A MORE DETAILED DESCRIPION OF THIS CLASS.
  13. *
  14. * Private Instance Variables
  15. * m_nConfID
  16. * The conference ID associated with this roster manager. Used
  17. * when delivering roster update messages.
  18. * m_fTopProvider
  19. * Flag indicating if this is a top provider node for this conference.
  20. * m_pMcsUserObject
  21. * This is the user attachment object associated with this conference.
  22. * m_AppSapEidList2
  23. * This list maintains all of the command target pointers for each
  24. * of the enrolled APEs. This list is used to deliver roster
  25. * update messages.
  26. * m_pConf
  27. * Pointer to object that will receive all owner callback messages
  28. * delivered from the application roster manager.
  29. * m_GlobalRosterList
  30. * This list maintains pointers to all the global application rosters.
  31. * m_LocalRosterList
  32. * This list maintains pointers to all the local application rosters.
  33. * This list will not be used if this is a Top Provider node.
  34. * m_RosterDeleteList
  35. * This list is used to hold any application rosters that have
  36. * been marked to be deleted (usually when they become empty). We
  37. * don't delete immediately to allow messages and PDUs to be processed
  38. * before deletion.
  39. * m_pSessionKey
  40. * This is the session key used to hold the protocol key associated
  41. * with this application roster manager.
  42. *
  43. * Caveats:
  44. * None
  45. *
  46. * Author:
  47. * blp
  48. */
  49. #include "arostmgr.h"
  50. #include "arostmsg.h"
  51. #include "appsap.h"
  52. #include "csap.h"
  53. #include "conf.h"
  54. /*
  55. * CAppRosterMgr ()
  56. *
  57. * Public Function Description
  58. * when pGccSessKey is not NULL
  59. * This is the application roster manager constructor. It is responsible
  60. * for initializing all the instance variables used by this class.
  61. * This constructor is used when the initial roster data that is
  62. * availble comes from local API data.
  63. *
  64. * when pSessKey is not NULL
  65. * This is the application roster manager constructor. It is responsible
  66. * for initializing all the instance variables used by this class.
  67. * This constructor is used when the initial roster data that is
  68. * availble comes from remote PDU data.
  69. * This constructor handles a number of different possiblities:
  70. * For Non Top Providers:
  71. * 1) A refresh received from the top provider.
  72. * 2) An update from a node below this one.
  73. *
  74. * For the Top Provider:
  75. * 1) An Update from a lower node
  76. */
  77. CAppRosterMgr::CAppRosterMgr(
  78. PGCCSessionKey pGccSessKey,
  79. PSessionKey pPduSessKey,
  80. GCCConfID nConfID,
  81. PMCSUser pMcsUserObject,
  82. CConf *pConf,
  83. PGCCError pRetCode)
  84. :
  85. CRefCount(MAKE_STAMP_ID('A','R','M','r')),
  86. m_nConfID(nConfID),
  87. // m_fTopProvider(FALSE),
  88. m_pMcsUserObject(pMcsUserObject),
  89. m_AppSapEidList2(DESIRED_MAX_APP_SAP_ITEMS),
  90. m_pConf(pConf)
  91. {
  92. GCCError rc = GCC_NO_ERROR;
  93. DebugEntry(CAppRosterMgr::CAppRosterMgr);
  94. // Determine if this is a top provider node
  95. m_fTopProvider = (m_pMcsUserObject->GetTopNodeID() == m_pMcsUserObject->GetMyNodeID());
  96. /*
  97. ** Set up this roster managers session key which will be used to
  98. ** determine whether or not to process a roster request or update.
  99. */
  100. if (NULL != pGccSessKey)
  101. {
  102. ASSERT(NULL == pPduSessKey);
  103. DBG_SAVE_FILE_LINE
  104. m_pSessionKey = new CSessKeyContainer(pGccSessKey, &rc);
  105. }
  106. else
  107. if (NULL != pPduSessKey)
  108. {
  109. DBG_SAVE_FILE_LINE
  110. m_pSessionKey = new CSessKeyContainer(pPduSessKey, &rc);
  111. }
  112. else
  113. {
  114. ERROR_OUT(("CAppRosterMgr::CAppRosterMgr: invalid session key"));
  115. rc = GCC_BAD_SESSION_KEY;
  116. goto MyExit;
  117. }
  118. if (NULL == m_pSessionKey || GCC_NO_ERROR != rc)
  119. {
  120. ERROR_OUT(("CAppRosterMgr::CAppRosterMgr: can't create session key"));
  121. rc = GCC_ALLOCATION_FAILURE;
  122. // we do the cleanup in the destructor
  123. goto MyExit;
  124. }
  125. ASSERT(GCC_NO_ERROR == rc);
  126. MyExit:
  127. DebugExitINT(CAppRosterMgr:;CAppRosterMgr, rc);
  128. *pRetCode = rc;
  129. }
  130. /*
  131. * ~CAppRosterMgr()
  132. *
  133. * Public Function Description
  134. * This is the application roster manager destructor. It is used to
  135. * free up all memory associated with this class.
  136. */
  137. CAppRosterMgr::~CAppRosterMgr(void)
  138. {
  139. m_GlobalRosterList.DeleteList();
  140. m_LocalRosterList.DeleteList();
  141. m_RosterDeleteList.DeleteList();
  142. if (NULL != m_pSessionKey)
  143. {
  144. m_pSessionKey->Release();
  145. }
  146. }
  147. /*
  148. * GCCError EnrollRequest ()
  149. *
  150. * Public Function Description
  151. * This routine is called whenever an APE wishes to enroll with the
  152. * conference in a specific session. This routine can be used to
  153. * either add a new record or replace a currently existing record.
  154. */
  155. GCCError CAppRosterMgr::
  156. EnrollRequest(GCCEnrollRequest *pReq, GCCEntityID eid, GCCNodeID nid, CAppSap *pAppSap)
  157. {
  158. GCCError rc = GCC_NO_ERROR;
  159. CAppRoster *pAppRoster = NULL;
  160. BOOL perform_add_record;
  161. BOOL maintain_pdu_data;
  162. DebugEntry(CAppRosterMgr::EnrollRequest);
  163. /*
  164. ** First we must make sure that the default version of this session
  165. ** key matches this application roster manager's
  166. */
  167. if (! IsThisSessionKeyValid(pReq->pSessionKey))
  168. {
  169. rc = GCC_BAD_SESSION_KEY;
  170. goto MyExit;
  171. }
  172. // Now save the App SAP so we can send roster report indications
  173. if (! m_AppSapEidList2.Find(eid))
  174. {
  175. m_AppSapEidList2.Append(eid, pAppSap);
  176. perform_add_record = TRUE;
  177. }
  178. else
  179. {
  180. perform_add_record = FALSE;
  181. }
  182. /*
  183. ** Next we must make sure that the global application roster (and
  184. ** local for non top providers) that matches this session key exist.
  185. ** If they don't exists then create them here.
  186. */
  187. pAppRoster = GetApplicationRoster(pReq->pSessionKey, &m_GlobalRosterList);
  188. if (pAppRoster == NULL)
  189. {
  190. maintain_pdu_data = m_fTopProvider;
  191. /*
  192. ** Here we create the global default application rosters. If
  193. ** this is the Top Provider we DO maintain PDU data within the
  194. ** roster.
  195. */
  196. DBG_SAVE_FILE_LINE
  197. pAppRoster = new CAppRoster(pReq->pSessionKey,
  198. NULL, // pSessKey
  199. this, // pOwnerObject
  200. m_fTopProvider,// fTopProvider
  201. FALSE, // fLocalRoster
  202. maintain_pdu_data, // fMaintainPduBuffer
  203. &rc);
  204. if ((pAppRoster != NULL) && (rc == GCC_NO_ERROR))
  205. {
  206. m_GlobalRosterList.Append(pAppRoster);
  207. }
  208. else
  209. {
  210. rc = GCC_ALLOCATION_FAILURE;
  211. goto MyExit;
  212. }
  213. }
  214. if (! m_fTopProvider)
  215. {
  216. pAppRoster = GetApplicationRoster(pReq->pSessionKey, &m_LocalRosterList);
  217. if (pAppRoster == NULL)
  218. {
  219. // Here we create the local default application rosters.
  220. DBG_SAVE_FILE_LINE
  221. pAppRoster = new CAppRoster(pReq->pSessionKey,
  222. NULL, // pSessKey
  223. this, // pOwnerObject
  224. m_fTopProvider,// fTopProvider
  225. TRUE, // fLocalRoster
  226. TRUE, // fMaintainPduBuffer
  227. &rc);
  228. if ((pAppRoster != NULL) && (rc == GCC_NO_ERROR))
  229. {
  230. m_LocalRosterList.Append(pAppRoster);
  231. }
  232. else
  233. {
  234. rc = GCC_ALLOCATION_FAILURE;
  235. goto MyExit;
  236. }
  237. }
  238. }
  239. //
  240. // LONCHANC: Something wrong here. roster_ptr could be either
  241. // the one in the global list or the one in the local list.
  242. // Should we add records to both roster_ptr???
  243. //
  244. // LONCHANC: It seems to me that only the local list has records in non-top provider.
  245. // On the other hand, only the global list has the record in top provider.
  246. // cf. UnEnrollRequest().
  247. //
  248. if (perform_add_record)
  249. {
  250. // Add the new record to the roster
  251. rc = pAppRoster->AddRecord(pReq, nid, eid);
  252. if (GCC_NO_ERROR != rc)
  253. {
  254. ERROR_OUT(("AppRosterManager::EnrollRequest: can't add record"));
  255. }
  256. }
  257. else
  258. {
  259. rc = pAppRoster->ReplaceRecord(pReq, nid, eid);
  260. if (GCC_NO_ERROR != rc)
  261. {
  262. ERROR_OUT(("AppRosterManager::EnrollRequest: can't repalce record"));
  263. }
  264. }
  265. // zero out the roster pointer because it should no be freed
  266. // in case of adding or replacing a record.
  267. // because the roster pointer has been added to the list,
  268. // it will be freed later.
  269. pAppRoster = NULL;
  270. MyExit:
  271. if (GCC_NO_ERROR != rc)
  272. {
  273. if (pAppRoster != NULL)
  274. {
  275. pAppRoster->Release();
  276. }
  277. }
  278. DebugExitINT(CAppRosterMgr::EnrollRequest, rc);
  279. return rc;
  280. }
  281. /*
  282. * GCCError UnEnrollRequest ()
  283. *
  284. * Public Function Description
  285. * This routine is called whenever an APE wishes to unenroll from the
  286. * conference (or a specific session).
  287. */
  288. GCCError CAppRosterMgr::UnEnrollRequest (
  289. PGCCSessionKey session_key,
  290. EntityID entity_id)
  291. {
  292. GCCError rc = GCC_NO_ERROR;
  293. CAppRoster *application_roster = NULL;
  294. CAppRosterList *roster_list;
  295. DebugEntry(CAppRosterMgr::UnEnrollRequest);
  296. // Is this a valid session key for the application roster manager
  297. if (IsThisSessionKeyValid (session_key) == FALSE)
  298. rc = GCC_INVALID_PARAMETER;
  299. else if (m_AppSapEidList2.Remove(entity_id))
  300. {
  301. // Now find the affected roster
  302. roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
  303. application_roster = GetApplicationRoster ( session_key, roster_list);
  304. // Now unenroll from the specified roster
  305. if (application_roster != NULL)
  306. {
  307. rc = application_roster->RemoveRecord(
  308. m_pMcsUserObject->GetMyNodeID(),
  309. entity_id);
  310. }
  311. else
  312. rc = GCC_BAD_SESSION_KEY;
  313. }
  314. else
  315. rc = GCC_APP_NOT_ENROLLED;
  316. DebugExitINT(CAppRosterMgr::UnEnrollRequest, rc);
  317. return rc;
  318. }
  319. /*
  320. * GCCError ProcessRosterUpdateIndicationPDU ()
  321. *
  322. * Public Function Description
  323. * This routine processes an incomming roster update PDU. It is
  324. * responsible for passing the PDU on to the right application roster.
  325. */
  326. GCCError CAppRosterMgr::ProcessRosterUpdateIndicationPDU(
  327. PSetOfApplicationInformation set_of_application_info,
  328. UserID sender_id)
  329. {
  330. GCCError rc = GCC_NO_ERROR;
  331. CAppRosterList *roster_list;
  332. CAppRoster *application_roster;
  333. BOOL maintain_pdu_buffer;
  334. BOOL is_local_roster;
  335. DebugEntry(CAppRosterMgr::ProcessRosterUpdateIndicationPDU);
  336. /*
  337. ** First make sure that the session key contained in the current
  338. ** set of application information is valid for this application roster
  339. ** manager.
  340. */
  341. if (IsThisSessionKeyPDUValid(&set_of_application_info->value.session_key))
  342. {
  343. /*
  344. ** Now search for the appropriate application roster. If it is not
  345. ** found we must create it here.
  346. */
  347. //
  348. // LONCHANC:
  349. // (1) If top provider, add default application roster to the global roster list.
  350. // (2) If non-top provider, we do not create both the local and global version of the
  351. // application roster for this particular session key.
  352. // instead, We create only the appropriate one here
  353. // and wait until we receive either a refresh from the
  354. // top provider or an update from a node below this one
  355. // in the connection hierarchy (or an application
  356. // enroll) before creating the other.
  357. // (3) If this PDU was sent from below this node it
  358. // must be an update of the local roster so save
  359. // the roster in the local roster list.
  360. //
  361. roster_list = (m_fTopProvider || (sender_id == m_pMcsUserObject->GetTopNodeID())) ?
  362. &m_GlobalRosterList : &m_LocalRosterList;
  363. application_roster = GetApplicationRosterFromPDU (
  364. &set_of_application_info->value.session_key,
  365. roster_list);
  366. if (application_roster != NULL)
  367. {
  368. rc = application_roster->
  369. ProcessRosterUpdateIndicationPDU(
  370. set_of_application_info,
  371. sender_id);
  372. }
  373. else
  374. {
  375. // First determine the characteristics of this roster
  376. if (m_fTopProvider)
  377. {
  378. maintain_pdu_buffer = TRUE;
  379. is_local_roster = FALSE;
  380. }
  381. else if (sender_id == m_pMcsUserObject->GetTopNodeID())
  382. {
  383. maintain_pdu_buffer = FALSE;
  384. is_local_roster = FALSE;
  385. }
  386. else
  387. {
  388. maintain_pdu_buffer = TRUE;
  389. is_local_roster = TRUE;
  390. }
  391. // Create the application roster from the passed in PDU.
  392. DBG_SAVE_FILE_LINE
  393. application_roster = new CAppRoster(NULL, // pGccSessKey
  394. &set_of_application_info->value.session_key, // pSessKey
  395. this, // pOwnerObject
  396. m_fTopProvider,// fTopProvider
  397. is_local_roster,// fLocalRoster
  398. maintain_pdu_buffer,// fMaintainPduBuffer
  399. &rc);
  400. if ((application_roster != NULL) && (rc == GCC_NO_ERROR))
  401. {
  402. // Process the PDU with the created application roster.
  403. rc = application_roster->
  404. ProcessRosterUpdateIndicationPDU(
  405. set_of_application_info,
  406. sender_id);
  407. if (rc == GCC_NO_ERROR)
  408. {
  409. roster_list->Append(application_roster);
  410. }
  411. }
  412. else
  413. {
  414. if (application_roster != NULL)
  415. {
  416. application_roster->Release();
  417. }
  418. else
  419. {
  420. rc = GCC_ALLOCATION_FAILURE;
  421. }
  422. }
  423. }
  424. }
  425. else
  426. {
  427. ERROR_OUT(("AppRosterManager::ProcessRosterUpdateIndicationPDU:"
  428. "ASSERTION: Application Information is not valid"));
  429. rc = GCC_INVALID_PARAMETER;
  430. }
  431. DebugExitINT(CAppRosterMgr::ProcessRosterUpdateIndicationPDU, rc);
  432. return rc;
  433. }
  434. /*
  435. * PSetOfApplicationInformation FlushRosterUpdateIndication ()
  436. *
  437. * Public Function Description
  438. * This routine is used to access any PDU data that might currently be
  439. * queued inside the application rosters managed by this application
  440. * roster manager. It also is responsible for flushing any queued
  441. * roster update messages if necessary.
  442. */
  443. PSetOfApplicationInformation
  444. CAppRosterMgr::FlushRosterUpdateIndication(
  445. PSetOfApplicationInformation * set_of_information,
  446. PGCCError rc)
  447. {
  448. PSetOfApplicationInformation pOld = NULL, pCurr;
  449. CAppRosterList *roster_list;
  450. CAppRoster *lpAppRoster;
  451. DebugEntry(CAppRosterMgr::FlushRosterUpdateIndication);
  452. /*
  453. ** First we deal with flushing the PDU data. We iterate through the
  454. ** appropriate list (Global if the Top Provider and Local if not the
  455. ** Top Provider) and get any PDU data associated with each of these.
  456. ** Note that some of these may not contain any PDU data.
  457. */
  458. *rc = GCC_NO_ERROR;
  459. *set_of_information = NULL;
  460. roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
  461. roster_list->Reset();
  462. while (NULL != (lpAppRoster = roster_list->Iterate()))
  463. {
  464. lpAppRoster->FlushRosterUpdateIndicationPDU(&pCurr);
  465. if (pCurr != NULL)
  466. {
  467. if (*set_of_information == NULL)
  468. *set_of_information = pCurr;
  469. else
  470. {
  471. if(pOld)
  472. {
  473. pOld->next = pCurr;
  474. }
  475. }
  476. (pOld = pCurr)->next = NULL;
  477. }
  478. }
  479. /*
  480. ** Next we deal with delivering the application roster update messages.
  481. ** We first check to see if any of the global rosters have changed. If
  482. ** none have changed, we will not deliver a roster update indication.
  483. */
  484. m_GlobalRosterList.Reset();
  485. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  486. {
  487. if (lpAppRoster->HasRosterChanged())
  488. {
  489. TRACE_OUT(("AppRosterManager::FlushRosterUpdateIndication:Roster HAS Changed"));
  490. *rc = SendRosterReportMessage ();
  491. break;
  492. }
  493. }
  494. /*
  495. ** Cleanup and reset any application rosters after the above flush is
  496. ** completed. This takes care of removing any rosters that have become
  497. ** empty. It also resets the rosters which takes care of resetting all
  498. ** the internal instance variables to their appropriate initial state.
  499. */
  500. CleanupApplicationRosterLists ();
  501. DebugExitPTR(CAppRosterMgr::FlushRosterUpdateIndication, pOld);
  502. //
  503. // LONCHANC: Yes, we need to return the last item in the list such that
  504. // we can continue to grow the list.
  505. // In fact, the next call to FlushRosterUpdateIndication() will have
  506. // &pOld as the input argument.
  507. // It is quite tricky.
  508. //
  509. // Please note that pOld is initialized to NULL.
  510. //
  511. return (pOld);
  512. }
  513. /*
  514. * PSetOfApplicationInformation GetFullRosterRefreshPDU ()
  515. *
  516. * Public Function Description
  517. * This routine is used to obtain a complete roster refresh of all the
  518. * rosters maintained by this roster manger.
  519. */
  520. PSetOfApplicationInformation
  521. CAppRosterMgr::GetFullRosterRefreshPDU (
  522. PSetOfApplicationInformation * set_of_information,
  523. PGCCError rc)
  524. {
  525. PSetOfApplicationInformation new_set_of_information = NULL;
  526. DebugEntry(CAppRosterMgr::GetFullRosterRefreshPDU);
  527. if (m_fTopProvider)
  528. {
  529. CAppRoster *lpAppRoster;
  530. *rc = GCC_NO_ERROR;
  531. *set_of_information = NULL;
  532. /*
  533. ** First we must tell all the application rosters to build the
  534. ** a full refresh PDU internally.
  535. */
  536. m_GlobalRosterList.Reset();
  537. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  538. {
  539. *rc = lpAppRoster->BuildFullRefreshPDU();
  540. if (GCC_NO_ERROR != *rc)
  541. {
  542. return NULL;
  543. }
  544. }
  545. /*
  546. ** Now we flush all the refreshes. Note that this also takes care
  547. ** of delivering any queued application roster update messages.
  548. */
  549. new_set_of_information = FlushRosterUpdateIndication (set_of_information, rc);
  550. }
  551. else
  552. *rc = GCC_INVALID_PARAMETER;
  553. DebugExitPTR(CAppRosterMgr::GetFullRosterRefreshPDU, new_set_of_information);
  554. return (new_set_of_information);
  555. }
  556. /*
  557. * Boolean IsThisYourSessionKey ()
  558. *
  559. * Public Function Description
  560. * This routine is used to determine if the specified "API" session key is
  561. * associated with this application roster manager.
  562. */
  563. /*
  564. * Boolean IsThisYourSessionKeyPDU ()
  565. *
  566. * Public Function Description
  567. * This routine is used to determine if the specified "PDU" session key is
  568. * associated with this application roster manager.
  569. */
  570. /*
  571. * GCCError RemoveEntityReference ()
  572. *
  573. * Public Function Description
  574. * This routine is used to remove the specified APE entity from the
  575. * session it is enrolled with. Note that this routine is only used
  576. * to remove local entity references.
  577. */
  578. GCCError CAppRosterMgr::RemoveEntityReference(EntityID entity_id)
  579. {
  580. GCCError rc = GCC_NO_ERROR;
  581. CAppRosterList *roster_list;
  582. DebugEntry(CAppRosterMgr::RemoveEntityReference);
  583. /*
  584. ** First remove this entity from the command target list if it is valid.
  585. ** We then iterate through all the rosters until we determine which
  586. ** roster holds the record associated with this entity.
  587. */
  588. if (m_AppSapEidList2.Remove(entity_id))
  589. {
  590. CAppRoster *lpAppRoster;
  591. /*
  592. ** Now get the affected roster. Note that if this is not the
  593. ** top provider we wait for the full refresh to update the
  594. ** global roster.
  595. */
  596. roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
  597. /*
  598. ** Try to delete this record from every roster in the list.
  599. ** Break when the correct roster is found.
  600. */
  601. roster_list->Reset();
  602. while (NULL != (lpAppRoster = roster_list->Iterate()))
  603. {
  604. rc = lpAppRoster->RemoveRecord(m_pMcsUserObject->GetMyNodeID(), entity_id);
  605. if (rc == GCC_NO_ERROR)
  606. break;
  607. }
  608. }
  609. else
  610. rc = GCC_APP_NOT_ENROLLED;
  611. DebugExitINT(CAppRosterMgr::RemoveEntityReference, rc);
  612. return rc;
  613. }
  614. /*
  615. * GCCError RemoveUserReference ()
  616. *
  617. * Public Function Description
  618. * This routine is used to remove all references associated with the
  619. * node defined by the detached user.
  620. */
  621. GCCError CAppRosterMgr::RemoveUserReference(
  622. UserID detached_user)
  623. {
  624. GCCError rc = GCC_NO_ERROR;
  625. GCCError error_value;
  626. CAppRosterList *roster_list;
  627. CAppRoster *lpAppRoster;
  628. DebugEntry(CAppRosterMgr::RemoveUserReference);
  629. /*
  630. ** Now get the affected roster. Note that if this is not the
  631. ** top provider we wait for the full refresh to update the
  632. ** global roster.
  633. */
  634. roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
  635. // Try to delete this user from every roster in the list
  636. roster_list->Reset();
  637. while (NULL != (lpAppRoster = roster_list->Iterate()))
  638. {
  639. error_value = lpAppRoster->RemoveUserReference (detached_user);
  640. if ((error_value != GCC_NO_ERROR) &&
  641. (error_value != GCC_INVALID_PARAMETER))
  642. {
  643. rc = error_value;
  644. WARNING_OUT(("AppRosterManager::RemoveUserReference:"
  645. "FATAL error occured while removing user reference."));
  646. break;
  647. }
  648. }
  649. DebugExitINT(CAppRosterMgr::RemoveUserReference, rc);
  650. return rc;
  651. }
  652. /*
  653. * Boolean IsEntityEnrolled ()
  654. *
  655. * Public Function Description
  656. * This routine informs the caller if the specified entity is enrolled
  657. * with any sessions managed by this application roster manager.
  658. */
  659. BOOL CAppRosterMgr::IsEntityEnrolled(EntityID application_entity)
  660. {
  661. BOOL rc = TRUE;
  662. CAppRosterList *application_roster_list;
  663. CAppRoster *lpAppRoster;
  664. DebugEntry(CAppRosterMgr::IsEntityEnrolled);
  665. application_roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
  666. application_roster_list->Reset();
  667. while (NULL != (lpAppRoster = application_roster_list->Iterate()))
  668. {
  669. if (lpAppRoster->DoesRecordExist(m_pMcsUserObject->GetMyNodeID(), application_entity))
  670. {
  671. rc = TRUE;
  672. break;
  673. }
  674. }
  675. DebugExitBOOL(AppRosterManager:IsEntityEnrolled, rc);
  676. return rc;
  677. }
  678. /*
  679. * GCCError ApplicationRosterInquire ()
  680. *
  681. * Public Function Description
  682. * This routine fills in an application roster message with either
  683. * a single roster (if a session other than the default is specified)
  684. * or the complete list of "Global" rosters contained by this roster
  685. * manager (if the specified session key is NULL or the session ID is
  686. * zero.
  687. */
  688. GCCError CAppRosterMgr::ApplicationRosterInquire (
  689. PGCCSessionKey session_key,
  690. CAppRosterMsg *roster_message)
  691. {
  692. GCCError rc = GCC_NO_ERROR;
  693. CAppRoster *application_roster = NULL;
  694. CSessKeyContainer *pSessKeyData;
  695. DebugEntry(CAppRosterMgr::ApplicationRosterInquire);
  696. if (session_key != NULL)
  697. {
  698. if (session_key->session_id != 0)
  699. {
  700. /*
  701. ** Here we try to find the specific application roster that was
  702. ** requested.
  703. */
  704. DBG_SAVE_FILE_LINE
  705. pSessKeyData = new CSessKeyContainer(session_key, &rc);
  706. if ((pSessKeyData != NULL) && (rc == GCC_NO_ERROR))
  707. {
  708. CAppRoster *lpAppRoster;
  709. m_GlobalRosterList.Reset();
  710. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  711. {
  712. CSessKeyContainer *pTempSessKeyData = lpAppRoster->GetSessionKey();
  713. if (*pTempSessKeyData == *pSessKeyData)
  714. {
  715. application_roster = lpAppRoster;
  716. break;
  717. }
  718. }
  719. }
  720. if (pSessKeyData != NULL)
  721. {
  722. pSessKeyData->Release();
  723. if (application_roster == NULL)
  724. {
  725. rc = GCC_NO_SUCH_APPLICATION;
  726. }
  727. }
  728. else
  729. {
  730. rc = GCC_ALLOCATION_FAILURE;
  731. }
  732. }
  733. }
  734. if (rc == GCC_NO_ERROR)
  735. {
  736. if (application_roster != NULL)
  737. {
  738. roster_message->AddRosterToMessage(application_roster);
  739. }
  740. else
  741. {
  742. CAppRoster *lpAppRoster;
  743. m_GlobalRosterList.Reset();
  744. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  745. {
  746. roster_message->AddRosterToMessage(lpAppRoster);
  747. }
  748. }
  749. }
  750. DebugExitINT(AppRosterManager:ApplicationRosterInquire, rc);
  751. return rc;
  752. }
  753. /*
  754. * BOOL IsAPEEnrolled ()
  755. *
  756. * Public Function Description
  757. * This function determines if the specified APE is enrolled with
  758. * any session in the list. It does not worry about a specific
  759. * session.
  760. */
  761. BOOL CAppRosterMgr::IsAPEEnrolled(
  762. UserID node_id,
  763. EntityID entity_id)
  764. {
  765. BOOL rc = FALSE;
  766. CAppRoster *lpAppRoster;
  767. DebugEntry(CAppRosterMgr::IsAPEEnrolled);
  768. /*
  769. ** First get a single session key. Note that it makes no difference
  770. ** where the key comes from because we are only goin to be comparing
  771. ** the base object key.
  772. */
  773. m_GlobalRosterList.Reset();
  774. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  775. {
  776. if (lpAppRoster->DoesRecordExist (node_id, entity_id))
  777. {
  778. rc = TRUE;
  779. break;
  780. }
  781. }
  782. DebugExitBOOL(AppRosterManager:IsAPEEnrolled, rc);
  783. return rc;
  784. }
  785. /*
  786. * BOOL IsAPEEnrolled ()
  787. *
  788. * Public Function Description
  789. * This function determines if the specified APE is enrolled with
  790. * a specific session in the list.
  791. */
  792. BOOL CAppRosterMgr::IsAPEEnrolled(
  793. CSessKeyContainer *session_key_data,
  794. UserID node_id,
  795. EntityID entity_id)
  796. {
  797. BOOL rc = FALSE;
  798. CAppRoster *lpAppRoster;
  799. DebugEntry(CAppRosterMgr::IsAPEEnrolled);
  800. /*
  801. ** First get a single session key. Note that it makes no difference
  802. ** where the key comes from because we are only goin to be comparing
  803. ** the base object key.
  804. */
  805. m_GlobalRosterList.Reset();
  806. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  807. {
  808. // We are looking for a session key match
  809. if (*(lpAppRoster->GetSessionKey()) == *session_key_data)
  810. {
  811. // If a match was found check to see if record exist
  812. rc = lpAppRoster->DoesRecordExist (node_id, entity_id);
  813. }
  814. }
  815. DebugExitBOOL(AppRosterManager:IsAPEEnrolled, rc);
  816. return rc;
  817. }
  818. /*
  819. * GCCError IsEmpty ()
  820. *
  821. * Public Function Description
  822. * This routine determines if this application roster managfer contains
  823. * any application rosters.
  824. */
  825. BOOL CAppRosterMgr::IsEmpty(void)
  826. {
  827. return (m_GlobalRosterList.IsEmpty() && m_LocalRosterList.IsEmpty()) ?
  828. TRUE : FALSE;
  829. }
  830. /*
  831. * GCCError SendRosterReportMessage ()
  832. *
  833. * Private Function Description
  834. * This routine is responsible for sending the application roster
  835. * update indications to the application SAPs.
  836. *
  837. * Formal Parameters:
  838. * None.
  839. *
  840. * Return Value
  841. * GCC_NO_ERROR - No error occured.
  842. * GCC_ALLOCATION_FAILURE - A resource error occured.
  843. *
  844. * Side Effects
  845. * None.
  846. *
  847. * Caveats:
  848. * We send indications for all rosters. Even roster that don't currently
  849. * contain records.
  850. */
  851. GCCError CAppRosterMgr::
  852. SendRosterReportMessage(void)
  853. {
  854. GCCError rc = GCC_NO_ERROR;
  855. CAppRosterMsg *roster_message;
  856. DebugEntry(CAppRosterMgr::SendRosterReportMessage);
  857. if (! m_GlobalRosterList.IsEmpty())
  858. {
  859. // First allocate the roster message
  860. DBG_SAVE_FILE_LINE
  861. roster_message = new CAppRosterMsg();
  862. if (roster_message != NULL)
  863. {
  864. CAppRoster *lpAppRoster;
  865. m_GlobalRosterList.Reset();
  866. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  867. {
  868. roster_message->AddRosterToMessage(lpAppRoster);
  869. }
  870. /*
  871. ** Here we iterate through the complete list of application
  872. ** saps to send the roster report indication. Note that
  873. ** we used the sent list to avoid sending the same roster
  874. ** update to a single SAP more than once. Note that since
  875. ** this sent list is defined as a local instance variable,
  876. ** it automatically is cleaned up after each roster update.
  877. **
  878. ** Note also that we iterate on a temporary list here in case
  879. ** an application unenrolls (usually due to a resource error)
  880. ** during this callback. We must protect the rogue wave
  881. ** iterator.
  882. */
  883. CAppSap *pAppSap;
  884. CAppSapList SentList;
  885. CAppSapEidList2 ToSendList(m_AppSapEidList2);
  886. ToSendList.Reset();
  887. while (NULL != (pAppSap = ToSendList.Iterate()))
  888. {
  889. if (! SentList.Find(pAppSap))
  890. {
  891. /*
  892. ** Hold on to this sap so that we don't send to it
  893. ** again for this update.
  894. */
  895. SentList.Append(pAppSap);
  896. // Here we actually deliver the roster update.
  897. pAppSap->AppRosterReportIndication(m_nConfID, roster_message);
  898. }
  899. }
  900. /*
  901. ** Here we send the roster report indication to the
  902. ** controler sap.
  903. */
  904. g_pControlSap->AppRosterReportIndication(m_nConfID, roster_message);
  905. /*
  906. ** Here we free up the roster message. Note that if this
  907. ** message got locked in the roster report indication calls
  908. ** this free will not delete the roster memory.
  909. */
  910. roster_message->Release();
  911. }
  912. else
  913. rc = GCC_ALLOCATION_FAILURE;
  914. }
  915. DebugExitINT(AppRosterManager::SendRosterReportMessage, rc);
  916. return rc;
  917. }
  918. /*
  919. * CAppRoster *GetApplicationRoster ()
  920. *
  921. * Private Function Description
  922. * This routine is responsible for returning the application pointer
  923. * associated with the specified session key.
  924. *
  925. * Formal Parameters:
  926. * session_key - Session key associated with roster to return.
  927. * roster_list - Roster list to search.
  928. *
  929. * Return Value
  930. * Either NULL if roster does not exists in list or a pointer to
  931. * the appropriate application roster.
  932. *
  933. * Side Effects
  934. * None.
  935. *
  936. * Caveats:
  937. * None.
  938. */
  939. CAppRoster * CAppRosterMgr::GetApplicationRoster (
  940. PGCCSessionKey session_key,
  941. CAppRosterList *roster_list)
  942. {
  943. GCCError rc;
  944. CAppRoster *application_roster = NULL;
  945. CAppRoster *lpAppRoster;
  946. CSessKeyContainer *pTempSessKeyData;
  947. DebugEntry(CAppRosterMgr::GetApplicationRoster);
  948. // First create a temporary session key for comparison purposes
  949. DBG_SAVE_FILE_LINE
  950. pTempSessKeyData = new CSessKeyContainer(session_key, &rc);
  951. if (pTempSessKeyData != NULL && GCC_NO_ERROR == rc)
  952. {
  953. // Now find the affected roster
  954. //
  955. // LONCHANC: The following line is totally wrong!!!
  956. // we passed in roster_list, but now we overwrite it right here???
  957. // Commented out the following line.
  958. // roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
  959. //
  960. roster_list->Reset();
  961. while (NULL != (lpAppRoster = roster_list->Iterate()))
  962. {
  963. if(*lpAppRoster->GetSessionKey() == *pTempSessKeyData)
  964. {
  965. application_roster = lpAppRoster;
  966. break;
  967. }
  968. }
  969. }
  970. if (pTempSessKeyData != NULL)
  971. pTempSessKeyData->Release();
  972. DebugExitPTR(AppRosterManager::GetApplicationRoster, application_roster);
  973. return (application_roster);
  974. }
  975. /*
  976. * CAppRoster * GetApplicationRosterFromPDU ()
  977. *
  978. * Private Function Description
  979. * This routine is responsible for returning the application pointer
  980. * associated with the specified session key PDU.
  981. *
  982. * Formal Parameters:
  983. * session_key - Session key PDU associated with roster to return.
  984. * roster_list - Roster list to search.
  985. *
  986. * Return Value
  987. * Either NULL if roster does not exists in list or a pointer to
  988. * the appropriate application roster.
  989. *
  990. * Side Effects
  991. * None.
  992. *
  993. * Caveats:
  994. * None.
  995. */
  996. CAppRoster * CAppRosterMgr::GetApplicationRosterFromPDU (
  997. PSessionKey session_key,
  998. CAppRosterList *roster_list)
  999. {
  1000. CSessKeyContainer *session_key_data;
  1001. CAppRoster *pAppRoster;
  1002. DebugEntry(CAppRosterMgr::GetApplicationRosterFromPDU);
  1003. roster_list->Reset();
  1004. while (NULL != (pAppRoster = roster_list->Iterate()))
  1005. {
  1006. session_key_data = pAppRoster->GetSessionKey();
  1007. if (session_key_data->IsThisYourSessionKeyPDU (session_key))
  1008. {
  1009. break;
  1010. }
  1011. }
  1012. DebugExitPTR(CAppRosterMgr::GetApplicationRosterFromPDU, pAppRoster);
  1013. return pAppRoster;
  1014. }
  1015. /*
  1016. * BOOL IsThisSessionKeyValid ()
  1017. *
  1018. * Private Function Description
  1019. * This routine is responsible for determining if the specified
  1020. * session key's application protocol key matches this application
  1021. * roster manager's. This routine works on API data.
  1022. *
  1023. * Formal Parameters:
  1024. * session_key - Session key to check.
  1025. *
  1026. * Return Value
  1027. * TRUE - If we have a match.
  1028. * FALSE - If we do NOT have a match.
  1029. *
  1030. * Side Effects
  1031. * None.
  1032. *
  1033. * Caveats:
  1034. * None.
  1035. */
  1036. /*
  1037. * BOOL IsThisSessionKeyPDUValid ()
  1038. *
  1039. * Private Function Description
  1040. * This routine is responsible for determining if the specified
  1041. * session key's application protocol key matches this application
  1042. * roster manager's. This routine works on PDU data.
  1043. *
  1044. * Formal Parameters:
  1045. * session_key - Session key to check.
  1046. *
  1047. * Return Value
  1048. * TRUE - If we have a match.
  1049. * FALSE - If we do NOT have a match.
  1050. *
  1051. * Side Effects
  1052. * None.
  1053. *
  1054. * Caveats:
  1055. * None.
  1056. */
  1057. /*
  1058. * void CleanupApplicationRosterLists ()
  1059. *
  1060. * Private Function Description
  1061. * This routine is responsible for cleaning up any empty application
  1062. * rosters. It also resets all the application rosters back to their
  1063. * neutral state so that any new updates will be handled correctly.
  1064. *
  1065. * Formal Parameters:
  1066. * None.
  1067. *
  1068. * Return Value
  1069. * None.
  1070. *
  1071. * Side Effects
  1072. * An owner callback will occur when the roster becomes empty.
  1073. *
  1074. * Caveats:
  1075. * This routine does not actually delete the empty rosters until it
  1076. * is placed in the delete list. Instead it places the rosters into the
  1077. * list of deleted rosters which causes them to be deleted the next time
  1078. * this routine is called (or when the object is destructed).
  1079. */
  1080. void CAppRosterMgr::CleanupApplicationRosterLists(void)
  1081. {
  1082. CAppRoster *lpAppRoster;
  1083. DebugEntry(CAppRosterMgr::CleanupApplicationRosterLists);
  1084. /*
  1085. ** First we iterate through the list of deleted rosters and delete
  1086. ** each entry in it.
  1087. */
  1088. m_RosterDeleteList.DeleteList();
  1089. /*
  1090. ** Next we iterate through all the rosters and remove any that
  1091. ** contain no application records. Here instead of deleting the
  1092. ** roster we move the roster into the delete list. We cannot do
  1093. ** the delete here because it is possible that PDU data owned by the
  1094. ** roster being deleted may be used after the Flush is called (or
  1095. ** after this routine is called). Therefore, we save it in the delete
  1096. ** list and delete it next time we enter this routine.
  1097. */
  1098. // Start with the Global Application Roster List
  1099. m_GlobalRosterList.Reset();
  1100. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  1101. {
  1102. if (lpAppRoster->GetNumberOfApplicationRecords() == 0)
  1103. {
  1104. //
  1105. // Here we clean up any "dangling" entries in the application
  1106. // registry by removing all the entries that contain the
  1107. // session key associated with the roster that is being deleted.
  1108. // Note that this is only done when a Global roster list is
  1109. //removed.
  1110. //
  1111. CRegistry *pAppReg = m_pConf->GetRegistry();
  1112. pAppReg->RemoveSessionKeyReference(lpAppRoster->GetSessionKey());
  1113. m_GlobalRosterList.Remove(lpAppRoster);
  1114. m_RosterDeleteList.Append(lpAppRoster);
  1115. TRACE_OUT(("AppRosterMgr: Cleanup: Deleting Global Roster"));
  1116. /*
  1117. ** Since you can not delete a list entry while iterating on it
  1118. ** we must reset the iterator every time an entry is removed.
  1119. */
  1120. m_GlobalRosterList.Reset();
  1121. }
  1122. else
  1123. {
  1124. /*
  1125. ** Here we reset the application roster to its neutral state.
  1126. ** This affects the nodes added and nodes removed flags.
  1127. */
  1128. lpAppRoster->ResetApplicationRoster();
  1129. }
  1130. }
  1131. // Next deal with the Local Application Roster List
  1132. if (! m_fTopProvider)
  1133. {
  1134. m_LocalRosterList.Reset();
  1135. while (NULL != (lpAppRoster = m_LocalRosterList.Iterate()))
  1136. {
  1137. if (lpAppRoster->GetNumberOfApplicationRecords() == 0)
  1138. {
  1139. m_LocalRosterList.Remove(lpAppRoster);
  1140. m_RosterDeleteList.Append(lpAppRoster);
  1141. TRACE_OUT(("AppRosterMgr: Cleanup: Deleting Local Roster"));
  1142. /*
  1143. ** Since you can not delete a list entry while iterating on it
  1144. ** we must reset the iterator every time an entry is removed.
  1145. */
  1146. m_LocalRosterList.Reset();
  1147. }
  1148. else
  1149. {
  1150. /*
  1151. ** Here we reset the application roster to its neutral state.
  1152. ** This affects the nodes added and nodes removed flags.
  1153. */
  1154. lpAppRoster->ResetApplicationRoster();
  1155. }
  1156. }
  1157. }
  1158. DebugExitVOID(CAppRosterMgr::CleanupApplicationRosterLists);
  1159. }
  1160. /*
  1161. * void DeleteRosterRecord ()
  1162. *
  1163. * Public Function Description
  1164. * This function overides the base class function and is used to
  1165. * receive all owner callback information from the application
  1166. * rosters owned by this object.
  1167. */
  1168. void CAppRosterMgr::
  1169. DeleteRosterRecord
  1170. (
  1171. GCCNodeID nidRecordToDelete,
  1172. GCCEntityID eidRecordToDelete
  1173. )
  1174. {
  1175. //
  1176. // Here we remove ownership from any registry entries associated
  1177. // with the record that was deleted. Note that since the entity
  1178. // id must be unique for all the APEs at a node (as stated by
  1179. // T.124) there is no need to include the session key to determine
  1180. // which registry entries to clean up.
  1181. //
  1182. CRegistry *pAppReg = m_pConf->GetRegistry();
  1183. pAppReg->RemoveEntityOwnership(nidRecordToDelete, eidRecordToDelete);
  1184. }
  1185. void CAppRosterMgrList::DeleteList(void)
  1186. {
  1187. CAppRosterMgr *pAppRosterMgr;
  1188. while (NULL != (pAppRosterMgr = Get()))
  1189. {
  1190. pAppRosterMgr->Release();
  1191. }
  1192. }