mirror of https://github.com/tongzx/nt5src
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
1329 lines
35 KiB
#include "precomp.h"
|
|
DEBUG_FILEZONE(ZONE_T120_APP_ROSTER);
|
|
/*
|
|
* arostmgr.cpp
|
|
*
|
|
* Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
|
|
*
|
|
* Abstract:
|
|
* This is the implementation file for the Application Roster
|
|
* Manager Class.
|
|
*
|
|
* SEE THE INTERFACE FILE FOR A MORE DETAILED DESCRIPION OF THIS CLASS.
|
|
*
|
|
* Private Instance Variables
|
|
* m_nConfID
|
|
* The conference ID associated with this roster manager. Used
|
|
* when delivering roster update messages.
|
|
* m_fTopProvider
|
|
* Flag indicating if this is a top provider node for this conference.
|
|
* m_pMcsUserObject
|
|
* This is the user attachment object associated with this conference.
|
|
* m_AppSapEidList2
|
|
* This list maintains all of the command target pointers for each
|
|
* of the enrolled APEs. This list is used to deliver roster
|
|
* update messages.
|
|
* m_pConf
|
|
* Pointer to object that will receive all owner callback messages
|
|
* delivered from the application roster manager.
|
|
* m_GlobalRosterList
|
|
* This list maintains pointers to all the global application rosters.
|
|
* m_LocalRosterList
|
|
* This list maintains pointers to all the local application rosters.
|
|
* This list will not be used if this is a Top Provider node.
|
|
* m_RosterDeleteList
|
|
* This list is used to hold any application rosters that have
|
|
* been marked to be deleted (usually when they become empty). We
|
|
* don't delete immediately to allow messages and PDUs to be processed
|
|
* before deletion.
|
|
* m_pSessionKey
|
|
* This is the session key used to hold the protocol key associated
|
|
* with this application roster manager.
|
|
*
|
|
* Caveats:
|
|
* None
|
|
*
|
|
* Author:
|
|
* blp
|
|
*/
|
|
|
|
|
|
#include "arostmgr.h"
|
|
#include "arostmsg.h"
|
|
#include "appsap.h"
|
|
#include "csap.h"
|
|
#include "conf.h"
|
|
|
|
|
|
/*
|
|
* CAppRosterMgr ()
|
|
*
|
|
* Public Function Description
|
|
* when pGccSessKey is not NULL
|
|
* This is the application roster manager constructor. It is responsible
|
|
* for initializing all the instance variables used by this class.
|
|
* This constructor is used when the initial roster data that is
|
|
* availble comes from local API data.
|
|
*
|
|
* when pSessKey is not NULL
|
|
* This is the application roster manager constructor. It is responsible
|
|
* for initializing all the instance variables used by this class.
|
|
* This constructor is used when the initial roster data that is
|
|
* availble comes from remote PDU data.
|
|
* This constructor handles a number of different possiblities:
|
|
* For Non Top Providers:
|
|
* 1) A refresh received from the top provider.
|
|
* 2) An update from a node below this one.
|
|
*
|
|
* For the Top Provider:
|
|
* 1) An Update from a lower node
|
|
*/
|
|
CAppRosterMgr::CAppRosterMgr(
|
|
PGCCSessionKey pGccSessKey,
|
|
PSessionKey pPduSessKey,
|
|
GCCConfID nConfID,
|
|
PMCSUser pMcsUserObject,
|
|
CConf *pConf,
|
|
PGCCError pRetCode)
|
|
:
|
|
CRefCount(MAKE_STAMP_ID('A','R','M','r')),
|
|
m_nConfID(nConfID),
|
|
// m_fTopProvider(FALSE),
|
|
m_pMcsUserObject(pMcsUserObject),
|
|
m_AppSapEidList2(DESIRED_MAX_APP_SAP_ITEMS),
|
|
m_pConf(pConf)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
|
|
DebugEntry(CAppRosterMgr::CAppRosterMgr);
|
|
|
|
// Determine if this is a top provider node
|
|
m_fTopProvider = (m_pMcsUserObject->GetTopNodeID() == m_pMcsUserObject->GetMyNodeID());
|
|
|
|
/*
|
|
** Set up this roster managers session key which will be used to
|
|
** determine whether or not to process a roster request or update.
|
|
*/
|
|
if (NULL != pGccSessKey)
|
|
{
|
|
ASSERT(NULL == pPduSessKey);
|
|
DBG_SAVE_FILE_LINE
|
|
m_pSessionKey = new CSessKeyContainer(pGccSessKey, &rc);
|
|
}
|
|
else
|
|
if (NULL != pPduSessKey)
|
|
{
|
|
DBG_SAVE_FILE_LINE
|
|
m_pSessionKey = new CSessKeyContainer(pPduSessKey, &rc);
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("CAppRosterMgr::CAppRosterMgr: invalid session key"));
|
|
rc = GCC_BAD_SESSION_KEY;
|
|
goto MyExit;
|
|
}
|
|
|
|
if (NULL == m_pSessionKey || GCC_NO_ERROR != rc)
|
|
{
|
|
ERROR_OUT(("CAppRosterMgr::CAppRosterMgr: can't create session key"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
// we do the cleanup in the destructor
|
|
goto MyExit;
|
|
}
|
|
|
|
ASSERT(GCC_NO_ERROR == rc);
|
|
|
|
MyExit:
|
|
|
|
DebugExitINT(CAppRosterMgr:;CAppRosterMgr, rc);
|
|
|
|
*pRetCode = rc;
|
|
}
|
|
|
|
/*
|
|
* ~CAppRosterMgr()
|
|
*
|
|
* Public Function Description
|
|
* This is the application roster manager destructor. It is used to
|
|
* free up all memory associated with this class.
|
|
*/
|
|
CAppRosterMgr::~CAppRosterMgr(void)
|
|
{
|
|
m_GlobalRosterList.DeleteList();
|
|
m_LocalRosterList.DeleteList();
|
|
m_RosterDeleteList.DeleteList();
|
|
|
|
if (NULL != m_pSessionKey)
|
|
{
|
|
m_pSessionKey->Release();
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* GCCError EnrollRequest ()
|
|
*
|
|
* Public Function Description
|
|
* This routine is called whenever an APE wishes to enroll with the
|
|
* conference in a specific session. This routine can be used to
|
|
* either add a new record or replace a currently existing record.
|
|
*/
|
|
GCCError CAppRosterMgr::
|
|
EnrollRequest(GCCEnrollRequest *pReq, GCCEntityID eid, GCCNodeID nid, CAppSap *pAppSap)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
CAppRoster *pAppRoster = NULL;
|
|
BOOL perform_add_record;
|
|
BOOL maintain_pdu_data;
|
|
|
|
DebugEntry(CAppRosterMgr::EnrollRequest);
|
|
|
|
/*
|
|
** First we must make sure that the default version of this session
|
|
** key matches this application roster manager's
|
|
*/
|
|
if (! IsThisSessionKeyValid(pReq->pSessionKey))
|
|
{
|
|
rc = GCC_BAD_SESSION_KEY;
|
|
goto MyExit;
|
|
}
|
|
|
|
// Now save the App SAP so we can send roster report indications
|
|
if (! m_AppSapEidList2.Find(eid))
|
|
{
|
|
m_AppSapEidList2.Append(eid, pAppSap);
|
|
perform_add_record = TRUE;
|
|
}
|
|
else
|
|
{
|
|
perform_add_record = FALSE;
|
|
}
|
|
|
|
/*
|
|
** Next we must make sure that the global application roster (and
|
|
** local for non top providers) that matches this session key exist.
|
|
** If they don't exists then create them here.
|
|
*/
|
|
pAppRoster = GetApplicationRoster(pReq->pSessionKey, &m_GlobalRosterList);
|
|
if (pAppRoster == NULL)
|
|
{
|
|
maintain_pdu_data = m_fTopProvider;
|
|
|
|
/*
|
|
** Here we create the global default application rosters. If
|
|
** this is the Top Provider we DO maintain PDU data within the
|
|
** roster.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
pAppRoster = new CAppRoster(pReq->pSessionKey,
|
|
NULL, // pSessKey
|
|
this, // pOwnerObject
|
|
m_fTopProvider,// fTopProvider
|
|
FALSE, // fLocalRoster
|
|
maintain_pdu_data, // fMaintainPduBuffer
|
|
&rc);
|
|
if ((pAppRoster != NULL) && (rc == GCC_NO_ERROR))
|
|
{
|
|
m_GlobalRosterList.Append(pAppRoster);
|
|
}
|
|
else
|
|
{
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
goto MyExit;
|
|
}
|
|
}
|
|
|
|
if (! m_fTopProvider)
|
|
{
|
|
pAppRoster = GetApplicationRoster(pReq->pSessionKey, &m_LocalRosterList);
|
|
if (pAppRoster == NULL)
|
|
{
|
|
// Here we create the local default application rosters.
|
|
DBG_SAVE_FILE_LINE
|
|
pAppRoster = new CAppRoster(pReq->pSessionKey,
|
|
NULL, // pSessKey
|
|
this, // pOwnerObject
|
|
m_fTopProvider,// fTopProvider
|
|
TRUE, // fLocalRoster
|
|
TRUE, // fMaintainPduBuffer
|
|
&rc);
|
|
if ((pAppRoster != NULL) && (rc == GCC_NO_ERROR))
|
|
{
|
|
m_LocalRosterList.Append(pAppRoster);
|
|
}
|
|
else
|
|
{
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
goto MyExit;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// LONCHANC: Something wrong here. roster_ptr could be either
|
|
// the one in the global list or the one in the local list.
|
|
// Should we add records to both roster_ptr???
|
|
//
|
|
// LONCHANC: It seems to me that only the local list has records in non-top provider.
|
|
// On the other hand, only the global list has the record in top provider.
|
|
// cf. UnEnrollRequest().
|
|
//
|
|
|
|
if (perform_add_record)
|
|
{
|
|
// Add the new record to the roster
|
|
rc = pAppRoster->AddRecord(pReq, nid, eid);
|
|
if (GCC_NO_ERROR != rc)
|
|
{
|
|
ERROR_OUT(("AppRosterManager::EnrollRequest: can't add record"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = pAppRoster->ReplaceRecord(pReq, nid, eid);
|
|
if (GCC_NO_ERROR != rc)
|
|
{
|
|
ERROR_OUT(("AppRosterManager::EnrollRequest: can't repalce record"));
|
|
}
|
|
}
|
|
|
|
// zero out the roster pointer because it should no be freed
|
|
// in case of adding or replacing a record.
|
|
// because the roster pointer has been added to the list,
|
|
// it will be freed later.
|
|
pAppRoster = NULL;
|
|
|
|
MyExit:
|
|
|
|
if (GCC_NO_ERROR != rc)
|
|
{
|
|
if (pAppRoster != NULL)
|
|
{
|
|
pAppRoster->Release();
|
|
}
|
|
}
|
|
|
|
DebugExitINT(CAppRosterMgr::EnrollRequest, rc);
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* GCCError UnEnrollRequest ()
|
|
*
|
|
* Public Function Description
|
|
* This routine is called whenever an APE wishes to unenroll from the
|
|
* conference (or a specific session).
|
|
*/
|
|
GCCError CAppRosterMgr::UnEnrollRequest (
|
|
PGCCSessionKey session_key,
|
|
EntityID entity_id)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
CAppRoster *application_roster = NULL;
|
|
CAppRosterList *roster_list;
|
|
|
|
DebugEntry(CAppRosterMgr::UnEnrollRequest);
|
|
|
|
// Is this a valid session key for the application roster manager
|
|
if (IsThisSessionKeyValid (session_key) == FALSE)
|
|
rc = GCC_INVALID_PARAMETER;
|
|
else if (m_AppSapEidList2.Remove(entity_id))
|
|
{
|
|
// Now find the affected roster
|
|
roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
|
|
|
|
application_roster = GetApplicationRoster ( session_key, roster_list);
|
|
// Now unenroll from the specified roster
|
|
if (application_roster != NULL)
|
|
{
|
|
rc = application_roster->RemoveRecord(
|
|
m_pMcsUserObject->GetMyNodeID(),
|
|
entity_id);
|
|
}
|
|
else
|
|
rc = GCC_BAD_SESSION_KEY;
|
|
}
|
|
else
|
|
rc = GCC_APP_NOT_ENROLLED;
|
|
|
|
DebugExitINT(CAppRosterMgr::UnEnrollRequest, rc);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* GCCError ProcessRosterUpdateIndicationPDU ()
|
|
*
|
|
* Public Function Description
|
|
* This routine processes an incomming roster update PDU. It is
|
|
* responsible for passing the PDU on to the right application roster.
|
|
*/
|
|
GCCError CAppRosterMgr::ProcessRosterUpdateIndicationPDU(
|
|
PSetOfApplicationInformation set_of_application_info,
|
|
UserID sender_id)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
CAppRosterList *roster_list;
|
|
CAppRoster *application_roster;
|
|
BOOL maintain_pdu_buffer;
|
|
BOOL is_local_roster;
|
|
|
|
DebugEntry(CAppRosterMgr::ProcessRosterUpdateIndicationPDU);
|
|
|
|
/*
|
|
** First make sure that the session key contained in the current
|
|
** set of application information is valid for this application roster
|
|
** manager.
|
|
*/
|
|
if (IsThisSessionKeyPDUValid(&set_of_application_info->value.session_key))
|
|
{
|
|
/*
|
|
** Now search for the appropriate application roster. If it is not
|
|
** found we must create it here.
|
|
*/
|
|
|
|
//
|
|
// LONCHANC:
|
|
// (1) If top provider, add default application roster to the global roster list.
|
|
// (2) If non-top provider, we do not create both the local and global version of the
|
|
// application roster for this particular session key.
|
|
// instead, We create only the appropriate one here
|
|
// and wait until we receive either a refresh from the
|
|
// top provider or an update from a node below this one
|
|
// in the connection hierarchy (or an application
|
|
// enroll) before creating the other.
|
|
// (3) If this PDU was sent from below this node it
|
|
// must be an update of the local roster so save
|
|
// the roster in the local roster list.
|
|
//
|
|
roster_list = (m_fTopProvider || (sender_id == m_pMcsUserObject->GetTopNodeID())) ?
|
|
&m_GlobalRosterList : &m_LocalRosterList;
|
|
|
|
application_roster = GetApplicationRosterFromPDU (
|
|
&set_of_application_info->value.session_key,
|
|
roster_list);
|
|
if (application_roster != NULL)
|
|
{
|
|
rc = application_roster->
|
|
ProcessRosterUpdateIndicationPDU(
|
|
set_of_application_info,
|
|
sender_id);
|
|
}
|
|
else
|
|
{
|
|
// First determine the characteristics of this roster
|
|
if (m_fTopProvider)
|
|
{
|
|
maintain_pdu_buffer = TRUE;
|
|
is_local_roster = FALSE;
|
|
}
|
|
else if (sender_id == m_pMcsUserObject->GetTopNodeID())
|
|
{
|
|
maintain_pdu_buffer = FALSE;
|
|
is_local_roster = FALSE;
|
|
}
|
|
else
|
|
{
|
|
maintain_pdu_buffer = TRUE;
|
|
is_local_roster = TRUE;
|
|
}
|
|
|
|
// Create the application roster from the passed in PDU.
|
|
DBG_SAVE_FILE_LINE
|
|
application_roster = new CAppRoster(NULL, // pGccSessKey
|
|
&set_of_application_info->value.session_key, // pSessKey
|
|
this, // pOwnerObject
|
|
m_fTopProvider,// fTopProvider
|
|
is_local_roster,// fLocalRoster
|
|
maintain_pdu_buffer,// fMaintainPduBuffer
|
|
&rc);
|
|
if ((application_roster != NULL) && (rc == GCC_NO_ERROR))
|
|
{
|
|
// Process the PDU with the created application roster.
|
|
rc = application_roster->
|
|
ProcessRosterUpdateIndicationPDU(
|
|
set_of_application_info,
|
|
sender_id);
|
|
if (rc == GCC_NO_ERROR)
|
|
{
|
|
roster_list->Append(application_roster);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (application_roster != NULL)
|
|
{
|
|
application_roster->Release();
|
|
}
|
|
else
|
|
{
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("AppRosterManager::ProcessRosterUpdateIndicationPDU:"
|
|
"ASSERTION: Application Information is not valid"));
|
|
rc = GCC_INVALID_PARAMETER;
|
|
}
|
|
|
|
DebugExitINT(CAppRosterMgr::ProcessRosterUpdateIndicationPDU, rc);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* PSetOfApplicationInformation FlushRosterUpdateIndication ()
|
|
*
|
|
* Public Function Description
|
|
* This routine is used to access any PDU data that might currently be
|
|
* queued inside the application rosters managed by this application
|
|
* roster manager. It also is responsible for flushing any queued
|
|
* roster update messages if necessary.
|
|
*/
|
|
PSetOfApplicationInformation
|
|
CAppRosterMgr::FlushRosterUpdateIndication(
|
|
PSetOfApplicationInformation * set_of_information,
|
|
PGCCError rc)
|
|
{
|
|
PSetOfApplicationInformation pOld = NULL, pCurr;
|
|
CAppRosterList *roster_list;
|
|
CAppRoster *lpAppRoster;
|
|
|
|
DebugEntry(CAppRosterMgr::FlushRosterUpdateIndication);
|
|
|
|
/*
|
|
** First we deal with flushing the PDU data. We iterate through the
|
|
** appropriate list (Global if the Top Provider and Local if not the
|
|
** Top Provider) and get any PDU data associated with each of these.
|
|
** Note that some of these may not contain any PDU data.
|
|
*/
|
|
*rc = GCC_NO_ERROR;
|
|
*set_of_information = NULL;
|
|
|
|
roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
|
|
|
|
roster_list->Reset();
|
|
while (NULL != (lpAppRoster = roster_list->Iterate()))
|
|
{
|
|
lpAppRoster->FlushRosterUpdateIndicationPDU(&pCurr);
|
|
if (pCurr != NULL)
|
|
{
|
|
if (*set_of_information == NULL)
|
|
*set_of_information = pCurr;
|
|
else
|
|
pOld->next = pCurr;
|
|
|
|
(pOld = pCurr)->next = NULL;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Next we deal with delivering the application roster update messages.
|
|
** We first check to see if any of the global rosters have changed. If
|
|
** none have changed, we will not deliver a roster update indication.
|
|
*/
|
|
m_GlobalRosterList.Reset();
|
|
while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
|
|
{
|
|
if (lpAppRoster->HasRosterChanged())
|
|
{
|
|
TRACE_OUT(("AppRosterManager::FlushRosterUpdateIndication:Roster HAS Changed"));
|
|
*rc = SendRosterReportMessage ();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Cleanup and reset any application rosters after the above flush is
|
|
** completed. This takes care of removing any rosters that have become
|
|
** empty. It also resets the rosters which takes care of resetting all
|
|
** the internal instance variables to their appropriate initial state.
|
|
*/
|
|
CleanupApplicationRosterLists ();
|
|
|
|
DebugExitPTR(CAppRosterMgr::FlushRosterUpdateIndication, pOld);
|
|
|
|
//
|
|
// LONCHANC: Yes, we need to return the last item in the list such that
|
|
// we can continue to grow the list.
|
|
// In fact, the next call to FlushRosterUpdateIndication() will have
|
|
// &pOld as the input argument.
|
|
// It is quite tricky.
|
|
//
|
|
// Please note that pOld is initialized to NULL.
|
|
//
|
|
|
|
return (pOld);
|
|
}
|
|
|
|
/*
|
|
* PSetOfApplicationInformation GetFullRosterRefreshPDU ()
|
|
*
|
|
* Public Function Description
|
|
* This routine is used to obtain a complete roster refresh of all the
|
|
* rosters maintained by this roster manger.
|
|
*/
|
|
PSetOfApplicationInformation
|
|
CAppRosterMgr::GetFullRosterRefreshPDU (
|
|
PSetOfApplicationInformation * set_of_information,
|
|
PGCCError rc)
|
|
{
|
|
PSetOfApplicationInformation new_set_of_information = NULL;
|
|
|
|
DebugEntry(CAppRosterMgr::GetFullRosterRefreshPDU);
|
|
|
|
if (m_fTopProvider)
|
|
{
|
|
CAppRoster *lpAppRoster;
|
|
|
|
*rc = GCC_NO_ERROR;
|
|
*set_of_information = NULL;
|
|
|
|
/*
|
|
** First we must tell all the application rosters to build the
|
|
** a full refresh PDU internally.
|
|
*/
|
|
m_GlobalRosterList.Reset();
|
|
while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
|
|
{
|
|
*rc = lpAppRoster->BuildFullRefreshPDU();
|
|
if (GCC_NO_ERROR != *rc)
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Now we flush all the refreshes. Note that this also takes care
|
|
** of delivering any queued application roster update messages.
|
|
*/
|
|
new_set_of_information = FlushRosterUpdateIndication (set_of_information, rc);
|
|
}
|
|
else
|
|
*rc = GCC_INVALID_PARAMETER;
|
|
|
|
DebugExitPTR(CAppRosterMgr::GetFullRosterRefreshPDU, new_set_of_information);
|
|
|
|
return (new_set_of_information);
|
|
}
|
|
|
|
/*
|
|
* Boolean IsThisYourSessionKey ()
|
|
*
|
|
* Public Function Description
|
|
* This routine is used to determine if the specified "API" session key is
|
|
* associated with this application roster manager.
|
|
*/
|
|
|
|
|
|
/*
|
|
* Boolean IsThisYourSessionKeyPDU ()
|
|
*
|
|
* Public Function Description
|
|
* This routine is used to determine if the specified "PDU" session key is
|
|
* associated with this application roster manager.
|
|
*/
|
|
|
|
|
|
/*
|
|
* GCCError RemoveEntityReference ()
|
|
*
|
|
* Public Function Description
|
|
* This routine is used to remove the specified APE entity from the
|
|
* session it is enrolled with. Note that this routine is only used
|
|
* to remove local entity references.
|
|
*/
|
|
GCCError CAppRosterMgr::RemoveEntityReference(EntityID entity_id)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
CAppRosterList *roster_list;
|
|
|
|
DebugEntry(CAppRosterMgr::RemoveEntityReference);
|
|
|
|
/*
|
|
** First remove this entity from the command target list if it is valid.
|
|
** We then iterate through all the rosters until we determine which
|
|
** roster holds the record associated with this entity.
|
|
*/
|
|
if (m_AppSapEidList2.Remove(entity_id))
|
|
{
|
|
CAppRoster *lpAppRoster;
|
|
|
|
/*
|
|
** Now get the affected roster. Note that if this is not the
|
|
** top provider we wait for the full refresh to update the
|
|
** global roster.
|
|
*/
|
|
roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
|
|
|
|
/*
|
|
** Try to delete this record from every roster in the list.
|
|
** Break when the correct roster is found.
|
|
*/
|
|
roster_list->Reset();
|
|
while (NULL != (lpAppRoster = roster_list->Iterate()))
|
|
{
|
|
rc = lpAppRoster->RemoveRecord(m_pMcsUserObject->GetMyNodeID(), entity_id);
|
|
if (rc == GCC_NO_ERROR)
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
rc = GCC_APP_NOT_ENROLLED;
|
|
|
|
DebugExitINT(CAppRosterMgr::RemoveEntityReference, rc);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* GCCError RemoveUserReference ()
|
|
*
|
|
* Public Function Description
|
|
* This routine is used to remove all references associated with the
|
|
* node defined by the detached user.
|
|
*/
|
|
GCCError CAppRosterMgr::RemoveUserReference(
|
|
UserID detached_user)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
GCCError error_value;
|
|
CAppRosterList *roster_list;
|
|
CAppRoster *lpAppRoster;
|
|
|
|
DebugEntry(CAppRosterMgr::RemoveUserReference);
|
|
|
|
/*
|
|
** Now get the affected roster. Note that if this is not the
|
|
** top provider we wait for the full refresh to update the
|
|
** global roster.
|
|
*/
|
|
roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
|
|
|
|
// Try to delete this user from every roster in the list
|
|
roster_list->Reset();
|
|
while (NULL != (lpAppRoster = roster_list->Iterate()))
|
|
{
|
|
error_value = lpAppRoster->RemoveUserReference (detached_user);
|
|
if ((error_value != GCC_NO_ERROR) &&
|
|
(error_value != GCC_INVALID_PARAMETER))
|
|
{
|
|
rc = error_value;
|
|
WARNING_OUT(("AppRosterManager::RemoveUserReference:"
|
|
"FATAL error occured while removing user reference."));
|
|
break;
|
|
}
|
|
}
|
|
|
|
DebugExitINT(CAppRosterMgr::RemoveUserReference, rc);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* Boolean IsEntityEnrolled ()
|
|
*
|
|
* Public Function Description
|
|
* This routine informs the caller if the specified entity is enrolled
|
|
* with any sessions managed by this application roster manager.
|
|
*/
|
|
BOOL CAppRosterMgr::IsEntityEnrolled(EntityID application_entity)
|
|
{
|
|
BOOL rc = TRUE;
|
|
CAppRosterList *application_roster_list;
|
|
CAppRoster *lpAppRoster;
|
|
|
|
DebugEntry(CAppRosterMgr::IsEntityEnrolled);
|
|
|
|
application_roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
|
|
|
|
application_roster_list->Reset();
|
|
while (NULL != (lpAppRoster = application_roster_list->Iterate()))
|
|
{
|
|
if (lpAppRoster->DoesRecordExist(m_pMcsUserObject->GetMyNodeID(), application_entity))
|
|
{
|
|
rc = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
DebugExitBOOL(AppRosterManager:IsEntityEnrolled, rc);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* GCCError ApplicationRosterInquire ()
|
|
*
|
|
* Public Function Description
|
|
* This routine fills in an application roster message with either
|
|
* a single roster (if a session other than the default is specified)
|
|
* or the complete list of "Global" rosters contained by this roster
|
|
* manager (if the specified session key is NULL or the session ID is
|
|
* zero.
|
|
*/
|
|
GCCError CAppRosterMgr::ApplicationRosterInquire (
|
|
PGCCSessionKey session_key,
|
|
CAppRosterMsg *roster_message)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
CAppRoster *application_roster = NULL;
|
|
CSessKeyContainer *pSessKeyData;
|
|
|
|
DebugEntry(CAppRosterMgr::ApplicationRosterInquire);
|
|
|
|
if (session_key != NULL)
|
|
{
|
|
if (session_key->session_id != 0)
|
|
{
|
|
/*
|
|
** Here we try to find the specific application roster that was
|
|
** requested.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
pSessKeyData = new CSessKeyContainer(session_key, &rc);
|
|
if ((pSessKeyData != NULL) && (rc == GCC_NO_ERROR))
|
|
{
|
|
CAppRoster *lpAppRoster;
|
|
m_GlobalRosterList.Reset();
|
|
while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
|
|
{
|
|
CSessKeyContainer *pTempSessKeyData = lpAppRoster->GetSessionKey();
|
|
if (*pTempSessKeyData == *pSessKeyData)
|
|
{
|
|
application_roster = lpAppRoster;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pSessKeyData != NULL)
|
|
{
|
|
pSessKeyData->Release();
|
|
if (application_roster == NULL)
|
|
{
|
|
rc = GCC_NO_SUCH_APPLICATION;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (rc == GCC_NO_ERROR)
|
|
{
|
|
if (application_roster != NULL)
|
|
{
|
|
roster_message->AddRosterToMessage(application_roster);
|
|
}
|
|
else
|
|
{
|
|
CAppRoster *lpAppRoster;
|
|
m_GlobalRosterList.Reset();
|
|
while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
|
|
{
|
|
roster_message->AddRosterToMessage(lpAppRoster);
|
|
}
|
|
}
|
|
}
|
|
|
|
DebugExitINT(AppRosterManager:ApplicationRosterInquire, rc);
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* BOOL IsAPEEnrolled ()
|
|
*
|
|
* Public Function Description
|
|
* This function determines if the specified APE is enrolled with
|
|
* any session in the list. It does not worry about a specific
|
|
* session.
|
|
*/
|
|
BOOL CAppRosterMgr::IsAPEEnrolled(
|
|
UserID node_id,
|
|
EntityID entity_id)
|
|
{
|
|
BOOL rc = FALSE;
|
|
CAppRoster *lpAppRoster;
|
|
|
|
DebugEntry(CAppRosterMgr::IsAPEEnrolled);
|
|
|
|
/*
|
|
** First get a single session key. Note that it makes no difference
|
|
** where the key comes from because we are only goin to be comparing
|
|
** the base object key.
|
|
*/
|
|
m_GlobalRosterList.Reset();
|
|
while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
|
|
{
|
|
if (lpAppRoster->DoesRecordExist (node_id, entity_id))
|
|
{
|
|
rc = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
DebugExitBOOL(AppRosterManager:IsAPEEnrolled, rc);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* BOOL IsAPEEnrolled ()
|
|
*
|
|
* Public Function Description
|
|
* This function determines if the specified APE is enrolled with
|
|
* a specific session in the list.
|
|
*/
|
|
BOOL CAppRosterMgr::IsAPEEnrolled(
|
|
CSessKeyContainer *session_key_data,
|
|
UserID node_id,
|
|
EntityID entity_id)
|
|
{
|
|
BOOL rc = FALSE;
|
|
CAppRoster *lpAppRoster;
|
|
|
|
DebugEntry(CAppRosterMgr::IsAPEEnrolled);
|
|
|
|
/*
|
|
** First get a single session key. Note that it makes no difference
|
|
** where the key comes from because we are only goin to be comparing
|
|
** the base object key.
|
|
*/
|
|
m_GlobalRosterList.Reset();
|
|
while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
|
|
{
|
|
// We are looking for a session key match
|
|
if (*(lpAppRoster->GetSessionKey()) == *session_key_data)
|
|
{
|
|
// If a match was found check to see if record exist
|
|
rc = lpAppRoster->DoesRecordExist (node_id, entity_id);
|
|
}
|
|
}
|
|
|
|
DebugExitBOOL(AppRosterManager:IsAPEEnrolled, rc);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* GCCError IsEmpty ()
|
|
*
|
|
* Public Function Description
|
|
* This routine determines if this application roster managfer contains
|
|
* any application rosters.
|
|
*/
|
|
BOOL CAppRosterMgr::IsEmpty(void)
|
|
{
|
|
return (m_GlobalRosterList.IsEmpty() && m_LocalRosterList.IsEmpty()) ?
|
|
TRUE : FALSE;
|
|
}
|
|
|
|
/*
|
|
* GCCError SendRosterReportMessage ()
|
|
*
|
|
* Private Function Description
|
|
* This routine is responsible for sending the application roster
|
|
* update indications to the application SAPs.
|
|
*
|
|
* Formal Parameters:
|
|
* None.
|
|
*
|
|
* Return Value
|
|
* GCC_NO_ERROR - No error occured.
|
|
* GCC_ALLOCATION_FAILURE - A resource error occured.
|
|
*
|
|
* Side Effects
|
|
* None.
|
|
*
|
|
* Caveats:
|
|
* We send indications for all rosters. Even roster that don't currently
|
|
* contain records.
|
|
*/
|
|
GCCError CAppRosterMgr::
|
|
SendRosterReportMessage(void)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
CAppRosterMsg *roster_message;
|
|
|
|
DebugEntry(CAppRosterMgr::SendRosterReportMessage);
|
|
|
|
if (! m_GlobalRosterList.IsEmpty())
|
|
{
|
|
// First allocate the roster message
|
|
DBG_SAVE_FILE_LINE
|
|
roster_message = new CAppRosterMsg();
|
|
if (roster_message != NULL)
|
|
{
|
|
CAppRoster *lpAppRoster;
|
|
|
|
m_GlobalRosterList.Reset();
|
|
while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
|
|
{
|
|
roster_message->AddRosterToMessage(lpAppRoster);
|
|
}
|
|
|
|
/*
|
|
** Here we iterate through the complete list of application
|
|
** saps to send the roster report indication. Note that
|
|
** we used the sent list to avoid sending the same roster
|
|
** update to a single SAP more than once. Note that since
|
|
** this sent list is defined as a local instance variable,
|
|
** it automatically is cleaned up after each roster update.
|
|
**
|
|
** Note also that we iterate on a temporary list here in case
|
|
** an application unenrolls (usually due to a resource error)
|
|
** during this callback. We must protect the rogue wave
|
|
** iterator.
|
|
*/
|
|
CAppSap *pAppSap;
|
|
CAppSapList SentList;
|
|
CAppSapEidList2 ToSendList(m_AppSapEidList2);
|
|
ToSendList.Reset();
|
|
while (NULL != (pAppSap = ToSendList.Iterate()))
|
|
{
|
|
if (! SentList.Find(pAppSap))
|
|
{
|
|
/*
|
|
** Hold on to this sap so that we don't send to it
|
|
** again for this update.
|
|
*/
|
|
SentList.Append(pAppSap);
|
|
|
|
// Here we actually deliver the roster update.
|
|
pAppSap->AppRosterReportIndication(m_nConfID, roster_message);
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Here we send the roster report indication to the
|
|
** controler sap.
|
|
*/
|
|
g_pControlSap->AppRosterReportIndication(m_nConfID, roster_message);
|
|
|
|
/*
|
|
** Here we free up the roster message. Note that if this
|
|
** message got locked in the roster report indication calls
|
|
** this free will not delete the roster memory.
|
|
*/
|
|
roster_message->Release();
|
|
}
|
|
else
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
}
|
|
|
|
DebugExitINT(AppRosterManager::SendRosterReportMessage, rc);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* CAppRoster *GetApplicationRoster ()
|
|
*
|
|
* Private Function Description
|
|
* This routine is responsible for returning the application pointer
|
|
* associated with the specified session key.
|
|
*
|
|
* Formal Parameters:
|
|
* session_key - Session key associated with roster to return.
|
|
* roster_list - Roster list to search.
|
|
*
|
|
* Return Value
|
|
* Either NULL if roster does not exists in list or a pointer to
|
|
* the appropriate application roster.
|
|
*
|
|
* Side Effects
|
|
* None.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*/
|
|
CAppRoster * CAppRosterMgr::GetApplicationRoster (
|
|
PGCCSessionKey session_key,
|
|
CAppRosterList *roster_list)
|
|
{
|
|
GCCError rc;
|
|
CAppRoster *application_roster = NULL;
|
|
CAppRoster *lpAppRoster;
|
|
CSessKeyContainer *pTempSessKeyData;
|
|
|
|
DebugEntry(CAppRosterMgr::GetApplicationRoster);
|
|
|
|
// First create a temporary session key for comparison purposes
|
|
DBG_SAVE_FILE_LINE
|
|
pTempSessKeyData = new CSessKeyContainer(session_key, &rc);
|
|
if (pTempSessKeyData != NULL && GCC_NO_ERROR == rc)
|
|
{
|
|
// Now find the affected roster
|
|
|
|
//
|
|
// LONCHANC: The following line is totally wrong!!!
|
|
// we passed in roster_list, but now we overwrite it right here???
|
|
// Commented out the following line.
|
|
// roster_list = m_fTopProvider ? &m_GlobalRosterList : &m_LocalRosterList;
|
|
//
|
|
|
|
roster_list->Reset();
|
|
while (NULL != (lpAppRoster = roster_list->Iterate()))
|
|
{
|
|
if(*lpAppRoster->GetSessionKey() == *pTempSessKeyData)
|
|
{
|
|
application_roster = lpAppRoster;
|
|
break;
|
|
}
|
|
}
|
|
|
|
pTempSessKeyData->Release();
|
|
}
|
|
|
|
DebugExitPTR(AppRosterManager::GetApplicationRoster, application_roster);
|
|
return (application_roster);
|
|
}
|
|
|
|
/*
|
|
* CAppRoster * GetApplicationRosterFromPDU ()
|
|
*
|
|
* Private Function Description
|
|
* This routine is responsible for returning the application pointer
|
|
* associated with the specified session key PDU.
|
|
*
|
|
* Formal Parameters:
|
|
* session_key - Session key PDU associated with roster to return.
|
|
* roster_list - Roster list to search.
|
|
*
|
|
* Return Value
|
|
* Either NULL if roster does not exists in list or a pointer to
|
|
* the appropriate application roster.
|
|
*
|
|
* Side Effects
|
|
* None.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*/
|
|
CAppRoster * CAppRosterMgr::GetApplicationRosterFromPDU (
|
|
PSessionKey session_key,
|
|
CAppRosterList *roster_list)
|
|
{
|
|
CSessKeyContainer *session_key_data;
|
|
CAppRoster *pAppRoster;
|
|
|
|
DebugEntry(CAppRosterMgr::GetApplicationRosterFromPDU);
|
|
|
|
roster_list->Reset();
|
|
while (NULL != (pAppRoster = roster_list->Iterate()))
|
|
{
|
|
session_key_data = pAppRoster->GetSessionKey();
|
|
if (session_key_data->IsThisYourSessionKeyPDU (session_key))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
DebugExitPTR(CAppRosterMgr::GetApplicationRosterFromPDU, pAppRoster);
|
|
|
|
return pAppRoster;
|
|
}
|
|
|
|
/*
|
|
* BOOL IsThisSessionKeyValid ()
|
|
*
|
|
* Private Function Description
|
|
* This routine is responsible for determining if the specified
|
|
* session key's application protocol key matches this application
|
|
* roster manager's. This routine works on API data.
|
|
*
|
|
* Formal Parameters:
|
|
* session_key - Session key to check.
|
|
*
|
|
* Return Value
|
|
* TRUE - If we have a match.
|
|
* FALSE - If we do NOT have a match.
|
|
*
|
|
* Side Effects
|
|
* None.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*/
|
|
|
|
|
|
/*
|
|
* BOOL IsThisSessionKeyPDUValid ()
|
|
*
|
|
* Private Function Description
|
|
* This routine is responsible for determining if the specified
|
|
* session key's application protocol key matches this application
|
|
* roster manager's. This routine works on PDU data.
|
|
*
|
|
* Formal Parameters:
|
|
* session_key - Session key to check.
|
|
*
|
|
* Return Value
|
|
* TRUE - If we have a match.
|
|
* FALSE - If we do NOT have a match.
|
|
*
|
|
* Side Effects
|
|
* None.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*/
|
|
|
|
|
|
/*
|
|
* void CleanupApplicationRosterLists ()
|
|
*
|
|
* Private Function Description
|
|
* This routine is responsible for cleaning up any empty application
|
|
* rosters. It also resets all the application rosters back to their
|
|
* neutral state so that any new updates will be handled correctly.
|
|
*
|
|
* Formal Parameters:
|
|
* None.
|
|
*
|
|
* Return Value
|
|
* None.
|
|
*
|
|
* Side Effects
|
|
* An owner callback will occur when the roster becomes empty.
|
|
*
|
|
* Caveats:
|
|
* This routine does not actually delete the empty rosters until it
|
|
* is placed in the delete list. Instead it places the rosters into the
|
|
* list of deleted rosters which causes them to be deleted the next time
|
|
* this routine is called (or when the object is destructed).
|
|
*/
|
|
void CAppRosterMgr::CleanupApplicationRosterLists(void)
|
|
{
|
|
CAppRoster *lpAppRoster;
|
|
|
|
DebugEntry(CAppRosterMgr::CleanupApplicationRosterLists);
|
|
|
|
/*
|
|
** First we iterate through the list of deleted rosters and delete
|
|
** each entry in it.
|
|
*/
|
|
m_RosterDeleteList.DeleteList();
|
|
|
|
/*
|
|
** Next we iterate through all the rosters and remove any that
|
|
** contain no application records. Here instead of deleting the
|
|
** roster we move the roster into the delete list. We cannot do
|
|
** the delete here because it is possible that PDU data owned by the
|
|
** roster being deleted may be used after the Flush is called (or
|
|
** after this routine is called). Therefore, we save it in the delete
|
|
** list and delete it next time we enter this routine.
|
|
*/
|
|
|
|
// Start with the Global Application Roster List
|
|
m_GlobalRosterList.Reset();
|
|
while (NULL != (lpAppRoster = m_GlobalRosterList.Iterate()))
|
|
{
|
|
if (lpAppRoster->GetNumberOfApplicationRecords() == 0)
|
|
{
|
|
//
|
|
// Here we clean up any "dangling" entries in the application
|
|
// registry by removing all the entries that contain the
|
|
// session key associated with the roster that is being deleted.
|
|
// Note that this is only done when a Global roster list is
|
|
//removed.
|
|
//
|
|
CRegistry *pAppReg = m_pConf->GetRegistry();
|
|
pAppReg->RemoveSessionKeyReference(lpAppRoster->GetSessionKey());
|
|
|
|
m_GlobalRosterList.Remove(lpAppRoster);
|
|
m_RosterDeleteList.Append(lpAppRoster);
|
|
|
|
TRACE_OUT(("AppRosterMgr: Cleanup: Deleting Global Roster"));
|
|
|
|
/*
|
|
** Since you can not delete a list entry while iterating on it
|
|
** we must reset the iterator every time an entry is removed.
|
|
*/
|
|
m_GlobalRosterList.Reset();
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
** Here we reset the application roster to its neutral state.
|
|
** This affects the nodes added and nodes removed flags.
|
|
*/
|
|
lpAppRoster->ResetApplicationRoster();
|
|
}
|
|
}
|
|
|
|
// Next deal with the Local Application Roster List
|
|
if (! m_fTopProvider)
|
|
{
|
|
m_LocalRosterList.Reset();
|
|
while (NULL != (lpAppRoster = m_LocalRosterList.Iterate()))
|
|
{
|
|
if (lpAppRoster->GetNumberOfApplicationRecords() == 0)
|
|
{
|
|
m_LocalRosterList.Remove(lpAppRoster);
|
|
m_RosterDeleteList.Append(lpAppRoster);
|
|
|
|
TRACE_OUT(("AppRosterMgr: Cleanup: Deleting Local Roster"));
|
|
|
|
/*
|
|
** Since you can not delete a list entry while iterating on it
|
|
** we must reset the iterator every time an entry is removed.
|
|
*/
|
|
m_LocalRosterList.Reset();
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
** Here we reset the application roster to its neutral state.
|
|
** This affects the nodes added and nodes removed flags.
|
|
*/
|
|
lpAppRoster->ResetApplicationRoster();
|
|
}
|
|
}
|
|
}
|
|
|
|
DebugExitVOID(CAppRosterMgr::CleanupApplicationRosterLists);
|
|
}
|
|
|
|
/*
|
|
* void DeleteRosterRecord ()
|
|
*
|
|
* Public Function Description
|
|
* This function overides the base class function and is used to
|
|
* receive all owner callback information from the application
|
|
* rosters owned by this object.
|
|
*/
|
|
void CAppRosterMgr::
|
|
DeleteRosterRecord
|
|
(
|
|
GCCNodeID nidRecordToDelete,
|
|
GCCEntityID eidRecordToDelete
|
|
)
|
|
{
|
|
//
|
|
// Here we remove ownership from any registry entries associated
|
|
// with the record that was deleted. Note that since the entity
|
|
// id must be unique for all the APEs at a node (as stated by
|
|
// T.124) there is no need to include the session key to determine
|
|
// which registry entries to clean up.
|
|
//
|
|
CRegistry *pAppReg = m_pConf->GetRegistry();
|
|
pAppReg->RemoveEntityOwnership(nidRecordToDelete, eidRecordToDelete);
|
|
}
|
|
|
|
|
|
void CAppRosterMgrList::DeleteList(void)
|
|
{
|
|
CAppRosterMgr *pAppRosterMgr;
|
|
while (NULL != (pAppRosterMgr = Get()))
|
|
{
|
|
pAppRosterMgr->Release();
|
|
}
|
|
}
|
|
|