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

1329 lines
35 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. pOld->next = pCurr;
  471. (pOld = pCurr)->next = NULL;
  472. }
  473. }
  474. /*
  475. ** Next we deal with delivering the application roster update messages.
  476. ** We first check to see if any of the global rosters have changed. If
  477. ** none have changed, we will not deliver a roster update indication.
  478. */
  479. m_GlobalRosterList.Reset();
  480. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  481. {
  482. if (lpAppRoster->HasRosterChanged())
  483. {
  484. TRACE_OUT(("AppRosterManager::FlushRosterUpdateIndication:Roster HAS Changed"));
  485. *rc = SendRosterReportMessage ();
  486. break;
  487. }
  488. }
  489. /*
  490. ** Cleanup and reset any application rosters after the above flush is
  491. ** completed. This takes care of removing any rosters that have become
  492. ** empty. It also resets the rosters which takes care of resetting all
  493. ** the internal instance variables to their appropriate initial state.
  494. */
  495. CleanupApplicationRosterLists ();
  496. DebugExitPTR(CAppRosterMgr::FlushRosterUpdateIndication, pOld);
  497. //
  498. // LONCHANC: Yes, we need to return the last item in the list such that
  499. // we can continue to grow the list.
  500. // In fact, the next call to FlushRosterUpdateIndication() will have
  501. // &pOld as the input argument.
  502. // It is quite tricky.
  503. //
  504. // Please note that pOld is initialized to NULL.
  505. //
  506. return (pOld);
  507. }
  508. /*
  509. * PSetOfApplicationInformation GetFullRosterRefreshPDU ()
  510. *
  511. * Public Function Description
  512. * This routine is used to obtain a complete roster refresh of all the
  513. * rosters maintained by this roster manger.
  514. */
  515. PSetOfApplicationInformation
  516. CAppRosterMgr::GetFullRosterRefreshPDU (
  517. PSetOfApplicationInformation * set_of_information,
  518. PGCCError rc)
  519. {
  520. PSetOfApplicationInformation new_set_of_information = NULL;
  521. DebugEntry(CAppRosterMgr::GetFullRosterRefreshPDU);
  522. if (m_fTopProvider)
  523. {
  524. CAppRoster *lpAppRoster;
  525. *rc = GCC_NO_ERROR;
  526. *set_of_information = NULL;
  527. /*
  528. ** First we must tell all the application rosters to build the
  529. ** a full refresh PDU internally.
  530. */
  531. m_GlobalRosterList.Reset();
  532. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  533. {
  534. *rc = lpAppRoster->BuildFullRefreshPDU();
  535. if (GCC_NO_ERROR != *rc)
  536. {
  537. return NULL;
  538. }
  539. }
  540. /*
  541. ** Now we flush all the refreshes. Note that this also takes care
  542. ** of delivering any queued application roster update messages.
  543. */
  544. new_set_of_information = FlushRosterUpdateIndication (set_of_information, rc);
  545. }
  546. else
  547. *rc = GCC_INVALID_PARAMETER;
  548. DebugExitPTR(CAppRosterMgr::GetFullRosterRefreshPDU, new_set_of_information);
  549. return (new_set_of_information);
  550. }
  551. /*
  552. * Boolean IsThisYourSessionKey ()
  553. *
  554. * Public Function Description
  555. * This routine is used to determine if the specified "API" session key is
  556. * associated with this application roster manager.
  557. */
  558. /*
  559. * Boolean IsThisYourSessionKeyPDU ()
  560. *
  561. * Public Function Description
  562. * This routine is used to determine if the specified "PDU" session key is
  563. * associated with this application roster manager.
  564. */
  565. /*
  566. * GCCError RemoveEntityReference ()
  567. *
  568. * Public Function Description
  569. * This routine is used to remove the specified APE entity from the
  570. * session it is enrolled with. Note that this routine is only used
  571. * to remove local entity references.
  572. */
  573. GCCError CAppRosterMgr::RemoveEntityReference(EntityID entity_id)
  574. {
  575. GCCError rc = GCC_NO_ERROR;
  576. CAppRosterList *roster_list;
  577. DebugEntry(CAppRosterMgr::RemoveEntityReference);
  578. /*
  579. ** First remove this entity from the command target list if it is valid.
  580. ** We then iterate through all the rosters until we determine which
  581. ** roster holds the record associated with this entity.
  582. */
  583. if (m_AppSapEidList2.Remove(entity_id))
  584. {
  585. CAppRoster *lpAppRoster;
  586. /*
  587. ** Now get the affected roster. Note that if this is not the
  588. ** top provider we wait for the full refresh to update the
  589. ** global roster.
  590. */
  591. roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
  592. /*
  593. ** Try to delete this record from every roster in the list.
  594. ** Break when the correct roster is found.
  595. */
  596. roster_list->Reset();
  597. while (NULL != (lpAppRoster = roster_list->Iterate()))
  598. {
  599. rc = lpAppRoster->RemoveRecord(m_pMcsUserObject->GetMyNodeID(), entity_id);
  600. if (rc == GCC_NO_ERROR)
  601. break;
  602. }
  603. }
  604. else
  605. rc = GCC_APP_NOT_ENROLLED;
  606. DebugExitINT(CAppRosterMgr::RemoveEntityReference, rc);
  607. return rc;
  608. }
  609. /*
  610. * GCCError RemoveUserReference ()
  611. *
  612. * Public Function Description
  613. * This routine is used to remove all references associated with the
  614. * node defined by the detached user.
  615. */
  616. GCCError CAppRosterMgr::RemoveUserReference(
  617. UserID detached_user)
  618. {
  619. GCCError rc = GCC_NO_ERROR;
  620. GCCError error_value;
  621. CAppRosterList *roster_list;
  622. CAppRoster *lpAppRoster;
  623. DebugEntry(CAppRosterMgr::RemoveUserReference);
  624. /*
  625. ** Now get the affected roster. Note that if this is not the
  626. ** top provider we wait for the full refresh to update the
  627. ** global roster.
  628. */
  629. roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
  630. // Try to delete this user from every roster in the list
  631. roster_list->Reset();
  632. while (NULL != (lpAppRoster = roster_list->Iterate()))
  633. {
  634. error_value = lpAppRoster->RemoveUserReference (detached_user);
  635. if ((error_value != GCC_NO_ERROR) &&
  636. (error_value != GCC_INVALID_PARAMETER))
  637. {
  638. rc = error_value;
  639. WARNING_OUT(("AppRosterManager::RemoveUserReference:"
  640. "FATAL error occured while removing user reference."));
  641. break;
  642. }
  643. }
  644. DebugExitINT(CAppRosterMgr::RemoveUserReference, rc);
  645. return rc;
  646. }
  647. /*
  648. * Boolean IsEntityEnrolled ()
  649. *
  650. * Public Function Description
  651. * This routine informs the caller if the specified entity is enrolled
  652. * with any sessions managed by this application roster manager.
  653. */
  654. BOOL CAppRosterMgr::IsEntityEnrolled(EntityID application_entity)
  655. {
  656. BOOL rc = TRUE;
  657. CAppRosterList *application_roster_list;
  658. CAppRoster *lpAppRoster;
  659. DebugEntry(CAppRosterMgr::IsEntityEnrolled);
  660. application_roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
  661. application_roster_list->Reset();
  662. while (NULL != (lpAppRoster = application_roster_list->Iterate()))
  663. {
  664. if (lpAppRoster->DoesRecordExist(m_pMcsUserObject->GetMyNodeID(), application_entity))
  665. {
  666. rc = TRUE;
  667. break;
  668. }
  669. }
  670. DebugExitBOOL(AppRosterManager:IsEntityEnrolled, rc);
  671. return rc;
  672. }
  673. /*
  674. * GCCError ApplicationRosterInquire ()
  675. *
  676. * Public Function Description
  677. * This routine fills in an application roster message with either
  678. * a single roster (if a session other than the default is specified)
  679. * or the complete list of "Global" rosters contained by this roster
  680. * manager (if the specified session key is NULL or the session ID is
  681. * zero.
  682. */
  683. GCCError CAppRosterMgr::ApplicationRosterInquire (
  684. PGCCSessionKey session_key,
  685. CAppRosterMsg *roster_message)
  686. {
  687. GCCError rc = GCC_NO_ERROR;
  688. CAppRoster *application_roster = NULL;
  689. CSessKeyContainer *pSessKeyData;
  690. DebugEntry(CAppRosterMgr::ApplicationRosterInquire);
  691. if (session_key != NULL)
  692. {
  693. if (session_key->session_id != 0)
  694. {
  695. /*
  696. ** Here we try to find the specific application roster that was
  697. ** requested.
  698. */
  699. DBG_SAVE_FILE_LINE
  700. pSessKeyData = new CSessKeyContainer(session_key, &rc);
  701. if ((pSessKeyData != NULL) && (rc == GCC_NO_ERROR))
  702. {
  703. CAppRoster *lpAppRoster;
  704. m_GlobalRosterList.Reset();
  705. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  706. {
  707. CSessKeyContainer *pTempSessKeyData = lpAppRoster->GetSessionKey();
  708. if (*pTempSessKeyData == *pSessKeyData)
  709. {
  710. application_roster = lpAppRoster;
  711. break;
  712. }
  713. }
  714. }
  715. if (pSessKeyData != NULL)
  716. {
  717. pSessKeyData->Release();
  718. if (application_roster == NULL)
  719. {
  720. rc = GCC_NO_SUCH_APPLICATION;
  721. }
  722. }
  723. else
  724. {
  725. rc = GCC_ALLOCATION_FAILURE;
  726. }
  727. }
  728. }
  729. if (rc == GCC_NO_ERROR)
  730. {
  731. if (application_roster != NULL)
  732. {
  733. roster_message->AddRosterToMessage(application_roster);
  734. }
  735. else
  736. {
  737. CAppRoster *lpAppRoster;
  738. m_GlobalRosterList.Reset();
  739. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  740. {
  741. roster_message->AddRosterToMessage(lpAppRoster);
  742. }
  743. }
  744. }
  745. DebugExitINT(AppRosterManager:ApplicationRosterInquire, rc);
  746. return rc;
  747. }
  748. /*
  749. * BOOL IsAPEEnrolled ()
  750. *
  751. * Public Function Description
  752. * This function determines if the specified APE is enrolled with
  753. * any session in the list. It does not worry about a specific
  754. * session.
  755. */
  756. BOOL CAppRosterMgr::IsAPEEnrolled(
  757. UserID node_id,
  758. EntityID entity_id)
  759. {
  760. BOOL rc = FALSE;
  761. CAppRoster *lpAppRoster;
  762. DebugEntry(CAppRosterMgr::IsAPEEnrolled);
  763. /*
  764. ** First get a single session key. Note that it makes no difference
  765. ** where the key comes from because we are only goin to be comparing
  766. ** the base object key.
  767. */
  768. m_GlobalRosterList.Reset();
  769. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  770. {
  771. if (lpAppRoster->DoesRecordExist (node_id, entity_id))
  772. {
  773. rc = TRUE;
  774. break;
  775. }
  776. }
  777. DebugExitBOOL(AppRosterManager:IsAPEEnrolled, rc);
  778. return rc;
  779. }
  780. /*
  781. * BOOL IsAPEEnrolled ()
  782. *
  783. * Public Function Description
  784. * This function determines if the specified APE is enrolled with
  785. * a specific session in the list.
  786. */
  787. BOOL CAppRosterMgr::IsAPEEnrolled(
  788. CSessKeyContainer *session_key_data,
  789. UserID node_id,
  790. EntityID entity_id)
  791. {
  792. BOOL rc = FALSE;
  793. CAppRoster *lpAppRoster;
  794. DebugEntry(CAppRosterMgr::IsAPEEnrolled);
  795. /*
  796. ** First get a single session key. Note that it makes no difference
  797. ** where the key comes from because we are only goin to be comparing
  798. ** the base object key.
  799. */
  800. m_GlobalRosterList.Reset();
  801. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  802. {
  803. // We are looking for a session key match
  804. if (*(lpAppRoster->GetSessionKey()) == *session_key_data)
  805. {
  806. // If a match was found check to see if record exist
  807. rc = lpAppRoster->DoesRecordExist (node_id, entity_id);
  808. }
  809. }
  810. DebugExitBOOL(AppRosterManager:IsAPEEnrolled, rc);
  811. return rc;
  812. }
  813. /*
  814. * GCCError IsEmpty ()
  815. *
  816. * Public Function Description
  817. * This routine determines if this application roster managfer contains
  818. * any application rosters.
  819. */
  820. BOOL CAppRosterMgr::IsEmpty(void)
  821. {
  822. return (m_GlobalRosterList.IsEmpty() && m_LocalRosterList.IsEmpty()) ?
  823. TRUE : FALSE;
  824. }
  825. /*
  826. * GCCError SendRosterReportMessage ()
  827. *
  828. * Private Function Description
  829. * This routine is responsible for sending the application roster
  830. * update indications to the application SAPs.
  831. *
  832. * Formal Parameters:
  833. * None.
  834. *
  835. * Return Value
  836. * GCC_NO_ERROR - No error occured.
  837. * GCC_ALLOCATION_FAILURE - A resource error occured.
  838. *
  839. * Side Effects
  840. * None.
  841. *
  842. * Caveats:
  843. * We send indications for all rosters. Even roster that don't currently
  844. * contain records.
  845. */
  846. GCCError CAppRosterMgr::
  847. SendRosterReportMessage(void)
  848. {
  849. GCCError rc = GCC_NO_ERROR;
  850. CAppRosterMsg *roster_message;
  851. DebugEntry(CAppRosterMgr::SendRosterReportMessage);
  852. if (! m_GlobalRosterList.IsEmpty())
  853. {
  854. // First allocate the roster message
  855. DBG_SAVE_FILE_LINE
  856. roster_message = new CAppRosterMsg();
  857. if (roster_message != NULL)
  858. {
  859. CAppRoster *lpAppRoster;
  860. m_GlobalRosterList.Reset();
  861. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  862. {
  863. roster_message->AddRosterToMessage(lpAppRoster);
  864. }
  865. /*
  866. ** Here we iterate through the complete list of application
  867. ** saps to send the roster report indication. Note that
  868. ** we used the sent list to avoid sending the same roster
  869. ** update to a single SAP more than once. Note that since
  870. ** this sent list is defined as a local instance variable,
  871. ** it automatically is cleaned up after each roster update.
  872. **
  873. ** Note also that we iterate on a temporary list here in case
  874. ** an application unenrolls (usually due to a resource error)
  875. ** during this callback. We must protect the rogue wave
  876. ** iterator.
  877. */
  878. CAppSap *pAppSap;
  879. CAppSapList SentList;
  880. CAppSapEidList2 ToSendList(m_AppSapEidList2);
  881. ToSendList.Reset();
  882. while (NULL != (pAppSap = ToSendList.Iterate()))
  883. {
  884. if (! SentList.Find(pAppSap))
  885. {
  886. /*
  887. ** Hold on to this sap so that we don't send to it
  888. ** again for this update.
  889. */
  890. SentList.Append(pAppSap);
  891. // Here we actually deliver the roster update.
  892. pAppSap->AppRosterReportIndication(m_nConfID, roster_message);
  893. }
  894. }
  895. /*
  896. ** Here we send the roster report indication to the
  897. ** controler sap.
  898. */
  899. g_pControlSap->AppRosterReportIndication(m_nConfID, roster_message);
  900. /*
  901. ** Here we free up the roster message. Note that if this
  902. ** message got locked in the roster report indication calls
  903. ** this free will not delete the roster memory.
  904. */
  905. roster_message->Release();
  906. }
  907. else
  908. rc = GCC_ALLOCATION_FAILURE;
  909. }
  910. DebugExitINT(AppRosterManager::SendRosterReportMessage, rc);
  911. return rc;
  912. }
  913. /*
  914. * CAppRoster *GetApplicationRoster ()
  915. *
  916. * Private Function Description
  917. * This routine is responsible for returning the application pointer
  918. * associated with the specified session key.
  919. *
  920. * Formal Parameters:
  921. * session_key - Session key associated with roster to return.
  922. * roster_list - Roster list to search.
  923. *
  924. * Return Value
  925. * Either NULL if roster does not exists in list or a pointer to
  926. * the appropriate application roster.
  927. *
  928. * Side Effects
  929. * None.
  930. *
  931. * Caveats:
  932. * None.
  933. */
  934. CAppRoster * CAppRosterMgr::GetApplicationRoster (
  935. PGCCSessionKey session_key,
  936. CAppRosterList *roster_list)
  937. {
  938. GCCError rc;
  939. CAppRoster *application_roster = NULL;
  940. CAppRoster *lpAppRoster;
  941. CSessKeyContainer *pTempSessKeyData;
  942. DebugEntry(CAppRosterMgr::GetApplicationRoster);
  943. // First create a temporary session key for comparison purposes
  944. DBG_SAVE_FILE_LINE
  945. pTempSessKeyData = new CSessKeyContainer(session_key, &rc);
  946. if (pTempSessKeyData != NULL && GCC_NO_ERROR == rc)
  947. {
  948. // Now find the affected roster
  949. //
  950. // LONCHANC: The following line is totally wrong!!!
  951. // we passed in roster_list, but now we overwrite it right here???
  952. // Commented out the following line.
  953. // roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
  954. //
  955. roster_list->Reset();
  956. while (NULL != (lpAppRoster = roster_list->Iterate()))
  957. {
  958. if(*lpAppRoster->GetSessionKey() == *pTempSessKeyData)
  959. {
  960. application_roster = lpAppRoster;
  961. break;
  962. }
  963. }
  964. pTempSessKeyData->Release();
  965. }
  966. DebugExitPTR(AppRosterManager::GetApplicationRoster, application_roster);
  967. return (application_roster);
  968. }
  969. /*
  970. * CAppRoster * GetApplicationRosterFromPDU ()
  971. *
  972. * Private Function Description
  973. * This routine is responsible for returning the application pointer
  974. * associated with the specified session key PDU.
  975. *
  976. * Formal Parameters:
  977. * session_key - Session key PDU associated with roster to return.
  978. * roster_list - Roster list to search.
  979. *
  980. * Return Value
  981. * Either NULL if roster does not exists in list or a pointer to
  982. * the appropriate application roster.
  983. *
  984. * Side Effects
  985. * None.
  986. *
  987. * Caveats:
  988. * None.
  989. */
  990. CAppRoster * CAppRosterMgr::GetApplicationRosterFromPDU (
  991. PSessionKey session_key,
  992. CAppRosterList *roster_list)
  993. {
  994. CSessKeyContainer *session_key_data;
  995. CAppRoster *pAppRoster;
  996. DebugEntry(CAppRosterMgr::GetApplicationRosterFromPDU);
  997. roster_list->Reset();
  998. while (NULL != (pAppRoster = roster_list->Iterate()))
  999. {
  1000. session_key_data = pAppRoster->GetSessionKey();
  1001. if (session_key_data->IsThisYourSessionKeyPDU (session_key))
  1002. {
  1003. break;
  1004. }
  1005. }
  1006. DebugExitPTR(CAppRosterMgr::GetApplicationRosterFromPDU, pAppRoster);
  1007. return pAppRoster;
  1008. }
  1009. /*
  1010. * BOOL IsThisSessionKeyValid ()
  1011. *
  1012. * Private Function Description
  1013. * This routine is responsible for determining if the specified
  1014. * session key's application protocol key matches this application
  1015. * roster manager's. This routine works on API data.
  1016. *
  1017. * Formal Parameters:
  1018. * session_key - Session key to check.
  1019. *
  1020. * Return Value
  1021. * TRUE - If we have a match.
  1022. * FALSE - If we do NOT have a match.
  1023. *
  1024. * Side Effects
  1025. * None.
  1026. *
  1027. * Caveats:
  1028. * None.
  1029. */
  1030. /*
  1031. * BOOL IsThisSessionKeyPDUValid ()
  1032. *
  1033. * Private Function Description
  1034. * This routine is responsible for determining if the specified
  1035. * session key's application protocol key matches this application
  1036. * roster manager's. This routine works on PDU data.
  1037. *
  1038. * Formal Parameters:
  1039. * session_key - Session key to check.
  1040. *
  1041. * Return Value
  1042. * TRUE - If we have a match.
  1043. * FALSE - If we do NOT have a match.
  1044. *
  1045. * Side Effects
  1046. * None.
  1047. *
  1048. * Caveats:
  1049. * None.
  1050. */
  1051. /*
  1052. * void CleanupApplicationRosterLists ()
  1053. *
  1054. * Private Function Description
  1055. * This routine is responsible for cleaning up any empty application
  1056. * rosters. It also resets all the application rosters back to their
  1057. * neutral state so that any new updates will be handled correctly.
  1058. *
  1059. * Formal Parameters:
  1060. * None.
  1061. *
  1062. * Return Value
  1063. * None.
  1064. *
  1065. * Side Effects
  1066. * An owner callback will occur when the roster becomes empty.
  1067. *
  1068. * Caveats:
  1069. * This routine does not actually delete the empty rosters until it
  1070. * is placed in the delete list. Instead it places the rosters into the
  1071. * list of deleted rosters which causes them to be deleted the next time
  1072. * this routine is called (or when the object is destructed).
  1073. */
  1074. void CAppRosterMgr::CleanupApplicationRosterLists(void)
  1075. {
  1076. CAppRoster *lpAppRoster;
  1077. DebugEntry(CAppRosterMgr::CleanupApplicationRosterLists);
  1078. /*
  1079. ** First we iterate through the list of deleted rosters and delete
  1080. ** each entry in it.
  1081. */
  1082. m_RosterDeleteList.DeleteList();
  1083. /*
  1084. ** Next we iterate through all the rosters and remove any that
  1085. ** contain no application records. Here instead of deleting the
  1086. ** roster we move the roster into the delete list. We cannot do
  1087. ** the delete here because it is possible that PDU data owned by the
  1088. ** roster being deleted may be used after the Flush is called (or
  1089. ** after this routine is called). Therefore, we save it in the delete
  1090. ** list and delete it next time we enter this routine.
  1091. */
  1092. // Start with the Global Application Roster List
  1093. m_GlobalRosterList.Reset();
  1094. while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
  1095. {
  1096. if (lpAppRoster->GetNumberOfApplicationRecords() == 0)
  1097. {
  1098. //
  1099. // Here we clean up any "dangling" entries in the application
  1100. // registry by removing all the entries that contain the
  1101. // session key associated with the roster that is being deleted.
  1102. // Note that this is only done when a Global roster list is
  1103. //removed.
  1104. //
  1105. CRegistry *pAppReg = m_pConf->GetRegistry();
  1106. pAppReg->RemoveSessionKeyReference(lpAppRoster->GetSessionKey());
  1107. m_GlobalRosterList.Remove(lpAppRoster);
  1108. m_RosterDeleteList.Append(lpAppRoster);
  1109. TRACE_OUT(("AppRosterMgr: Cleanup: Deleting Global Roster"));
  1110. /*
  1111. ** Since you can not delete a list entry while iterating on it
  1112. ** we must reset the iterator every time an entry is removed.
  1113. */
  1114. m_GlobalRosterList.Reset();
  1115. }
  1116. else
  1117. {
  1118. /*
  1119. ** Here we reset the application roster to its neutral state.
  1120. ** This affects the nodes added and nodes removed flags.
  1121. */
  1122. lpAppRoster->ResetApplicationRoster();
  1123. }
  1124. }
  1125. // Next deal with the Local Application Roster List
  1126. if (! m_fTopProvider)
  1127. {
  1128. m_LocalRosterList.Reset();
  1129. while (NULL != (lpAppRoster = m_LocalRosterList.Iterate()))
  1130. {
  1131. if (lpAppRoster->GetNumberOfApplicationRecords() == 0)
  1132. {
  1133. m_LocalRosterList.Remove(lpAppRoster);
  1134. m_RosterDeleteList.Append(lpAppRoster);
  1135. TRACE_OUT(("AppRosterMgr: Cleanup: Deleting Local Roster"));
  1136. /*
  1137. ** Since you can not delete a list entry while iterating on it
  1138. ** we must reset the iterator every time an entry is removed.
  1139. */
  1140. m_LocalRosterList.Reset();
  1141. }
  1142. else
  1143. {
  1144. /*
  1145. ** Here we reset the application roster to its neutral state.
  1146. ** This affects the nodes added and nodes removed flags.
  1147. */
  1148. lpAppRoster->ResetApplicationRoster();
  1149. }
  1150. }
  1151. }
  1152. DebugExitVOID(CAppRosterMgr::CleanupApplicationRosterLists);
  1153. }
  1154. /*
  1155. * void DeleteRosterRecord ()
  1156. *
  1157. * Public Function Description
  1158. * This function overides the base class function and is used to
  1159. * receive all owner callback information from the application
  1160. * rosters owned by this object.
  1161. */
  1162. void CAppRosterMgr::
  1163. DeleteRosterRecord
  1164. (
  1165. GCCNodeID nidRecordToDelete,
  1166. GCCEntityID eidRecordToDelete
  1167. )
  1168. {
  1169. //
  1170. // Here we remove ownership from any registry entries associated
  1171. // with the record that was deleted. Note that since the entity
  1172. // id must be unique for all the APEs at a node (as stated by
  1173. // T.124) there is no need to include the session key to determine
  1174. // which registry entries to clean up.
  1175. //
  1176. CRegistry *pAppReg = m_pConf->GetRegistry();
  1177. pAppReg->RemoveEntityOwnership(nidRecordToDelete, eidRecordToDelete);
  1178. }
  1179. void CAppRosterMgrList::DeleteList(void)
  1180. {
  1181. CAppRosterMgr *pAppRosterMgr;
  1182. while (NULL != (pAppRosterMgr = Get()))
  1183. {
  1184. pAppRosterMgr->Release();
  1185. }
  1186. }