6624 lines
176 KiB
C++
6624 lines
176 KiB
C++
#include "precomp.h"
|
||
DEBUG_FILEZONE(ZONE_T120_GCCNC);
|
||
/*
|
||
* mcsuser.cpp
|
||
*
|
||
* Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
|
||
*
|
||
* Abstract:
|
||
* This is the implemntation file for the MCSUser class. It implements
|
||
* functions responsible for encoding out bound indirect conference
|
||
* join request and response PDUs, and also Send user ID Requests. All
|
||
* these PDUs are encapsulated in user data field of MCSSendDataRequest.
|
||
* Also this file implements functions that are responsible for decoding
|
||
* incoming indications and confirm PDUs which are encapsulated in the
|
||
* user data field of MCSSendDataIndication. Functions responsible for
|
||
* joining different channels are also implemented in this module.
|
||
*
|
||
* SEE THE INTERFACE FILE FOR A MORE DETAILED DESCRIPTION OF THIS CLASS.
|
||
*
|
||
* Private Instance Variables
|
||
* m_pMCSSap
|
||
* This is the MCS User handle handed back from the MCS Attache User
|
||
* Request.
|
||
* m_nidMyself
|
||
* The is the MCS User ID returned in the Attach User Confirm. This
|
||
* is also refered to as the Node ID with in GCC.
|
||
* m_nidTopProvider
|
||
* This holds the MCS User ID (or Node ID) for the top Provider.
|
||
* m_nidParent
|
||
* This holds the MCS User ID (or Node ID) for this nodes parent node.
|
||
* m_fEjectionPending
|
||
* This flag indicates if an ejection of this node is pending.
|
||
* m_eEjectReason
|
||
* This variable holds the reason for ejection until the eject
|
||
* indication can be delivered after all child nodes have disconnected.
|
||
* m_pOwnerConf
|
||
* Pointer to the object that will receive all the owner callbacks
|
||
* from the user object (typically the conference object).
|
||
* m_ChannelJoinedFlags
|
||
* A structure of flags used to keep up with creation state machine.
|
||
* Basically, it keeps up with which channels have been joined and
|
||
* which ones have not.
|
||
* m_ChildUidConnHdlList2
|
||
* Keeps mapping of child Node IDs to child logical connection
|
||
* handles.
|
||
* m_OutgoingPDUQueue
|
||
* This is a rogue wave list used to queue up all outgoing PDUs.
|
||
* m_ConfJoinResponseList2
|
||
* This rogue wave list holds information needed to send back in a join
|
||
* response after the local node controller responds.
|
||
* m_EjectedNodeAlarmList2
|
||
* This list holds alarm objects for all the nodes that have been
|
||
* ejected and are directly connected to this node. The alarm is
|
||
* used to disconnect any misbehaving nodes that do not disconnect
|
||
* after the EJECTED_NODE_TIMER_DURATION.
|
||
* m_EjectedNodeList
|
||
* This list keeps up with nodes that have been ejected but are NOT
|
||
* directly connected to this node. We save these nodes so that
|
||
* a correct reason for disconnecting (user ejected) can be issued
|
||
* when the detch user indication comes in.
|
||
*
|
||
* Author:
|
||
* blp
|
||
*/
|
||
|
||
#include "mcsuser.h"
|
||
#include "mcsdllif.h"
|
||
#include "ogcccode.h"
|
||
#include "conf.h"
|
||
#include "translat.h"
|
||
#include "gcontrol.h"
|
||
|
||
// Static Channel and Token ID definitions used by the MCS user object.
|
||
#define BROADCAST_CHANNEL_ID 1
|
||
#define CONVENER_CHANNEL_ID 2
|
||
#define CONDUCTOR_TOKEN_ID 1
|
||
|
||
// Time given to allow an ejected node to disconnect before it is disconnected
|
||
#define EJECTED_NODE_TIMER_DURATION 10000 // Duration in milliseconds
|
||
|
||
|
||
extern MCSDLLInterface *g_pMCSIntf;
|
||
|
||
/*
|
||
* This is a global variable that has a pointer to the one GCC coder that
|
||
* is instantiated by the GCC Controller. Most objects know in advance
|
||
* whether they need to use the MCS or the GCC coder, so, they do not need
|
||
* this pointer in their constructors.
|
||
*/
|
||
extern CGCCCoder *g_GCCCoder;
|
||
|
||
/*
|
||
* MCSUser ()
|
||
*
|
||
* Public Function Description
|
||
* This is the MCSUser object constructor. It is responsible for
|
||
* initializing all the instance variables used by this class. The
|
||
* constructor is responsible for establishing the user attachment to
|
||
* the MCS domain defined by the conference ID. It also kicks off the
|
||
* process of joining all the appropriate channels.
|
||
*/
|
||
MCSUser::
|
||
MCSUser(CConf *pConf,
|
||
GCCNodeID nidTopProvider,
|
||
GCCNodeID nidParent,
|
||
PGCCError return_value)
|
||
:
|
||
CRefCount(MAKE_STAMP_ID('M','U','s','r')),
|
||
m_ChildUidConnHdlList2(),
|
||
m_EjectedNodeAlarmList2(),
|
||
m_EjectedNodeList(),
|
||
m_pConf(pConf),
|
||
m_nidTopProvider(nidTopProvider),
|
||
m_nidParent(nidParent),
|
||
m_nidMyself(NULL),
|
||
m_fEjectionPending(FALSE)
|
||
{
|
||
MCSError mcs_rc;
|
||
GCCConfID nConfID = pConf->GetConfID();
|
||
|
||
// No channels are joined initially
|
||
m_ChannelJoinedFlags.user_channel_joined = FALSE;
|
||
m_ChannelJoinedFlags.broadcast_channel_joined = FALSE;
|
||
m_ChannelJoinedFlags.convener_channel_joined = FALSE;
|
||
m_ChannelJoinedFlags.channel_join_error = FALSE;
|
||
|
||
mcs_rc = g_pMCSIntf->AttachUserRequest(&nConfID, &m_pMCSSap, this);
|
||
if (MCS_NO_ERROR != mcs_rc)
|
||
{
|
||
WARNING_OUT(("MCSUser::MCSUser: Failure in attach user req, "));
|
||
*return_value = GCC_FAILURE_ATTACHING_TO_MCS;
|
||
}
|
||
else
|
||
{
|
||
*return_value = GCC_NO_ERROR;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* ~MCSUser ()
|
||
*
|
||
* Public Function Description
|
||
* This is the user destructor. It takes care of leaving channels
|
||
* joined by the user object. Also it detaches the user attachment
|
||
* with MCS by issuing a detach user request.
|
||
*/
|
||
MCSUser::~MCSUser(void)
|
||
{
|
||
// Clean up the Ejected Node Alarm List
|
||
PAlarm lpAlarm;
|
||
while (NULL != (lpAlarm = m_EjectedNodeAlarmList2.Get()))
|
||
{
|
||
delete lpAlarm;
|
||
}
|
||
|
||
if(m_ChannelJoinedFlags.user_channel_joined)
|
||
{
|
||
g_pMCSIntf->ChannelLeaveRequest(m_nidMyself, m_pMCSSap);
|
||
}
|
||
|
||
if(m_ChannelJoinedFlags.broadcast_channel_joined)
|
||
{
|
||
g_pMCSIntf->ChannelLeaveRequest(BROADCAST_CHANNEL_ID, m_pMCSSap);
|
||
}
|
||
|
||
if(m_ChannelJoinedFlags.convener_channel_joined)
|
||
{
|
||
g_pMCSIntf->ChannelLeaveRequest(CONVENER_CHANNEL_ID, m_pMCSSap);
|
||
}
|
||
|
||
// Empty the queue of all PDUs
|
||
SEND_DATA_REQ_INFO *pReqInfo;
|
||
m_OutgoingPDUQueue.Reset();
|
||
while (NULL != (pReqInfo = m_OutgoingPDUQueue.Iterate()))
|
||
{
|
||
pReqInfo->packet->Unlock();
|
||
delete pReqInfo;
|
||
}
|
||
|
||
g_pMCSIntf->DetachUserRequest(m_pMCSSap, this);
|
||
}
|
||
|
||
/*
|
||
* UINT ProcessAttachUserConfirm ()
|
||
*
|
||
* Private Function Description
|
||
* This function is called when the user object gets an attach user
|
||
* confirm from MCS in response to an attach user request made by the
|
||
* user object in it's constructor. The function checks the result
|
||
* indicated in the confirm. If the result is a successful attachment, then
|
||
* different channels depending upon the type of the provider, are joined.
|
||
* Also this function reports failures in attach user (as indicated by
|
||
* result in attach user confirm) and channel joins, to the conference
|
||
* through an owner callback.
|
||
*
|
||
* Formal Parameters:
|
||
* result - (i) Result of the attach user request.
|
||
* user_id - (i) This nodes user or Node ID if successful result.
|
||
*
|
||
* Return Value
|
||
* MCS_NO_ERROR - No error is always returned.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
UINT MCSUser::ProcessAttachUserConfirm(Result result, UserID user_id)
|
||
{
|
||
UINT rc;
|
||
|
||
if (result == RESULT_SUCCESSFUL)
|
||
{
|
||
m_nidMyself = user_id;
|
||
|
||
/*
|
||
** After the attach confirm is received we go ahead and join the
|
||
** appropriate channel based on the conf node type. If this
|
||
** node is the yop provider we also set up the top provider user id,
|
||
** otherwise this gets set up in the constructor.
|
||
*/
|
||
switch (m_pConf->GetConfNodeType())
|
||
{
|
||
case TOP_PROVIDER_NODE:
|
||
m_nidTopProvider = m_nidMyself;
|
||
rc = JoinUserAndBroadCastChannels();
|
||
break;
|
||
|
||
case JOINED_CONVENER_NODE:
|
||
case CONVENER_NODE:
|
||
rc = JoinUserAndBroadCastChannels();
|
||
if(rc == MCS_NO_ERROR)
|
||
{
|
||
rc = JoinConvenerChannel();
|
||
}
|
||
break;
|
||
|
||
case TOP_PROVIDER_AND_CONVENER_NODE:
|
||
m_nidTopProvider = m_nidMyself;
|
||
rc = JoinUserAndBroadCastChannels();
|
||
if(rc == MCS_NO_ERROR)
|
||
{
|
||
rc = JoinConvenerChannel();
|
||
}
|
||
break;
|
||
|
||
case JOINED_NODE:
|
||
case INVITED_NODE:
|
||
rc = JoinUserAndBroadCastChannels();
|
||
break;
|
||
|
||
default:
|
||
ERROR_OUT(("User::ProcessAttachUserConfirm: Bad Node Type, %u", (UINT) m_pConf->GetConfNodeType()));
|
||
break;
|
||
}
|
||
|
||
if (rc != MCS_NO_ERROR)
|
||
{
|
||
/*
|
||
* ChannelJoinRequestFailed at some level in MCS
|
||
* So this message tells the conferenceabout this
|
||
* failure. Conference will delete the user object
|
||
* as a result of this
|
||
*/
|
||
m_pConf->ProcessUserCreateConfirm(USER_CHANNEL_JOIN_FAILURE, m_nidMyself);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* Attach user request failed as indicated by the result field in the
|
||
* confirm message, because of any of the following causes:
|
||
* congested, domain disconnected, no such domain, too many channels,
|
||
* too many users, unspecified failure. In this case the user object
|
||
* just sends the conference a GCC_USER_ATTACH_FAILURE ( to be defined
|
||
* in command target.h) , which causes
|
||
* the conference object to delete the user attachment.
|
||
* UserCreateConfirm message is not corresponding exectly to a single
|
||
* primitive.
|
||
*/
|
||
WARNING_OUT(("MCSUser::ProcessAttachUserConfirm: ATTACH FAILED"));
|
||
m_pConf->ProcessUserCreateConfirm(USER_ATTACH_FAILURE, m_nidMyself);
|
||
}
|
||
|
||
return (MCS_NO_ERROR);
|
||
}
|
||
|
||
/*
|
||
* MCSError JoinUserAndBroadCastChannels()
|
||
*
|
||
* Private Function Description
|
||
* This function is called by user object when it gets a successful
|
||
* attach user confrim, to join user id and broadcast channels.
|
||
* If the channel join requests fail, it returns the appropriate MCS
|
||
* Error.
|
||
*
|
||
* Formal Parameters:
|
||
* None.
|
||
*
|
||
* Return Value
|
||
* See return values for mcs channel jon request.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
|
||
MCSError MCSUser::JoinUserAndBroadCastChannels()
|
||
{
|
||
MCSError rc;
|
||
|
||
rc = g_pMCSIntf->ChannelJoinRequest(m_nidMyself, m_pMCSSap);
|
||
if(rc == MCS_NO_ERROR)
|
||
|
||
{
|
||
rc = g_pMCSIntf->ChannelJoinRequest(BROADCAST_CHANNEL_ID, m_pMCSSap);
|
||
}
|
||
|
||
return (rc);
|
||
}
|
||
|
||
/*
|
||
* MCSError JoinUserAndBroadCastChannels()
|
||
*
|
||
* Private Function Description
|
||
* This function is called by user object of a convener gcc provider
|
||
* when it gets a successful attach user confrim, to join convener
|
||
* channel. If the channel join requests fail, it returns the appropriate
|
||
* MCS Error.
|
||
*
|
||
* Formal Parameters:
|
||
* None.
|
||
*
|
||
* Return Value
|
||
* See return values for mcs channel jon request.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
MCSError MCSUser::JoinConvenerChannel()
|
||
{
|
||
return g_pMCSIntf->ChannelJoinRequest(CONVENER_CHANNEL_ID, m_pMCSSap);
|
||
}
|
||
|
||
/*
|
||
* UINT ProcessChannelJoinConfirm()
|
||
*
|
||
* Private Function Description
|
||
* This function is called when the user object gets an channel join
|
||
* confirm from MCS in response to channel join requests made by the
|
||
* user object. If a channel is joined successfully as indicated by
|
||
* the result in the confirm, a channel joined flag corresponding to
|
||
* that channel id is set. This flag indicates as to which channels a
|
||
* user object is joined at any given time. Also after setting this
|
||
* flag the functions checks to see if all tke required channels based
|
||
* on the type of gcc provider, are joined. If all required channels are
|
||
* joined the conference object is informaed about it via an owner call-
|
||
* back (USER_CREATE_CONFIRM).
|
||
*
|
||
* Formal Parameters:
|
||
* result - (i) Result of the channel join request.
|
||
* channel_id - (i) Channel ID that this confirm pertains to.
|
||
*
|
||
* Return Value
|
||
* MCS_NO_ERROR is always returned.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
UINT MCSUser::ProcessChannelJoinConfirm(Result result, ChannelID channel_id)
|
||
{
|
||
if (m_ChannelJoinedFlags.channel_join_error == FALSE)
|
||
{
|
||
if (result == RESULT_SUCCESSFUL)
|
||
{
|
||
if( channel_id == m_nidMyself)
|
||
{
|
||
m_ChannelJoinedFlags.user_channel_joined = TRUE;
|
||
}
|
||
else
|
||
{
|
||
switch (channel_id)
|
||
{
|
||
case CONVENER_CHANNEL_ID:
|
||
m_ChannelJoinedFlags.convener_channel_joined = TRUE;
|
||
break;
|
||
|
||
case BROADCAST_CHANNEL_ID:
|
||
m_ChannelJoinedFlags.broadcast_channel_joined = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
/*
|
||
** If all the channels are joined we inform the owner object that
|
||
** the user object was successfully created.
|
||
*/
|
||
if (AreAllChannelsJoined())
|
||
{
|
||
m_pConf->ProcessUserCreateConfirm(USER_RESULT_SUCCESSFUL, m_nidMyself);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
WARNING_OUT(("MCSUser::ProcessChannelJoinConfirm: Error joining channel, result=%u", (UINT) result));
|
||
|
||
m_ChannelJoinedFlags.channel_join_error = TRUE ;
|
||
|
||
m_pConf->ProcessUserCreateConfirm(USER_CHANNEL_JOIN_FAILURE, m_nidMyself);
|
||
}
|
||
}
|
||
|
||
return (MCS_NO_ERROR);
|
||
}
|
||
|
||
/*
|
||
* BOOL AreAllChannelsJoined()
|
||
*
|
||
* Public Function Description
|
||
* This function is called to check if all tke required channels based
|
||
* on the type of gcc provider, are joined. It returns true if all
|
||
* required channels are joined and false otherwise. This function uses
|
||
* different channel joined flags to check which channels the given user
|
||
* object is joined to.
|
||
*
|
||
* Formal Parameters:
|
||
* None.
|
||
*
|
||
* Return Value
|
||
* TRUE - If all channels are joined.
|
||
* FALSE - If all the channels are not joined.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
BOOL MCSUser::AreAllChannelsJoined(void)
|
||
{
|
||
BOOL rc = FALSE;
|
||
|
||
switch (m_pConf->GetConfNodeType())
|
||
{
|
||
case TOP_PROVIDER_NODE:
|
||
if ((m_ChannelJoinedFlags.user_channel_joined) &&
|
||
(m_ChannelJoinedFlags.broadcast_channel_joined))
|
||
{
|
||
rc = TRUE;
|
||
}
|
||
break;
|
||
|
||
case JOINED_CONVENER_NODE:
|
||
case CONVENER_NODE:
|
||
if ((m_ChannelJoinedFlags.convener_channel_joined) &&
|
||
(m_ChannelJoinedFlags.user_channel_joined) &&
|
||
(m_ChannelJoinedFlags.broadcast_channel_joined))
|
||
{
|
||
rc = TRUE;
|
||
}
|
||
break;
|
||
|
||
case TOP_PROVIDER_AND_CONVENER_NODE:
|
||
if ((m_ChannelJoinedFlags.convener_channel_joined) &&
|
||
(m_ChannelJoinedFlags.user_channel_joined) &&
|
||
(m_ChannelJoinedFlags.broadcast_channel_joined))
|
||
{
|
||
rc = TRUE;
|
||
}
|
||
break;
|
||
|
||
case JOINED_NODE:
|
||
case INVITED_NODE:
|
||
if( (m_ChannelJoinedFlags.user_channel_joined) &&
|
||
(m_ChannelJoinedFlags.broadcast_channel_joined))
|
||
{
|
||
rc = TRUE;
|
||
}
|
||
break;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* void SendUserIDRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This request originates from the conference object. Conference object
|
||
* sends the sequence number obtained in the conference create confirm
|
||
* or conference join confirm to the parent GCC provider on the parent
|
||
* gcc provider's UserId channel. The pdu is encoded here and is
|
||
* queued to be sent during the next heartbeat.
|
||
*/
|
||
void MCSUser::SendUserIDRequest(TagNumber tag_number)
|
||
{
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
/*
|
||
** Fill in the UserIDIndication pdu structure to be passed in the
|
||
** constructor of the packet class.
|
||
*/
|
||
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = USER_ID_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.user_id_indication.tag = tag_number;
|
||
|
||
/*
|
||
** Create a packet object
|
||
*/
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU, // pdu_type
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidParent, TOP_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* GCCError ConferenceJoinRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This call is made by the conference object of the intermediate node
|
||
* to forward the conference join request over to the top provider. This
|
||
* function encodes the conference join request pdu and queues it to be
|
||
* sent in the next heartbeat.
|
||
*
|
||
* Caveats
|
||
* The connection handle is used here for a TAG and should be passed back
|
||
* to the owner object when the join response comes in.
|
||
*/
|
||
GCCError MCSUser::ConferenceJoinRequest(
|
||
CPassword *convener_password,
|
||
CPassword *password_challenge,
|
||
LPWSTR pwszCallerID,
|
||
CUserDataListContainer *user_data_list,
|
||
ConnectionHandle connection_handle)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
// Encode the PDU that will be forwarded to the top provider.
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = CONFERENCE_JOIN_REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.u.conference_join_request.tag = (TagNumber)connection_handle;
|
||
gcc_pdu.u.request.u.conference_join_request.bit_mask = TAG_PRESENT;
|
||
|
||
// Insert the convener password into the ASN.1 structure
|
||
if (convener_password != NULL)
|
||
{
|
||
rc = convener_password->GetPasswordSelectorPDU(
|
||
&gcc_pdu.u.request.u.conference_join_request.cjrq_convener_password);
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.request.u.conference_join_request.bit_mask |= CJRQ_CONVENER_PASSWORD_PRESENT;
|
||
}
|
||
}
|
||
|
||
// Insert the password challenge into the ASN.1 structure
|
||
if (( password_challenge != NULL ) && (rc == GCC_NO_ERROR))
|
||
{
|
||
rc = password_challenge->GetPasswordChallengeResponsePDU (
|
||
&gcc_pdu.u.request.u.conference_join_request.
|
||
cjrq_password);
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.request.u.conference_join_request.bit_mask |=
|
||
CJRQ_PASSWORD_PRESENT;
|
||
}
|
||
}
|
||
|
||
// Insert the caller identifier into the ASN.1 structure
|
||
UINT cchCallerID = ::My_strlenW(pwszCallerID);
|
||
if ((cchCallerID != 0 ) && (rc == GCC_NO_ERROR))
|
||
{
|
||
gcc_pdu.u.request.u.conference_join_request.cjrq_caller_id.value = pwszCallerID;
|
||
gcc_pdu.u.request.u.conference_join_request.cjrq_caller_id.length = cchCallerID;
|
||
gcc_pdu.u.request.u.conference_join_request.bit_mask |= CJRQ_CALLER_ID_PRESENT;
|
||
}
|
||
|
||
// Insert the user data into the ASN.1 structure
|
||
if (( user_data_list != NULL ) && (rc == GCC_NO_ERROR))
|
||
{
|
||
rc = user_data_list->GetUserDataPDU (
|
||
&gcc_pdu.u.request.u.conference_join_request.cjrq_user_data);
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.request.u.conference_join_request.bit_mask |= CJRQ_USER_DATA_PRESENT;
|
||
}
|
||
}
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, TOP_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
// Cleanup after any errors
|
||
if (rc == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError SendConferenceLockRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This function is invoked by the owner object to send a conference lock
|
||
* request PDU to the top provider.
|
||
*/
|
||
GCCError MCSUser::SendConferenceLockRequest()
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = CONFERENCE_LOCK_REQUEST_CHOSEN;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError SendConferenceLockResponse()
|
||
*
|
||
* Public Function Description:
|
||
* This function is invoked by the owner object to send a conference lock
|
||
* response PDU to the requesting node.
|
||
*/
|
||
GCCError MCSUser::SendConferenceLockResponse (
|
||
UserID source_node,
|
||
GCCResult result)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
gcc_pdu.choice = RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.choice = CONFERENCE_LOCK_RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.u.conference_lock_response.result =
|
||
::TranslateGCCResultToLockResult(result);
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, source_node, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError SendConferenceUnlockRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This function is invoked by the owner object to send a conference unlock
|
||
* request PDU to the top provider.
|
||
*/
|
||
GCCError MCSUser::SendConferenceUnlockRequest ()
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = CONFERENCE_UNLOCK_REQUEST_CHOSEN;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError SendConferenceUnlockResponse()
|
||
*
|
||
* Public Function Description:
|
||
* This function is invoked by the owner object to send a conference unlock
|
||
* response PDU to the requesting node.
|
||
*/
|
||
GCCError MCSUser::SendConferenceUnlockResponse (
|
||
UserID source_node,
|
||
GCCResult result)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
gcc_pdu.choice = RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.choice = CONFERENCE_UNLOCK_RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.u.conference_unlock_response.result =
|
||
::TranslateGCCResultToUnlockResult(result);
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, source_node, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError SendConferenceLockIndication()
|
||
*
|
||
* Public Function Description:
|
||
* This function is invoked by the owner object of the top provider
|
||
* to send a conference lock indication PDU to one or all other nodes
|
||
* that are registered in the conference.
|
||
*/
|
||
GCCError MCSUser::SendConferenceLockIndication(
|
||
BOOL uniform_send,
|
||
UserID source_node)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONFERENCE_LOCK_INDICATION_CHOSEN;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(
|
||
packet,
|
||
uniform_send ? BROADCAST_CHANNEL_ID : source_node,
|
||
HIGH_PRIORITY,
|
||
uniform_send);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError SendConferenceUnlockIndication()
|
||
*
|
||
* Public Function Description:
|
||
* This function is invoked by the owner object of the top provider
|
||
* to send a conference unlock indication PDU to one or all other nodes
|
||
* that are registered in the conference.
|
||
*/
|
||
GCCError MCSUser::SendConferenceUnlockIndication(
|
||
BOOL uniform_send,
|
||
UserID source_node)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONFERENCE_UNLOCK_INDICATION_CHOSEN;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(
|
||
packet,
|
||
uniform_send ? BROADCAST_CHANNEL_ID : source_node,
|
||
HIGH_PRIORITY,
|
||
uniform_send);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/******************************* Registry Calls ******************************/
|
||
|
||
/*
|
||
* void RegistryRegisterChannelRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used when an APE wishes to register a channel in
|
||
* the application registry.
|
||
*/
|
||
void MCSUser::RegistryRegisterChannelRequest(
|
||
CRegKeyContainer *registry_key_data,
|
||
ChannelID channel_id,
|
||
EntityID entity_id)
|
||
{
|
||
GCCError error_value;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
// Encode the PDU that will be forwarded to the top provider.
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = REGISTRY_REGISTER_CHANNEL_REQUEST_CHOSEN;
|
||
|
||
error_value = registry_key_data->GetRegistryKeyDataPDU(
|
||
&gcc_pdu.u.request.u.
|
||
registry_register_channel_request.key);
|
||
|
||
if (error_value == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.request.u.registry_register_channel_request.channel_id =
|
||
channel_id;
|
||
gcc_pdu.u.request.u.registry_register_channel_request.entity_id =
|
||
entity_id;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser::RegistryRegisterChannelRequest: Error creating packet"));
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
registry_key_data->FreeRegistryKeyDataPDU();
|
||
}
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* MCSUser::RegistryAssignTokenRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used when an APE wishes to register a token in
|
||
* the application registry. Note that there is no token ID included in
|
||
* this request. The token ID is allocated at the top provider.
|
||
*/
|
||
void MCSUser::RegistryAssignTokenRequest (
|
||
CRegKeyContainer *registry_key_data,
|
||
EntityID entity_id)
|
||
{
|
||
GCCError error_value;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
// Encode the PDU that will be forwarded to the top provider.
|
||
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = REGISTRY_ASSIGN_TOKEN_REQUEST_CHOSEN;
|
||
|
||
|
||
error_value = registry_key_data->GetRegistryKeyDataPDU(
|
||
&gcc_pdu.u.request.u.
|
||
registry_assign_token_request.registry_key);
|
||
|
||
if (error_value == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.request.u.registry_assign_token_request.entity_id = entity_id;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
registry_key_data->FreeRegistryKeyDataPDU();
|
||
}
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void RegistrySetParameterRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used when an APE wishes to register a parameter in
|
||
* the application registry. Note that parameter to be registered is
|
||
* included in this request.
|
||
*/
|
||
void MCSUser::RegistrySetParameterRequest (
|
||
CRegKeyContainer *registry_key_data,
|
||
LPOSTR parameter_value,
|
||
GCCModificationRights modification_rights,
|
||
EntityID entity_id)
|
||
{
|
||
GCCError error_value;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
// Encode the PDU that will be forwarded to the top provider.
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = REGISTRY_SET_PARAMETER_REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.u.registry_set_parameter_request.bit_mask = 0;
|
||
|
||
error_value = registry_key_data->GetRegistryKeyDataPDU(
|
||
&gcc_pdu.u.request.u.
|
||
registry_set_parameter_request.key);
|
||
|
||
if (error_value == GCC_NO_ERROR)
|
||
{
|
||
if (parameter_value != NULL)
|
||
{
|
||
gcc_pdu.u.request.u.registry_set_parameter_request.
|
||
registry_set_parameter.length =
|
||
parameter_value->length;
|
||
|
||
memcpy (gcc_pdu.u.request.u.registry_set_parameter_request.
|
||
registry_set_parameter.value,
|
||
parameter_value->value,
|
||
parameter_value->length);
|
||
}
|
||
else
|
||
{
|
||
gcc_pdu.u.request.u.registry_set_parameter_request.
|
||
registry_set_parameter.length = 0;
|
||
}
|
||
|
||
gcc_pdu.u.request.u.registry_set_parameter_request.entity_id =
|
||
entity_id;
|
||
|
||
// Set up the modification rights here if it exists
|
||
if (modification_rights != GCC_NO_MODIFICATION_RIGHTS_SPECIFIED)
|
||
{
|
||
gcc_pdu.u.request.u.registry_set_parameter_request.bit_mask |=
|
||
PARAMETER_MODIFY_RIGHTS_PRESENT;
|
||
|
||
gcc_pdu.u.request.u.registry_set_parameter_request.
|
||
parameter_modify_rights =
|
||
(RegistryModificationRights)modification_rights;
|
||
}
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
registry_key_data->FreeRegistryKeyDataPDU();
|
||
}
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void RegistryRetrieveEntryRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used when an APE wishes to retrieve an registry item
|
||
* from the registry.
|
||
*/
|
||
void MCSUser::RegistryRetrieveEntryRequest (
|
||
CRegKeyContainer *registry_key_data,
|
||
EntityID entity_id)
|
||
{
|
||
GCCError error_value;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
// Encode the PDU that will be forwarded to the top provider.
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = REGISTRY_RETRIEVE_ENTRY_REQUEST_CHOSEN;
|
||
|
||
error_value = registry_key_data->GetRegistryKeyDataPDU(
|
||
&gcc_pdu.u.request.u.
|
||
registry_retrieve_entry_request.key);
|
||
if (error_value == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.request.u.registry_retrieve_entry_request.entity_id =
|
||
entity_id;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
registry_key_data->FreeRegistryKeyDataPDU();
|
||
}
|
||
else
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void RegistryDeleteEntryRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used when an APE wishes to delete a registry item
|
||
* from the registry.
|
||
*/
|
||
void MCSUser::RegistryDeleteEntryRequest (
|
||
CRegKeyContainer *registry_key_data,
|
||
EntityID entity_id)
|
||
{
|
||
GCCError error_value;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
// Encode the PDU that will be forwarded to the top provider.
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = REGISTRY_DELETE_ENTRY_REQUEST_CHOSEN;
|
||
|
||
error_value = registry_key_data->GetRegistryKeyDataPDU(
|
||
&gcc_pdu.u.request.u.
|
||
registry_delete_entry_request.key);
|
||
|
||
if (error_value == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.request.u.registry_delete_entry_request.entity_id = entity_id;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
registry_key_data->FreeRegistryKeyDataPDU();
|
||
}
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void RegistryMonitorRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used when an APE wishes to monitor a registry item
|
||
* in the registry.
|
||
*/
|
||
void MCSUser::RegistryMonitorRequest (
|
||
CRegKeyContainer *registry_key_data,
|
||
EntityID entity_id)
|
||
{
|
||
GCCError error_value;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
// Encode the PDU that will be forwarded to the top provider.
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = REGISTRY_MONITOR_ENTRY_REQUEST_CHOSEN;
|
||
|
||
error_value = registry_key_data->GetRegistryKeyDataPDU(
|
||
&gcc_pdu.u.request.u.
|
||
registry_monitor_entry_request.key);
|
||
|
||
if (error_value == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.request.u.registry_monitor_entry_request.entity_id= entity_id;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
registry_key_data->FreeRegistryKeyDataPDU();
|
||
}
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void RegistryAllocateHandleRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used when an APE wishes to allocate a number of
|
||
* handles from the application registry.
|
||
*/
|
||
void MCSUser::RegistryAllocateHandleRequest(
|
||
UINT number_of_handles,
|
||
EntityID entity_id )
|
||
{
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
// Encode the PDU that will be forwarded to the top provider.
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = REGISTRY_ALLOCATE_HANDLE_REQUEST_CHOSEN;
|
||
|
||
gcc_pdu.u.request.u.registry_allocate_handle_request.number_of_handles = (USHORT) number_of_handles;
|
||
gcc_pdu.u.request.u.registry_allocate_handle_request.entity_id= entity_id;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void RegistryAllocateHandleResponse()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used by the Top Provider to respond to an allocate
|
||
* handle request from an APE at a remote node. The allocated handles
|
||
* are passed back here.
|
||
*/
|
||
void MCSUser::RegistryAllocateHandleResponse (
|
||
UINT number_of_handles,
|
||
UINT registry_handle,
|
||
EntityID requester_entity_id,
|
||
UserID requester_node_id,
|
||
GCCResult result)
|
||
{
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
// Encode the PDU that will be forwarded to the top provider.
|
||
gcc_pdu.choice = RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.choice = REGISTRY_ALLOCATE_HANDLE_RESPONSE_CHOSEN;
|
||
|
||
gcc_pdu.u.response.u.registry_allocate_handle_response.number_of_handles = (USHORT) number_of_handles;
|
||
gcc_pdu.u.response.u.registry_allocate_handle_response.entity_id = requester_entity_id;
|
||
gcc_pdu.u.response.u.registry_allocate_handle_response.first_handle = (Handle) registry_handle;
|
||
|
||
if (result == GCC_RESULT_SUCCESSFUL)
|
||
{
|
||
gcc_pdu.u.response.u.registry_allocate_handle_response.result = RARS_RESULT_SUCCESS;
|
||
}
|
||
else
|
||
{
|
||
gcc_pdu.u.response.u.registry_allocate_handle_response.result = NO_HANDLES_AVAILABLE;
|
||
}
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, requester_node_id, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void RegistryResponse()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used to respond to all the registry request except
|
||
* allocate handle. It formulates the response PDU and queues it for
|
||
* delivery.
|
||
*/
|
||
void MCSUser::RegistryResponse (
|
||
RegistryResponsePrimitiveType primitive_type,
|
||
UserID requester_owner_id,
|
||
EntityID requester_entity_id,
|
||
CRegKeyContainer *registry_key_data,
|
||
CRegItem *registry_item_data,
|
||
GCCModificationRights modification_rights,
|
||
UserID entry_owner_id,
|
||
EntityID entry_entity_id,
|
||
GCCResult result)
|
||
{
|
||
GCCError error_value;
|
||
GCCPDU gcc_pdu;
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
|
||
DebugEntry(MCSUser::RegistryResponse);
|
||
|
||
/*
|
||
** Encode the conference join response PDU, along with the sequence
|
||
** number.
|
||
*/
|
||
gcc_pdu.choice = RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.choice = REGISTRY_RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.u.registry_response.bit_mask = 0;
|
||
|
||
error_value = registry_key_data->GetRegistryKeyDataPDU(&gcc_pdu.u.response.u.registry_response.key);
|
||
if (error_value == GCC_NO_ERROR)
|
||
{
|
||
if (registry_item_data != NULL)
|
||
{
|
||
registry_item_data->GetRegistryItemDataPDU(&gcc_pdu.u.response.u.registry_response.item);
|
||
}
|
||
else
|
||
{
|
||
gcc_pdu.u.response.u.registry_response.item.choice = VACANT_CHOSEN;
|
||
}
|
||
|
||
TRACE_OUT(("MCSUser: RegistryResponse: item_type=%d", (UINT) gcc_pdu.u.response.u.registry_response.item.choice));
|
||
|
||
// Set up the entry owner
|
||
if (entry_owner_id != 0)
|
||
{
|
||
gcc_pdu.u.response.u.registry_response.owner.choice = OWNED_CHOSEN;
|
||
gcc_pdu.u.response.u.registry_response.owner.u.owned.node_id = entry_owner_id;
|
||
gcc_pdu.u.response.u.registry_response.owner.u.owned.entity_id = entry_entity_id;
|
||
}
|
||
else
|
||
{
|
||
gcc_pdu.u.response.u.registry_response.owner.choice = NOT_OWNED_CHOSEN;
|
||
}
|
||
|
||
// Set up the requesters entity ID
|
||
gcc_pdu.u.response.u.registry_response.entity_id = requester_entity_id;
|
||
|
||
// Set up the primitive type
|
||
gcc_pdu.u.response.u.registry_response.primitive_type = primitive_type;
|
||
|
||
gcc_pdu.u.response.u.registry_response.result =
|
||
::TranslateGCCResultToRegistryResp(result);
|
||
|
||
if (modification_rights != GCC_NO_MODIFICATION_RIGHTS_SPECIFIED)
|
||
{
|
||
gcc_pdu.u.response.u.registry_response.bit_mask |=
|
||
RESPONSE_MODIFY_RIGHTS_PRESENT;
|
||
|
||
gcc_pdu.u.response.u.registry_response.response_modify_rights =
|
||
(RegistryModificationRights)modification_rights;
|
||
}
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, requester_owner_id, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
DebugExitVOID(MCSUser::RegistryResponse);
|
||
}
|
||
|
||
/*
|
||
* void RegistryMonitorEntryIndication()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used by the top provider to issue a monitor
|
||
* indication anytime a registry entry that is being monitored changes.
|
||
*/
|
||
void MCSUser::RegistryMonitorEntryIndication (
|
||
CRegKeyContainer *registry_key_data,
|
||
CRegItem *registry_item_data,
|
||
UserID entry_owner_id,
|
||
EntityID entry_entity_id,
|
||
GCCModificationRights modification_rights)
|
||
{
|
||
GCCError error_value;
|
||
GCCPDU gcc_pdu;
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
|
||
/*
|
||
** Encode the conference join response PDU, along with the sequence
|
||
** number.
|
||
*/
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = REGISTRY_MONITOR_ENTRY_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.registry_monitor_entry_indication.bit_mask = 0;
|
||
|
||
|
||
error_value = registry_key_data->GetRegistryKeyDataPDU(
|
||
&gcc_pdu.u.indication.u.
|
||
registry_monitor_entry_indication.key);
|
||
|
||
if (error_value == GCC_NO_ERROR)
|
||
{
|
||
registry_item_data->GetRegistryItemDataPDU(&gcc_pdu.u.indication.u.registry_monitor_entry_indication.item);
|
||
|
||
// Set up the entry owner
|
||
if (entry_owner_id != 0)
|
||
{
|
||
gcc_pdu.u.indication.u.registry_monitor_entry_indication.owner.choice = OWNED_CHOSEN;
|
||
gcc_pdu.u.indication.u.registry_monitor_entry_indication.owner.u.owned.node_id = entry_owner_id;
|
||
gcc_pdu.u.indication.u.registry_monitor_entry_indication.owner.u.owned.entity_id = entry_entity_id;
|
||
}
|
||
else
|
||
{
|
||
gcc_pdu.u.indication.u.registry_monitor_entry_indication.owner.choice = NOT_OWNED_CHOSEN;
|
||
}
|
||
|
||
if (modification_rights != GCC_NO_MODIFICATION_RIGHTS_SPECIFIED)
|
||
{
|
||
gcc_pdu.u.indication.u.registry_monitor_entry_indication.bit_mask |= RESPONSE_MODIFY_RIGHTS_PRESENT;
|
||
|
||
gcc_pdu.u.indication.u.registry_monitor_entry_indication.entry_modify_rights =
|
||
(RegistryModificationRights)modification_rights;
|
||
}
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
|
||
}
|
||
else
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
|
||
/************************************************************************/
|
||
|
||
/*
|
||
* GCCError AppInvokeIndication()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used to send an application invoke indication to
|
||
* every node in the conference.
|
||
*/
|
||
GCCError MCSUser::AppInvokeIndication(
|
||
CInvokeSpecifierListContainer *invoke_specifier_list,
|
||
GCCSimpleNodeList *pNodeList)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
PSetOfDestinationNodes new_destination_node;
|
||
PSetOfDestinationNodes old_destination_node = NULL;
|
||
PSetOfDestinationNodes pDstNodesToFree = NULL;
|
||
UINT i;
|
||
|
||
// Encode the PDU that will be forwarded to the top provider.
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = APPLICATION_INVOKE_INDICATION_CHOSEN;
|
||
|
||
gcc_pdu.u.indication.u.application_invoke_indication.bit_mask = 0;
|
||
gcc_pdu.u.indication.u.application_invoke_indication.destination_nodes = NULL;
|
||
gcc_pdu.u.indication.u.application_invoke_indication.application_protocol_entity_list = NULL;
|
||
|
||
// First, set up the destination node list
|
||
if (pNodeList->cNodes != 0)
|
||
{
|
||
gcc_pdu.u.indication.u.application_invoke_indication.bit_mask |=
|
||
DESTINATION_NODES_PRESENT;
|
||
|
||
for (i = 0; i < pNodeList->cNodes; i++)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
new_destination_node = new SetOfDestinationNodes;
|
||
if (new_destination_node != NULL)
|
||
{
|
||
if (gcc_pdu.u.indication.u.application_invoke_indication.
|
||
destination_nodes == NULL)
|
||
{
|
||
gcc_pdu.u.indication.u.application_invoke_indication.
|
||
destination_nodes = new_destination_node;
|
||
pDstNodesToFree = new_destination_node;
|
||
}
|
||
else
|
||
{
|
||
old_destination_node->next = new_destination_node;
|
||
}
|
||
|
||
old_destination_node = new_destination_node;
|
||
new_destination_node->next = NULL;
|
||
new_destination_node->value = pNodeList->aNodeIDs[i];
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
rc = invoke_specifier_list->GetApplicationInvokeSpecifierListPDU(
|
||
&gcc_pdu.u.indication.u.application_invoke_indication.
|
||
application_protocol_entity_list);
|
||
}
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
if (NULL != pDstNodesToFree)
|
||
{
|
||
PSetOfDestinationNodes p;
|
||
while (NULL != (p = pDstNodesToFree))
|
||
{
|
||
pDstNodesToFree = pDstNodesToFree->next;
|
||
delete p;
|
||
}
|
||
}
|
||
|
||
if (rc == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError TextMessageIndication()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used to send a text message to either a specific node
|
||
* or to every node in the conference.
|
||
*/
|
||
GCCError MCSUser::TextMessageIndication (
|
||
LPWSTR pwszTextMsg,
|
||
UserID destination_node )
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
LPWSTR pwszMsg;
|
||
|
||
// Encode the PDU that will be forwarded to the top provider.
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = TEXT_MESSAGE_INDICATION_CHOSEN;
|
||
|
||
if (NULL != (pwszMsg = ::My_strdupW(pwszTextMsg)))
|
||
{
|
||
gcc_pdu.u.indication.u.text_message_indication.message.length = ::lstrlenW(pwszMsg);
|
||
gcc_pdu.u.indication.u.text_message_indication.message.value = pwszMsg;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPVOID)&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(
|
||
packet,
|
||
(destination_node == 0) ? BROADCAST_CHANNEL_ID : destination_node,
|
||
HIGH_PRIORITY,
|
||
FALSE);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
delete pwszMsg;
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
|
||
if (rc == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError ConferenceAssistanceIndication()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used to send a conference assistance indication to
|
||
* every node in the conference.
|
||
*/
|
||
GCCError MCSUser::ConferenceAssistanceIndication (
|
||
UINT number_of_user_data_members,
|
||
PGCCUserData * user_data_list)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
CUserDataListContainer *user_data_record;
|
||
|
||
DebugEntry(MCSUser::ConferenceAssistanceIndication);
|
||
|
||
// Encode the PDU
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONFERENCE_ASSISTANCE_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.conference_assistance_indication.bit_mask = 0;
|
||
|
||
// Construct the user data list container
|
||
if ((number_of_user_data_members != 0) && (rc == GCC_NO_ERROR))
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
user_data_record = new CUserDataListContainer(number_of_user_data_members, user_data_list, &rc);
|
||
if (user_data_record == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
user_data_record = NULL;
|
||
}
|
||
|
||
if ((user_data_record != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
rc = user_data_record->GetUserDataPDU(
|
||
&gcc_pdu.u.indication.u.conference_assistance_indication.
|
||
cain_user_data);
|
||
|
||
gcc_pdu.u.indication.u.conference_assistance_indication.bit_mask
|
||
|= CAIN_USER_DATA_PRESENT;
|
||
}
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
// Clean up containers
|
||
if (user_data_record != NULL)
|
||
{
|
||
user_data_record->Release();
|
||
}
|
||
|
||
return (rc);
|
||
}
|
||
|
||
|
||
|
||
/*
|
||
* GCCError ConferenceTransferRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used to send a conference transfer request to the
|
||
* top provider in the conference.
|
||
*/
|
||
GCCError MCSUser::ConferenceTransferRequest (
|
||
PGCCConferenceName destination_conference_name,
|
||
GCCNumericString destination_conference_modifier,
|
||
CNetAddrListContainer *destination_address_list,
|
||
UINT number_of_destination_nodes,
|
||
PUserID destination_node_list,
|
||
CPassword *password)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
UINT string_length;
|
||
PSetOfTransferringNodesRq new_set_of_nodes;
|
||
PSetOfTransferringNodesRq old_set_of_nodes;
|
||
UINT i;
|
||
|
||
DebugEntry(MCSUser::ConferenceTransferRequest);
|
||
|
||
// Encode the PDU
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = CONFERENCE_TRANSFER_REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.u.conference_transfer_request.bit_mask = 0;
|
||
|
||
// First get the conference name (either numeric or text).
|
||
if (destination_conference_name->numeric_string != NULL)
|
||
{
|
||
gcc_pdu.u.request.u.conference_transfer_request.conference_name.choice =
|
||
NAME_SELECTOR_NUMERIC_CHOSEN;
|
||
|
||
lstrcpy (gcc_pdu.u.request.u.conference_transfer_request.
|
||
conference_name.u.name_selector_numeric,
|
||
(LPSTR)destination_conference_name->numeric_string);
|
||
}
|
||
else
|
||
{
|
||
// Use a unicode string to determine the length
|
||
gcc_pdu.u.request.u.conference_transfer_request.conference_name.choice =
|
||
NAME_SELECTOR_TEXT_CHOSEN;
|
||
|
||
string_length = ::My_strlenW(destination_conference_name->text_string);
|
||
|
||
gcc_pdu.u.request.u.conference_transfer_request.
|
||
conference_name.u.name_selector_text.length = string_length;
|
||
|
||
gcc_pdu.u.request.u.conference_transfer_request.
|
||
conference_name.u.name_selector_text.value =
|
||
destination_conference_name->text_string;
|
||
}
|
||
|
||
|
||
// Next get the conference name modifier if it exists
|
||
if (destination_conference_modifier != NULL)
|
||
{
|
||
gcc_pdu.u.request.u.conference_transfer_request.bit_mask |=
|
||
CTRQ_CONFERENCE_MODIFIER_PRESENT;
|
||
|
||
lstrcpy (gcc_pdu.u.request.u.conference_transfer_request.
|
||
ctrq_conference_modifier,
|
||
(LPSTR)destination_conference_modifier);
|
||
}
|
||
|
||
// Get the network address list if it exist
|
||
if (destination_address_list != NULL)
|
||
{
|
||
gcc_pdu.u.request.u.conference_transfer_request.bit_mask |=
|
||
CTRQ_NETWORK_ADDRESS_PRESENT;
|
||
|
||
rc = destination_address_list->GetNetworkAddressListPDU (
|
||
&gcc_pdu.u.request.u.conference_transfer_request.
|
||
ctrq_net_address);
|
||
}
|
||
|
||
// Get the destination node list if it exists
|
||
if ((number_of_destination_nodes != 0) && (rc == GCC_NO_ERROR))
|
||
{
|
||
gcc_pdu.u.request.u.conference_transfer_request.bit_mask |=
|
||
CTRQ_TRANSFERRING_NODES_PRESENT;
|
||
|
||
old_set_of_nodes = NULL;
|
||
gcc_pdu.u.request.u.conference_transfer_request.
|
||
ctrq_transferring_nodes = NULL;
|
||
|
||
for (i = 0; i < number_of_destination_nodes; i++)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
new_set_of_nodes = new SetOfTransferringNodesRq;
|
||
if (new_set_of_nodes == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
break;
|
||
}
|
||
else
|
||
new_set_of_nodes->next = NULL;
|
||
|
||
if (old_set_of_nodes == NULL)
|
||
{
|
||
gcc_pdu.u.request.u.conference_transfer_request.
|
||
ctrq_transferring_nodes = new_set_of_nodes;
|
||
}
|
||
else
|
||
old_set_of_nodes->next = new_set_of_nodes;
|
||
|
||
old_set_of_nodes = new_set_of_nodes;
|
||
new_set_of_nodes->value = destination_node_list[i];
|
||
}
|
||
}
|
||
|
||
// Get the password if it exists
|
||
if ((password != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
gcc_pdu.u.request.u.conference_transfer_request.bit_mask |=
|
||
CTRQ_PASSWORD_PRESENT;
|
||
|
||
rc = password->GetPasswordSelectorPDU (
|
||
&gcc_pdu.u.request.u.conference_transfer_request.ctrq_password);
|
||
}
|
||
|
||
// Encode the PDU
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
// Clean up the node list if it was created
|
||
if (gcc_pdu.u.request.u.conference_transfer_request.bit_mask &
|
||
CTRQ_TRANSFERRING_NODES_PRESENT)
|
||
{
|
||
old_set_of_nodes = gcc_pdu.u.request.u.conference_transfer_request.
|
||
ctrq_transferring_nodes;
|
||
while (old_set_of_nodes != NULL)
|
||
{
|
||
new_set_of_nodes = old_set_of_nodes->next;
|
||
delete old_set_of_nodes;
|
||
old_set_of_nodes = new_set_of_nodes;
|
||
}
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
|
||
/*
|
||
* GCCError ConferenceTransferIndication()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used by the top provider to send out the transfer
|
||
* indication to every node in the conference. It is each nodes
|
||
* responsiblity to search the destination node list to see if
|
||
* it should transfer.
|
||
*/
|
||
GCCError MCSUser::ConferenceTransferIndication (
|
||
PGCCConferenceName destination_conference_name,
|
||
GCCNumericString destination_conference_modifier,
|
||
CNetAddrListContainer *destination_address_list,
|
||
UINT number_of_destination_nodes,
|
||
PUserID destination_node_list,
|
||
CPassword *password)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
UINT string_length;
|
||
PSetOfTransferringNodesIn new_set_of_nodes;
|
||
PSetOfTransferringNodesIn old_set_of_nodes;
|
||
UINT i;
|
||
|
||
DebugEntry(MCSUser::ConferenceTransferIndication);
|
||
|
||
// Encode the PDU
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONFERENCE_TRANSFER_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask = 0;
|
||
|
||
// First get the conference name (either numeric or text).
|
||
if (destination_conference_name->numeric_string != NULL)
|
||
{
|
||
gcc_pdu.u.indication.u.conference_transfer_indication.
|
||
conference_name.choice =
|
||
NAME_SELECTOR_NUMERIC_CHOSEN;
|
||
|
||
lstrcpy (gcc_pdu.u.indication.u.conference_transfer_indication.
|
||
conference_name.u.name_selector_numeric,
|
||
(LPSTR)destination_conference_name->numeric_string);
|
||
}
|
||
else
|
||
{
|
||
// Use a unicode string to determine the length
|
||
gcc_pdu.u.indication.u.conference_transfer_indication.
|
||
conference_name.choice =
|
||
NAME_SELECTOR_TEXT_CHOSEN;
|
||
|
||
string_length = ::My_strlenW(destination_conference_name->text_string);
|
||
|
||
gcc_pdu.u.indication.u.conference_transfer_indication.
|
||
conference_name.u.name_selector_text.length = string_length;
|
||
|
||
gcc_pdu.u.indication.u.conference_transfer_indication.
|
||
conference_name.u.name_selector_text.value =
|
||
destination_conference_name->text_string;
|
||
}
|
||
|
||
|
||
// Next get the conference name modifier if it exists
|
||
if (destination_conference_modifier != NULL)
|
||
{
|
||
gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask |=
|
||
CTIN_CONFERENCE_MODIFIER_PRESENT;
|
||
|
||
lstrcpy (gcc_pdu.u.indication.u.conference_transfer_indication.
|
||
ctin_conference_modifier,
|
||
(LPSTR)destination_conference_modifier);
|
||
}
|
||
|
||
// Get the network address list if it exist
|
||
if (destination_address_list != NULL)
|
||
{
|
||
gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask |=
|
||
CTIN_NETWORK_ADDRESS_PRESENT;
|
||
|
||
rc = destination_address_list->GetNetworkAddressListPDU (
|
||
&gcc_pdu.u.indication.u.conference_transfer_indication.
|
||
ctin_net_address);
|
||
}
|
||
|
||
// Get the destination node list if it exists
|
||
if ((number_of_destination_nodes != 0) && (rc == GCC_NO_ERROR))
|
||
{
|
||
gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask |=
|
||
CTIN_TRANSFERRING_NODES_PRESENT;
|
||
|
||
old_set_of_nodes = NULL;
|
||
gcc_pdu.u.indication.u.conference_transfer_indication.
|
||
ctin_transferring_nodes = NULL;
|
||
|
||
for (i = 0; i < number_of_destination_nodes; i++)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
new_set_of_nodes = new SetOfTransferringNodesIn;
|
||
if (new_set_of_nodes == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
break;
|
||
}
|
||
else
|
||
new_set_of_nodes->next = NULL;
|
||
|
||
if (old_set_of_nodes == NULL)
|
||
{
|
||
gcc_pdu.u.indication.u.conference_transfer_indication.
|
||
ctin_transferring_nodes = new_set_of_nodes;
|
||
}
|
||
else
|
||
old_set_of_nodes->next = new_set_of_nodes;
|
||
|
||
old_set_of_nodes = new_set_of_nodes;
|
||
new_set_of_nodes->value = destination_node_list[i];
|
||
}
|
||
}
|
||
|
||
// Get the password if it exists
|
||
if ((password != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask |=
|
||
CTIN_PASSWORD_PRESENT;
|
||
|
||
rc = password->GetPasswordSelectorPDU (
|
||
&gcc_pdu.u.indication.u.conference_transfer_indication.
|
||
ctin_password);
|
||
}
|
||
|
||
// Encode the PDU
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
// Clean up the node list if it was created
|
||
if (gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask &
|
||
CTIN_TRANSFERRING_NODES_PRESENT)
|
||
{
|
||
old_set_of_nodes = gcc_pdu.u.indication.u.
|
||
conference_transfer_indication.ctin_transferring_nodes;
|
||
while (old_set_of_nodes != NULL)
|
||
{
|
||
new_set_of_nodes = old_set_of_nodes->next;
|
||
delete old_set_of_nodes;
|
||
old_set_of_nodes = new_set_of_nodes;
|
||
}
|
||
}
|
||
|
||
DebugExitINT(MCSUser::ConferenceTransferIndication, rc);
|
||
return rc;
|
||
}
|
||
|
||
|
||
/*
|
||
* GCCError ConferenceTransferResponse()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used by the top provider to send back a response to
|
||
* the node that made a transfer request. The info specified in the
|
||
* request is included in the response to match request to response.
|
||
*/
|
||
GCCError MCSUser::ConferenceTransferResponse (
|
||
UserID requesting_node_id,
|
||
PGCCConferenceName destination_conference_name,
|
||
GCCNumericString destination_conference_modifier,
|
||
UINT number_of_destination_nodes,
|
||
PUserID destination_node_list,
|
||
GCCResult result)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
UINT string_length;
|
||
PSetOfTransferringNodesRs new_set_of_nodes;
|
||
PSetOfTransferringNodesRs old_set_of_nodes;
|
||
UINT i;
|
||
|
||
DebugEntry(MCSUser::ConferenceTransferResponse);
|
||
|
||
// Encode the PDU
|
||
gcc_pdu.choice = RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.choice = CONFERENCE_TRANSFER_RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.u.conference_transfer_response.bit_mask = 0;
|
||
|
||
// First get the conference name (either numeric or text).
|
||
if (destination_conference_name->numeric_string != NULL)
|
||
{
|
||
gcc_pdu.u.response.u.conference_transfer_response.
|
||
conference_name.choice =
|
||
NAME_SELECTOR_NUMERIC_CHOSEN;
|
||
|
||
::lstrcpyA(gcc_pdu.u.response.u.conference_transfer_response.
|
||
conference_name.u.name_selector_numeric,
|
||
(LPSTR)destination_conference_name->numeric_string);
|
||
}
|
||
else
|
||
{
|
||
// Use a unicode string to determine the length
|
||
gcc_pdu.u.response.u.conference_transfer_response.
|
||
conference_name.choice =
|
||
NAME_SELECTOR_TEXT_CHOSEN;
|
||
|
||
string_length = ::My_strlenW(destination_conference_name->text_string);
|
||
|
||
gcc_pdu.u.response.u.conference_transfer_response.
|
||
conference_name.u.name_selector_text.length = string_length;
|
||
|
||
gcc_pdu.u.response.u.conference_transfer_response.
|
||
conference_name.u.name_selector_text.value =
|
||
destination_conference_name->text_string;
|
||
}
|
||
|
||
|
||
// Next get the conference name modifier if it exists
|
||
if (destination_conference_modifier != NULL)
|
||
{
|
||
gcc_pdu.u.response.u.conference_transfer_response.bit_mask |=
|
||
CTRS_CONFERENCE_MODIFIER_PRESENT;
|
||
|
||
::lstrcpyA(gcc_pdu.u.response.u.conference_transfer_response.
|
||
ctrs_conference_modifier,
|
||
(LPSTR)destination_conference_modifier);
|
||
}
|
||
|
||
// Get the destination node list if it exists
|
||
if ((number_of_destination_nodes != 0) && (rc == GCC_NO_ERROR))
|
||
{
|
||
gcc_pdu.u.response.u.conference_transfer_response.bit_mask |=
|
||
CTRS_TRANSFERRING_NODES_PRESENT;
|
||
|
||
old_set_of_nodes = NULL;
|
||
gcc_pdu.u.response.u.conference_transfer_response.
|
||
ctrs_transferring_nodes = NULL;
|
||
|
||
for (i = 0; i < number_of_destination_nodes; i++)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
new_set_of_nodes = new SetOfTransferringNodesRs;
|
||
if (new_set_of_nodes == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
break;
|
||
}
|
||
else
|
||
new_set_of_nodes->next = NULL;
|
||
|
||
if (old_set_of_nodes == NULL)
|
||
{
|
||
gcc_pdu.u.response.u.conference_transfer_response.
|
||
ctrs_transferring_nodes = new_set_of_nodes;
|
||
}
|
||
else
|
||
old_set_of_nodes->next = new_set_of_nodes;
|
||
|
||
old_set_of_nodes = new_set_of_nodes;
|
||
new_set_of_nodes->value = destination_node_list[i];
|
||
}
|
||
}
|
||
|
||
// Set up the result
|
||
if (result == GCC_RESULT_SUCCESSFUL)
|
||
{
|
||
gcc_pdu.u.response.u.conference_transfer_response.result =
|
||
CTRANS_RESULT_SUCCESS;
|
||
}
|
||
else
|
||
{
|
||
gcc_pdu.u.response.u.conference_transfer_response.result =
|
||
CTRANS_RESULT_INVALID_REQUESTER;
|
||
}
|
||
|
||
// Encode the PDU
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, requesting_node_id, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
// Clean up the node list if it was created
|
||
if (gcc_pdu.u.response.u.conference_transfer_response.bit_mask &
|
||
CTRS_TRANSFERRING_NODES_PRESENT)
|
||
{
|
||
old_set_of_nodes = gcc_pdu.u.response.u.
|
||
conference_transfer_response.ctrs_transferring_nodes;
|
||
while (old_set_of_nodes != NULL)
|
||
{
|
||
new_set_of_nodes = old_set_of_nodes->next;
|
||
delete old_set_of_nodes;
|
||
old_set_of_nodes = new_set_of_nodes;
|
||
}
|
||
}
|
||
|
||
DebugExitINT(MCSUser::ConferenceTransferResponse, rc);
|
||
return rc;
|
||
}
|
||
|
||
|
||
/*
|
||
* GCCError ConferenceAddRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used to send a conference add request to the appropriate
|
||
* node. This call can be made by the requesting node or by the top
|
||
* provider to pass the add request on to the adding node.
|
||
*/
|
||
GCCError MCSUser::ConferenceAddRequest (
|
||
TagNumber conference_add_tag,
|
||
UserID requesting_node,
|
||
UserID adding_node,
|
||
UserID target_node,
|
||
CNetAddrListContainer *network_address_container,
|
||
CUserDataListContainer *user_data_container)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
DebugEntry(MCSUser::ConferenceAddRequest);
|
||
|
||
// Encode the PDU
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = CONFERENCE_ADD_REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.u.conference_add_request.bit_mask = 0;
|
||
|
||
// Get the network address list if it exist
|
||
if (network_address_container != NULL)
|
||
{
|
||
// Set up the network address portion of the pdu
|
||
rc = network_address_container->GetNetworkAddressListPDU (
|
||
&gcc_pdu.u.request.u.conference_add_request.
|
||
add_request_net_address);
|
||
|
||
// Set up the user data container
|
||
if ((rc == GCC_NO_ERROR) && (user_data_container != NULL))
|
||
{
|
||
rc = user_data_container->GetUserDataPDU (
|
||
&gcc_pdu.u.request.u.conference_add_request.carq_user_data);
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.request.u.conference_add_request.bit_mask |=
|
||
CARQ_USER_DATA_PRESENT;
|
||
}
|
||
}
|
||
|
||
// Encode the PDU
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
// specify the requesting node
|
||
gcc_pdu.u.request.u.conference_add_request.requesting_node =
|
||
requesting_node;
|
||
|
||
if (adding_node != 0)
|
||
{
|
||
gcc_pdu.u.request.u.conference_add_request.bit_mask |=
|
||
ADDING_MCU_PRESENT;
|
||
gcc_pdu.u.request.u.conference_add_request.adding_mcu =
|
||
adding_node;
|
||
}
|
||
|
||
gcc_pdu.u.request.u.conference_add_request.tag = conference_add_tag;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, target_node, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_BAD_NETWORK_ADDRESS;
|
||
}
|
||
|
||
DebugExitINT(MCSUser::ConferenceAddRequest, rc);
|
||
return rc;
|
||
}
|
||
|
||
|
||
/*
|
||
* GCCError ConferenceAddResponse()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used to send a conference add request to the appropriate
|
||
* node. This call can be made by the requesting node or by the top
|
||
* provider to pass the add request on to the adding node.
|
||
*/
|
||
GCCError MCSUser::ConferenceAddResponse(
|
||
TagNumber add_request_tag,
|
||
UserID requesting_node,
|
||
CUserDataListContainer *user_data_container,
|
||
GCCResult result)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
DebugEntry(MCSUser::ConferenceAddResponse);
|
||
|
||
// Encode the PDU
|
||
gcc_pdu.choice = RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.choice = CONFERENCE_ADD_RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.u.conference_add_response.bit_mask = 0;
|
||
|
||
// Set up the user data container
|
||
if ((rc == GCC_NO_ERROR) && (user_data_container != NULL))
|
||
{
|
||
rc = user_data_container->GetUserDataPDU (
|
||
&gcc_pdu.u.response.u.conference_add_response.cars_user_data);
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.response.u.conference_add_response.bit_mask |=
|
||
CARS_USER_DATA_PRESENT;
|
||
}
|
||
}
|
||
|
||
// Encode the PDU
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.response.u.conference_add_response.tag = add_request_tag;
|
||
|
||
gcc_pdu.u.response.u.conference_add_response.result =
|
||
::TranslateGCCResultToAddResult(result);
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, requesting_node, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
DebugExitINT(MCSUser::ConferenceAddResponse, rc);
|
||
return rc;
|
||
}
|
||
|
||
|
||
/************************* Conductorship Calls ***********************/
|
||
/*
|
||
* GCCError ConductorTokenGrab()
|
||
*
|
||
* Public Function Description:
|
||
* This routine makes the MCS calls to grab the conductor token.
|
||
*/
|
||
GCCError MCSUser::ConductorTokenGrab()
|
||
{
|
||
MCSError mcs_error;
|
||
|
||
mcs_error = g_pMCSIntf->TokenGrabRequest(m_pMCSSap, CONDUCTOR_TOKEN_ID);
|
||
|
||
return (g_pMCSIntf->TranslateMCSIFErrorToGCCError (mcs_error));
|
||
}
|
||
|
||
/*
|
||
* GCCError ConductorTokenRelease()
|
||
*
|
||
* Public Function Description:
|
||
* This routine makes the MCS calls to release the conductor token.
|
||
*/
|
||
GCCError MCSUser::ConductorTokenRelease()
|
||
{
|
||
MCSError mcs_error;
|
||
|
||
mcs_error = g_pMCSIntf->TokenReleaseRequest(m_pMCSSap, CONDUCTOR_TOKEN_ID);
|
||
|
||
return (g_pMCSIntf->TranslateMCSIFErrorToGCCError (mcs_error));
|
||
}
|
||
/*
|
||
* GCCError ConductorTokenPlease()
|
||
*
|
||
* Public Function Description:
|
||
* This routine makes the MCS calls to request the conductor token from
|
||
* the current conductor.
|
||
*/
|
||
GCCError MCSUser::ConductorTokenPlease()
|
||
{
|
||
MCSError mcs_error;
|
||
|
||
mcs_error = g_pMCSIntf->TokenPleaseRequest(m_pMCSSap, CONDUCTOR_TOKEN_ID);
|
||
|
||
return (g_pMCSIntf->TranslateMCSIFErrorToGCCError (mcs_error));
|
||
}
|
||
|
||
/*
|
||
* GCCError ConductorTokenGive ()
|
||
*
|
||
* Public Function Description:
|
||
* This routine makes the MCS calls to give the conductor token to the
|
||
* specified node.
|
||
*/
|
||
GCCError MCSUser::ConductorTokenGive(UserID recipient_user_id)
|
||
{
|
||
MCSError mcs_error;
|
||
|
||
mcs_error = g_pMCSIntf->TokenGiveRequest(m_pMCSSap, CONDUCTOR_TOKEN_ID,
|
||
recipient_user_id);
|
||
|
||
return (g_pMCSIntf->TranslateMCSIFErrorToGCCError (mcs_error));
|
||
}
|
||
|
||
/*
|
||
* GCCError ConductorTokenGiveResponse ()
|
||
*
|
||
* Public Function Description:
|
||
* This routine makes the MCS calls to respond to a conductor give
|
||
* request.
|
||
*/
|
||
GCCError MCSUser::ConductorTokenGiveResponse(Result result)
|
||
{
|
||
MCSError mcs_error;
|
||
|
||
mcs_error = g_pMCSIntf->TokenGiveResponse(m_pMCSSap, CONDUCTOR_TOKEN_ID, result);
|
||
|
||
return g_pMCSIntf->TranslateMCSIFErrorToGCCError(mcs_error);
|
||
}
|
||
|
||
/*
|
||
* GCCError ConductorTokenTest ()
|
||
*
|
||
* Public Function Description:
|
||
* This routine is used to test the current state of the conductor token
|
||
* (is it grabbed or not).
|
||
*/
|
||
GCCError MCSUser::ConductorTokenTest()
|
||
{
|
||
MCSError mcs_error;
|
||
|
||
mcs_error = g_pMCSIntf->TokenTestRequest(m_pMCSSap, CONDUCTOR_TOKEN_ID);
|
||
|
||
return g_pMCSIntf->TranslateMCSIFErrorToGCCError(mcs_error);
|
||
}
|
||
|
||
|
||
/*
|
||
* GCCError SendConductorAssignIndication()
|
||
*
|
||
* Public Function Description:
|
||
* This routine sends a conductor assign indication to all the
|
||
* nodes in the conference.
|
||
*/
|
||
GCCError MCSUser::SendConductorAssignIndication(
|
||
UserID conductor_user_id)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
/*
|
||
** Fill in the ConductorAssignIndication pdu structure to be passed in the
|
||
** constructor of the packet class.
|
||
*/
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONDUCTOR_ASSIGN_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.conductor_assign_indication.user_id =
|
||
conductor_user_id;
|
||
|
||
/*
|
||
** Create a packet object
|
||
*/
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU, // pdu_type
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, TOP_PRIORITY, TRUE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError SendConductorReleaseIndication()
|
||
*
|
||
* Public Function Description:
|
||
* This routine sends a conductor release indication to all the
|
||
* nodes in the conference.
|
||
*/
|
||
GCCError MCSUser::SendConductorReleaseIndication()
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
/*
|
||
** Fill in the ConductorAssignIndication pdu structure to be passed in the
|
||
** constructor of the packet class.
|
||
*/
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONDUCTOR_RELEASE_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.conductor_release_indication.placeholder = 0;
|
||
|
||
/*
|
||
** Create a packet object
|
||
*/
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU, // pdu_type
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, TOP_PRIORITY, TRUE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError SendConductorPermitAsk ()
|
||
*
|
||
* Public Function Description:
|
||
* This routine sends a conductor permission ask request directly to the
|
||
* conductor node.
|
||
*/
|
||
GCCError MCSUser::SendConductorPermitAsk (
|
||
BOOL grant_permission)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
/*
|
||
** Fill in the ConductorPermissionAskIndication pdu structure to be passed
|
||
** in the constructor of the packet class.
|
||
*/
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONDUCTOR_PERMISSION_ASK_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.conductor_permission_ask_indication.
|
||
permission_is_granted = (ASN1bool_t)grant_permission;
|
||
|
||
/*
|
||
** Create a packet object
|
||
*/
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU, // pdu_type
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError SendConductorPermitGrant ()
|
||
*
|
||
* Public Function Description:
|
||
* This routine sends a conductor permission grant indication to every
|
||
* node in the conference. Usually issued when permissions change.
|
||
*/
|
||
GCCError MCSUser::SendConductorPermitGrant (
|
||
UINT number_granted,
|
||
PUserID granted_node_list,
|
||
UINT number_waiting,
|
||
PUserID waiting_node_list)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
PPermissionList permission_list;
|
||
PPermissionList previous_permission_list;
|
||
PWaitingList waiting_list;
|
||
PWaitingList previous_waiting_list;
|
||
UINT i;
|
||
|
||
/*
|
||
** Fill in the ConductorPermissionAskIndication pdu structure to be passed
|
||
** in the constructor of the packet class.
|
||
*/
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONDUCTOR_PERMISSION_GRANT_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.conductor_permission_grant_indication.bit_mask = 0;
|
||
|
||
// First fill in the granted node permission list
|
||
gcc_pdu.u.indication.u.
|
||
conductor_permission_grant_indication.permission_list = NULL;
|
||
previous_permission_list = NULL;
|
||
for (i = 0; i < number_granted; i++)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
permission_list = new PermissionList;
|
||
if (permission_list == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
break;
|
||
}
|
||
|
||
if (previous_permission_list == NULL)
|
||
{
|
||
gcc_pdu.u.indication.u.conductor_permission_grant_indication.
|
||
permission_list = permission_list;
|
||
}
|
||
else
|
||
previous_permission_list->next = permission_list;
|
||
|
||
previous_permission_list = permission_list;
|
||
|
||
permission_list->value = granted_node_list[i];
|
||
permission_list->next = NULL;
|
||
}
|
||
|
||
// If waiting list exists fill it in
|
||
if ((number_waiting != 0) && (rc == GCC_NO_ERROR))
|
||
{
|
||
gcc_pdu.u.indication.u.conductor_permission_grant_indication.bit_mask =
|
||
WAITING_LIST_PRESENT;
|
||
gcc_pdu.u.indication.u.
|
||
conductor_permission_grant_indication.waiting_list = NULL;
|
||
previous_waiting_list = NULL;
|
||
for (i = 0; i < number_waiting; i++)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
waiting_list = new WaitingList;
|
||
if (waiting_list == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
break;
|
||
}
|
||
|
||
if (previous_waiting_list == NULL)
|
||
{
|
||
gcc_pdu.u.indication.u.conductor_permission_grant_indication.
|
||
waiting_list = waiting_list;
|
||
}
|
||
else
|
||
previous_waiting_list->next = waiting_list;
|
||
|
||
previous_waiting_list = waiting_list;
|
||
|
||
waiting_list->value = waiting_node_list[i];
|
||
waiting_list->next = NULL;
|
||
}
|
||
}
|
||
|
||
/*
|
||
** Create a packet object
|
||
*/
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU, // pdu_type
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, TOP_PRIORITY, TRUE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/**********************************************************************/
|
||
|
||
|
||
/***************** Miscelaneous calls ******************************/
|
||
/*
|
||
* GCCError TimeRemainingRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This routine sends out an indication to every node in the
|
||
* conference informing how much time is remaining in the conference.
|
||
*/
|
||
GCCError MCSUser::TimeRemainingRequest (
|
||
UINT time_remaining,
|
||
UserID node_id)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
/*
|
||
** Fill in the TimeRemainingRequest pdu structure to be passed in the
|
||
** constructor of the packet class.
|
||
*/
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONFERENCE_TIME_REMAINING_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.conference_time_remaining_indication.bit_mask = 0;
|
||
|
||
gcc_pdu.u.indication.u.conference_time_remaining_indication.time_remaining =
|
||
time_remaining;
|
||
|
||
if (node_id != 0)
|
||
{
|
||
gcc_pdu.u.indication.u.conference_time_remaining_indication.bit_mask |=
|
||
TIME_REMAINING_NODE_ID_PRESENT;
|
||
gcc_pdu.u.indication.u.conference_time_remaining_indication.
|
||
time_remaining_node_id = node_id;
|
||
}
|
||
|
||
/*
|
||
** Create a packet object
|
||
*/
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU, // pdu_type
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError TimeInquireRequest()
|
||
*
|
||
* Public Function Description:
|
||
* This routine sends out a request for a time remaing update.
|
||
*/
|
||
GCCError MCSUser::TimeInquireRequest (
|
||
BOOL time_is_conference_wide)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
/*
|
||
** Fill in the TimeInquireRequest pdu structure to be passed in the
|
||
** constructor of the packet class.
|
||
*/
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONFERENCE_TIME_INQUIRE_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.conference_time_inquire_indication.
|
||
time_is_node_specific = (ASN1bool_t)time_is_conference_wide;
|
||
|
||
/*
|
||
** Create a packet object
|
||
*/
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU, // pdu_type
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, CONVENER_CHANNEL_ID, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* GCCError ConferenceExtendIndication()
|
||
*
|
||
* Public Function Description:
|
||
* This routine sends out an indication informing conference participants
|
||
* of an extension.
|
||
*/
|
||
GCCError MCSUser::ConferenceExtendIndication (
|
||
UINT extension_time,
|
||
BOOL time_is_conference_wide)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
PPacket packet;
|
||
GCCPDU gcc_pdu;
|
||
PacketError packet_error;
|
||
|
||
/*
|
||
** Fill in the ConfernceExtendIndication pdu structure to be passed in the
|
||
** constructor of the packet class.
|
||
*/
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONFERENCE_TIME_EXTEND_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.conference_time_extend_indication.
|
||
time_to_extend = extension_time;
|
||
gcc_pdu.u.indication.u.conference_time_extend_indication.
|
||
time_is_node_specific = (ASN1bool_t)time_is_conference_wide;
|
||
|
||
/*
|
||
** Create a packet object
|
||
*/
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU, // pdu_type
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, CONVENER_CHANNEL_ID, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* void ConferenceJoinResponse()
|
||
*
|
||
* Functional Description:
|
||
* This function is called by the conference object of the
|
||
* top provider when it wants to send the join response back to the gcc
|
||
* provider that made the join request, through the directly connected
|
||
* intermediate node. This function does the encoding of the join response
|
||
* PDU and also adds the sequence number sent in the request.
|
||
*/
|
||
void MCSUser::ConferenceJoinResponse(
|
||
UserID receiver_id,
|
||
BOOL password_is_in_the_clear,
|
||
BOOL conference_locked,
|
||
BOOL conference_listed,
|
||
GCCTerminationMethod termination_method,
|
||
CPassword *password_challenge,
|
||
CUserDataListContainer *user_data_list,
|
||
GCCResult result)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
GCCPDU gcc_pdu;
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
TagNumber lTagNum;
|
||
|
||
if (0 == (lTagNum = m_ConfJoinResponseList2.Find(receiver_id)))
|
||
{
|
||
WARNING_OUT(("MCSUser::ConferenceJoinResponse: Unexpected Join Response"));
|
||
return;
|
||
}
|
||
|
||
/*
|
||
** Encode the conference join response PDU, along with the sequence
|
||
** number.
|
||
*/
|
||
gcc_pdu.choice = RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.choice = CONFERENCE_JOIN_RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.u.conference_join_response.bit_mask = 0;
|
||
|
||
/*
|
||
** Get the sequence number of the outstanding response from the
|
||
** list of seq # vs userID using the userID passed from above.
|
||
*/
|
||
gcc_pdu.u.response.u.conference_join_response.tag = lTagNum;
|
||
|
||
// Remove this entry from the list.
|
||
m_ConfJoinResponseList2.Remove(receiver_id);
|
||
|
||
|
||
// Get password challenge PDU
|
||
if ((password_challenge != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
rc = password_challenge->GetPasswordChallengeResponsePDU (
|
||
&gcc_pdu.u.response.u.conference_join_response.cjrs_password);
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.response.u.conference_join_response.bit_mask |=
|
||
CJRS_PASSWORD_PRESENT;
|
||
}
|
||
}
|
||
|
||
// Get user data list PDU
|
||
if ((user_data_list != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
rc = user_data_list->GetUserDataPDU (
|
||
&gcc_pdu.u.response.u.conference_join_response.cjrs_user_data);
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.response.u.conference_join_response.bit_mask |=
|
||
CJRS_USER_DATA_PRESENT;
|
||
}
|
||
}
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
gcc_pdu.u.response.u.conference_join_response.
|
||
top_node_id = m_nidTopProvider;
|
||
|
||
gcc_pdu.u.response.u.conference_join_response.
|
||
clear_password_required = (ASN1bool_t)password_is_in_the_clear;
|
||
|
||
gcc_pdu.u.response.u.conference_join_response.
|
||
conference_is_locked = (ASN1bool_t)conference_locked;
|
||
|
||
gcc_pdu.u.response.u.conference_join_response.
|
||
conference_is_listed = (ASN1bool_t)conference_listed;
|
||
|
||
gcc_pdu.u.response.u.conference_join_response.termination_method =
|
||
(TerminationMethod)termination_method;
|
||
|
||
gcc_pdu.u.response.u.conference_join_response.result =
|
||
::TranslateGCCResultToJoinResult(result);
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, receiver_id, TOP_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
if (rc == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void ConferenceTerminateRequest()
|
||
*
|
||
* Functional Description:
|
||
* This routine is used by a node subordinate to the top provider to
|
||
* request that the conference by terminated.
|
||
*/
|
||
void MCSUser::ConferenceTerminateRequest(
|
||
GCCReason reason)
|
||
{
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
GCCPDU gcc_pdu;
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = CONFERENCE_TERMINATE_REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.u.conference_terminate_request.reason =
|
||
::TranslateGCCReasonToTerminateRqReason(reason);
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void ConferenceTerminateResponse ()
|
||
*
|
||
* Functional Description:
|
||
* This routine is used by the top provider to respond to a terminate
|
||
* request issued by a subordinate node. The result indicates if the
|
||
* requesting node had the correct privileges.
|
||
*/
|
||
void MCSUser::ConferenceTerminateResponse (
|
||
UserID requester_id,
|
||
GCCResult result)
|
||
{
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
GCCPDU gcc_pdu;
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
|
||
gcc_pdu.choice = RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.choice = CONFERENCE_TERMINATE_RESPONSE_CHOSEN;
|
||
gcc_pdu.u.response.u.conference_terminate_response.result =
|
||
::TranslateGCCResultToTerminateResult(result);
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, requester_id, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* GCCError ConferenceTerminateIndication()
|
||
*
|
||
* Functional Description:
|
||
* This routine is used by the top provider to send out a terminate
|
||
* indication to every node in the conference.
|
||
*/
|
||
void MCSUser::ConferenceTerminateIndication (
|
||
GCCReason reason)
|
||
{
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
GCCPDU gcc_pdu;
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONFERENCE_TERMINATE_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.conference_terminate_indication.reason =
|
||
::TranslateGCCReasonToTerminateInReason(reason);
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void EjectNodeFromConference()
|
||
*
|
||
* Functional Description:
|
||
* This routine is used when attempting to eject a node from the
|
||
* conference.
|
||
*/
|
||
GCCError MCSUser::EjectNodeFromConference ( UserID ejected_node_id,
|
||
GCCReason reason)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
GCCPDU gcc_pdu;
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
ChannelID channel_id;
|
||
BOOL uniform_send;
|
||
Priority priority;
|
||
PAlarm alarm;
|
||
|
||
if (ejected_node_id == m_nidMyself)
|
||
{
|
||
/*
|
||
** If the ejected node is this node we can immediately initiate the
|
||
** ejection. There is no need to request this through the Top
|
||
** Provider.
|
||
*/
|
||
rc = InitiateEjectionFromConference (reason);
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
** If the ejected node is a child node to this node we can directly
|
||
** eject it. Otherwise the request is forwarded to the Top Provider.
|
||
*/
|
||
if (m_ChildUidConnHdlList2.Find(ejected_node_id) ||
|
||
(m_nidTopProvider == m_nidMyself))
|
||
{
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice =
|
||
CONFERENCE_EJECT_USER_INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.u.conference_eject_user_indication.
|
||
node_to_eject = ejected_node_id;
|
||
gcc_pdu.u.indication.u.conference_eject_user_indication.reason =
|
||
::TranslateGCCReasonToEjectInd(reason);
|
||
|
||
uniform_send = TRUE;
|
||
channel_id = BROADCAST_CHANNEL_ID;
|
||
|
||
// If this is the top provider send the data at TOP priority
|
||
if (m_nidTopProvider == m_nidMyself)
|
||
priority = TOP_PRIORITY;
|
||
else
|
||
priority = HIGH_PRIORITY;
|
||
|
||
/*
|
||
** Set up ejection alarm to automatically eject any misbehaving
|
||
** nodes. Note that we only do this if we are directly connected
|
||
** to the node to be ejected.
|
||
*/
|
||
if (m_ChildUidConnHdlList2.Find(ejected_node_id))
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
alarm = new Alarm (EJECTED_NODE_TIMER_DURATION);
|
||
if (alarm != NULL)
|
||
{
|
||
/*
|
||
** Here we save the alarm in a list of ejected nodes. This
|
||
** alarm is used to cleanup any misbehaving node.
|
||
*/
|
||
m_EjectedNodeAlarmList2.Append(ejected_node_id, alarm);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
gcc_pdu.choice = REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.choice = CONFERENCE_EJECT_USER_REQUEST_CHOSEN;
|
||
gcc_pdu.u.request.u.conference_eject_user_request.node_to_eject =
|
||
ejected_node_id;
|
||
|
||
// The only valid reason is user initiated which is zero
|
||
gcc_pdu.u.request.u.conference_eject_user_request.reason =
|
||
CERQ_REASON_USER_INITIATED;
|
||
|
||
uniform_send = FALSE;
|
||
channel_id = m_nidTopProvider;
|
||
priority = TOP_PRIORITY;
|
||
}
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, channel_id, priority, uniform_send);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (rc == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* void SendEjectNodeResponse()
|
||
*
|
||
* Functional Description:
|
||
* This routine is used by the top provider to respond to an eject
|
||
* user request.
|
||
*/
|
||
GCCError MCSUser::SendEjectNodeResponse ( UserID requester_id,
|
||
UserID node_to_eject,
|
||
GCCResult result)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
GCCPDU gcc_pdu;
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
|
||
gcc_pdu.choice = RESPONSE_CHOSEN;
|
||
|
||
gcc_pdu.u.response.choice = CONFERENCE_EJECT_USER_RESPONSE_CHOSEN;
|
||
|
||
gcc_pdu.u.response.u.conference_eject_user_response.node_to_eject =
|
||
node_to_eject;
|
||
|
||
gcc_pdu.u.response.u.conference_eject_user_response.result =
|
||
::TranslateGCCResultToEjectResult(result);
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, requester_id, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
* void RosterUpdateIndication()
|
||
*
|
||
* Functional Description:
|
||
* This routine is used to forward a roster update indication either
|
||
* upward to the parent node or downward as a full refresh to all nodes
|
||
* in the conference.
|
||
*/
|
||
void MCSUser::RosterUpdateIndication(PGCCPDU gcc_pdu,
|
||
BOOL send_update_upward)
|
||
{
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
if (send_update_upward)
|
||
{
|
||
AddToMCSMessageQueue(packet, m_nidParent, HIGH_PRIORITY, FALSE);
|
||
}
|
||
else
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
delete packet;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void AddToMCSMessageQueue()
|
||
*
|
||
* Private Function Description:
|
||
* This function adds the out bound messages to a queue which is
|
||
* flushed in the next heartbeat when controller call FlushMessageQueue.
|
||
* In case memory allocation for messages holding the out bound inform-
|
||
* ation fails an owner call back is sent to conference object to
|
||
* indicate insufficient memory.
|
||
*
|
||
* Formal Parameters:
|
||
* packet - (i) Pointer to packet to queue up.
|
||
* send_data_request_info - (i) Structure containing all the info
|
||
* necessary to deliver the packet.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::
|
||
AddToMCSMessageQueue
|
||
(
|
||
PPacket packet,
|
||
ChannelID channel_id,
|
||
Priority priority,
|
||
BOOL uniform_send
|
||
)
|
||
{
|
||
SEND_DATA_REQ_INFO *pReqInfo;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
pReqInfo = new SEND_DATA_REQ_INFO;
|
||
if (pReqInfo != NULL)
|
||
{
|
||
pReqInfo->packet = packet;
|
||
pReqInfo->channel_id = channel_id;
|
||
pReqInfo->priority = priority;
|
||
pReqInfo->uniform_send = uniform_send;
|
||
|
||
/*
|
||
** This forces the packet to be encoded. This must happen here so
|
||
** that any memory used by the decoded portion of the packet can
|
||
** be freed after returning.
|
||
*/
|
||
// packet->Lock();
|
||
|
||
m_OutgoingPDUQueue.Append(pReqInfo);
|
||
|
||
if (m_OutgoingPDUQueue.GetCount() == 1)
|
||
{
|
||
if (FlushOutgoingPDU())
|
||
{
|
||
// Inform the MCS interface that there are PDUs queued
|
||
g_pGCCController->SetEventToFlushOutgoingPDU();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Inform the MCS interface that there are PDUs queued
|
||
g_pGCCController->SetEventToFlushOutgoingPDU();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ResourceFailureHandler();
|
||
/*
|
||
** This just sets a flag in the packet object that allows packet
|
||
** to commit suicide if lock count on encoded and decoded data is
|
||
** zero. This will occur once the packet is sent on to MCS.
|
||
*/
|
||
packet->Unlock();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* BOOL FlushOutgoingPDU()
|
||
*
|
||
* Public Function Description:
|
||
* This function is called by the owner object in every heartbeat. This
|
||
* function iterates throught the list of pending out bound messages
|
||
* and sends them down to MCS. Also after a successful send it frees
|
||
* any resources tied up with the outbound messages. If however a message
|
||
* can not be sent in this heartbeat, as indicated by MCS, then it
|
||
* inserts the message back onto the message queue and returns.
|
||
*
|
||
* Return value:
|
||
* TRUE, if there remain un-processed msgs in the MCS message queue
|
||
* FALSE, if all the msgs in the MCS msg queue were processed.
|
||
*/
|
||
void MCSUser::
|
||
CheckEjectedNodeAlarms ( void )
|
||
{
|
||
/*
|
||
** We first check the eject user list to make sure that no alarms have
|
||
** expired on any of the ejected nodes.
|
||
*/
|
||
if (m_EjectedNodeAlarmList2.IsEmpty() == FALSE)
|
||
{
|
||
PAlarm lpAlarm;
|
||
UserID uid;
|
||
|
||
// We copy the list so that we can remove entries in the iterator
|
||
while (NULL != (lpAlarm = m_EjectedNodeAlarmList2.Get(&uid)))
|
||
{
|
||
// Has the alarm expired for this node?
|
||
if (lpAlarm->IsExpired())
|
||
{
|
||
ConnectionHandle hConn;
|
||
|
||
/*
|
||
** Tell the owner object to disconnect the misbehaving node
|
||
** that exists at the connection handle accessed through
|
||
** the m_ChildUidConnHdlList2.
|
||
*/
|
||
if (NULL != (hConn = m_ChildUidConnHdlList2.Find(uid)))
|
||
{
|
||
//
|
||
// This must generate a disconnect provider for eject node to
|
||
// work properly.
|
||
//
|
||
g_pMCSIntf->DisconnectProviderRequest(hConn);
|
||
|
||
//
|
||
// Since this node will not get a disconnect indication when it
|
||
// issues a DisconnectProviderRequest we go ahead and call it
|
||
// from here.
|
||
//
|
||
m_pConf->DisconnectProviderIndication(hConn);
|
||
}
|
||
}
|
||
|
||
// Delete the alarm
|
||
delete lpAlarm;
|
||
}
|
||
}
|
||
}
|
||
|
||
BOOL MCSUser::
|
||
FlushOutgoingPDU ( void )
|
||
{
|
||
|
||
DWORD mcs_message_count;
|
||
DWORD count;
|
||
UINT rc;
|
||
SEND_DATA_REQ_INFO *pReqInfo;
|
||
|
||
mcs_message_count = m_OutgoingPDUQueue.GetCount();
|
||
for (count = 0;
|
||
(count < mcs_message_count) && (m_OutgoingPDUQueue.IsEmpty() == FALSE);
|
||
count++)
|
||
{
|
||
/*
|
||
** Get the next message from the queue.
|
||
*/
|
||
pReqInfo = m_OutgoingPDUQueue.Get();
|
||
|
||
/*
|
||
* If MCS takes the request without an error, free information
|
||
* structure and unlock the encoded information in the packet.
|
||
* Unlocking the packet before deleting the infomration structure
|
||
* ensures that packet object is deleted and not left dangling.
|
||
* This is true because here only one lock is performed.
|
||
* If there is an error in the send data request, it means mcs can not
|
||
* take any more requests, therefore insert the information
|
||
* structure back in the queue and break out of this loop.
|
||
*/
|
||
if (pReqInfo->uniform_send)
|
||
{
|
||
rc = g_pMCSIntf->UniformSendDataRequest(
|
||
pReqInfo->channel_id,
|
||
m_pMCSSap,
|
||
pReqInfo->priority,
|
||
(LPBYTE) pReqInfo->packet->GetEncodedData(),
|
||
pReqInfo->packet->GetEncodedDataLength());
|
||
}
|
||
else
|
||
{
|
||
rc = g_pMCSIntf->SendDataRequest(
|
||
pReqInfo->channel_id,
|
||
m_pMCSSap,
|
||
pReqInfo->priority,
|
||
(LPBYTE) pReqInfo->packet->GetEncodedData(),
|
||
pReqInfo->packet->GetEncodedDataLength());
|
||
}
|
||
|
||
if (rc == MCS_NO_ERROR)
|
||
{
|
||
pReqInfo->packet->Unlock();
|
||
delete pReqInfo;
|
||
}
|
||
else
|
||
{
|
||
TRACE_OUT(("MCSUser::FlushMessageQueue: Could not send queued packet data in this heartbeat"));
|
||
m_OutgoingPDUQueue.Prepend(pReqInfo);
|
||
break; // breaking out of the for loop
|
||
}
|
||
}
|
||
|
||
return (! (m_OutgoingPDUQueue.IsEmpty() && m_EjectedNodeAlarmList2.IsEmpty()));
|
||
}
|
||
|
||
/*
|
||
* MCSUser::SetChildUserID()
|
||
*
|
||
* Public Function Description:
|
||
* This function is called by the conference object to pass on the user id
|
||
* of the child node to the user object. The user object inserts this
|
||
* user id into a user id list of it's children which it maintains.
|
||
*/
|
||
void MCSUser::SetChildUserIDAndConnection (
|
||
UserID child_user_id,
|
||
ConnectionHandle child_connection_handle)
|
||
{
|
||
TRACE_OUT(("MCSUser::SetChildUserID: Adding Child userid=0x%04x to the list", (UINT) child_user_id));
|
||
TRACE_OUT(("MCSUser::SetChildUserID: Adding Child Connection=%d to the list", (UINT) child_connection_handle));
|
||
|
||
m_ChildUidConnHdlList2.Append(child_user_id, child_connection_handle);
|
||
}
|
||
|
||
/*
|
||
* GCCError InitiateEjectionFromConference()
|
||
*
|
||
* Private Function Description:
|
||
* This internal routine kicks of the process of ejecting this node
|
||
* from the conference. This includes ejecting all the nodes below
|
||
* this node and waiting for their disconnect indications to come back
|
||
* in.
|
||
*
|
||
* Formal Parameters:
|
||
* reason - (i) Reason for ejection.
|
||
*
|
||
* Return Value
|
||
* GCC_NO_ERROR - No error occured.
|
||
* GCC_ALLOCATION_FAILURE - A resource error occured.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
GCCError MCSUser::InitiateEjectionFromConference (GCCReason reason)
|
||
{
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
GCCPDU gcc_pdu;
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
PAlarm alarm = NULL;
|
||
|
||
m_fEjectionPending = TRUE;
|
||
m_eEjectReason = reason;
|
||
|
||
if (m_ChildUidConnHdlList2.IsEmpty() == FALSE)
|
||
{
|
||
UserID uid;
|
||
|
||
gcc_pdu.choice = INDICATION_CHOSEN;
|
||
gcc_pdu.u.indication.choice = CONFERENCE_EJECT_USER_INDICATION_CHOSEN;
|
||
|
||
gcc_pdu.u.indication.u.conference_eject_user_indication.reason =
|
||
::TranslateGCCReasonToEjectInd(
|
||
GCC_REASON_HIGHER_NODE_EJECTED);
|
||
|
||
m_ChildUidConnHdlList2.Reset();
|
||
while (m_ChildUidConnHdlList2.Iterate(&uid))
|
||
{
|
||
// Get the Node to eject from the list of child nodes
|
||
gcc_pdu.u.indication.u.conference_eject_user_indication.node_to_eject = uid;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
&gcc_pdu,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
alarm = new Alarm (EJECTED_NODE_TIMER_DURATION);
|
||
if (alarm != NULL)
|
||
{
|
||
/*
|
||
** Here we save the alarm in a list of ejected
|
||
** nodes. This alarm is used to cleanup any
|
||
** misbehaving node.
|
||
*/
|
||
m_EjectedNodeAlarmList2.Append(uid, alarm);
|
||
}
|
||
else
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
delete packet;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
m_pConf->ProcessEjectUserIndication(m_eEjectReason);
|
||
}
|
||
|
||
return (error_value);
|
||
}
|
||
|
||
/*
|
||
* UINT ProcessSendDataIndication()
|
||
*
|
||
* Private Function Description:
|
||
* This function is called when the user object gets send data indications
|
||
* from below. It finds out the message type and decodes the pdu in the
|
||
* user data field of send data indications. Based on the type of decoded
|
||
* pdu it take the necessary actions.
|
||
*
|
||
* Formal Parameters:
|
||
* send_data_info - (i) Send data structure to process.
|
||
*
|
||
* Return Value
|
||
* MCS_NO_ERROR is always returned from this routine.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
UINT MCSUser::ProcessSendDataIndication(PSendData send_data_info)
|
||
{
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
PGCCPDU gcc_pdu;
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
UserID initiator;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPBYTE)send_data_info->user_data.value,
|
||
send_data_info->user_data.length,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if(packet != NULL && packet_error == PACKET_NO_ERROR)
|
||
{
|
||
initiator = send_data_info->initiator;
|
||
gcc_pdu = (PGCCPDU)packet->GetDecodedData();
|
||
switch(gcc_pdu->choice)
|
||
{
|
||
case INDICATION_CHOSEN: // Data PDU
|
||
switch(gcc_pdu->u.indication.choice)
|
||
{
|
||
case USER_ID_INDICATION_CHOSEN:
|
||
{
|
||
/*
|
||
* Sequence number and User Id sent by the child
|
||
* node after a successful conference create or
|
||
* join.
|
||
*/
|
||
m_pConf->ProcessUserIDIndication(
|
||
gcc_pdu->u.indication.u.user_id_indication.tag,
|
||
initiator);
|
||
}
|
||
break;
|
||
|
||
case ROSTER_UPDATE_INDICATION_CHOSEN:
|
||
if(send_data_info->channel_id == m_nidMyself)
|
||
{
|
||
//
|
||
// We only process the roster update if the conference is
|
||
// established.
|
||
//
|
||
if (m_pConf->IsConfEstablished())
|
||
{
|
||
m_pConf->ProcessRosterUpdatePDU(gcc_pdu, initiator);
|
||
}
|
||
}
|
||
break;
|
||
|
||
case CONFERENCE_TIME_INQUIRE_INDICATION_CHOSEN:
|
||
g_pControlSap->ConfTimeInquireIndication(
|
||
m_pConf->GetConfID(),
|
||
gcc_pdu->u.indication.u.conference_time_inquire_indication.time_is_node_specific,
|
||
initiator);
|
||
break;
|
||
|
||
case CONFERENCE_TIME_EXTEND_INDICATION_CHOSEN:
|
||
#ifdef JASPER
|
||
ProcessConferenceExtendIndicationPDU(
|
||
&gcc_pdu->u.indication.u.
|
||
conference_time_extend_indication,
|
||
initiator);
|
||
#endif // JASPER
|
||
break;
|
||
|
||
case APPLICATION_INVOKE_INDICATION_CHOSEN:
|
||
ProcessApplicationInvokeIndication(
|
||
&gcc_pdu->u.indication.u.
|
||
application_invoke_indication,
|
||
initiator);
|
||
break;
|
||
|
||
case TEXT_MESSAGE_INDICATION_CHOSEN:
|
||
#ifdef JASPER
|
||
if (ProcessTextMessageIndication(
|
||
&gcc_pdu->u.indication.u.
|
||
text_message_indication,
|
||
initiator) != GCC_NO_ERROR)
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
#endif // JASPER
|
||
break;
|
||
|
||
case CONFERENCE_LOCK_INDICATION_CHOSEN:
|
||
m_pConf->ProcessConferenceLockIndication(initiator);
|
||
break;
|
||
|
||
case CONFERENCE_UNLOCK_INDICATION_CHOSEN:
|
||
m_pConf->ProcessConferenceUnlockIndication(initiator);
|
||
break;
|
||
|
||
default:
|
||
ERROR_OUT(("User::ProcessSendDataIndication Unsupported PDU"));
|
||
break;
|
||
} // switch(gcc_pdu->u.indication.choice)
|
||
break;
|
||
|
||
case REQUEST_CHOSEN: // Connection(control) PDU
|
||
switch(gcc_pdu->u.request.choice)
|
||
{
|
||
case CONFERENCE_JOIN_REQUEST_CHOSEN:
|
||
ProcessConferenceJoinRequestPDU(
|
||
&gcc_pdu->u.request.u.conference_join_request,
|
||
send_data_info);
|
||
break;
|
||
|
||
case CONFERENCE_TERMINATE_REQUEST_CHOSEN:
|
||
ProcessConferenceTerminateRequestPDU(
|
||
&gcc_pdu->u.request.u.
|
||
conference_terminate_request,
|
||
send_data_info);
|
||
break;
|
||
|
||
case CONFERENCE_EJECT_USER_REQUEST_CHOSEN:
|
||
ProcessConferenceEjectUserRequestPDU(
|
||
&gcc_pdu->u.request.u.
|
||
conference_eject_user_request,
|
||
send_data_info);
|
||
break;
|
||
|
||
case REGISTRY_ALLOCATE_HANDLE_REQUEST_CHOSEN:
|
||
ProcessRegistryAllocateHandleRequestPDU(
|
||
&gcc_pdu->u.request.u.
|
||
registry_allocate_handle_request,
|
||
send_data_info);
|
||
break;
|
||
|
||
case CONFERENCE_LOCK_REQUEST_CHOSEN:
|
||
m_pConf->ProcessConferenceLockRequest(initiator);
|
||
break;
|
||
|
||
case CONFERENCE_UNLOCK_REQUEST_CHOSEN:
|
||
m_pConf->ProcessConferenceUnlockRequest(initiator);
|
||
break;
|
||
|
||
case CONFERENCE_TRANSFER_REQUEST_CHOSEN:
|
||
ProcessTransferRequestPDU(
|
||
&gcc_pdu->u.request.u.conference_transfer_request,
|
||
send_data_info);
|
||
break;
|
||
|
||
case CONFERENCE_ADD_REQUEST_CHOSEN:
|
||
ProcessAddRequestPDU (
|
||
&gcc_pdu->u.request.u.conference_add_request,
|
||
send_data_info);
|
||
break;
|
||
|
||
case REGISTRY_REGISTER_CHANNEL_REQUEST_CHOSEN:
|
||
case REGISTRY_ASSIGN_TOKEN_REQUEST_CHOSEN:
|
||
case REGISTRY_SET_PARAMETER_REQUEST_CHOSEN:
|
||
case REGISTRY_DELETE_ENTRY_REQUEST_CHOSEN:
|
||
case REGISTRY_RETRIEVE_ENTRY_REQUEST_CHOSEN:
|
||
case REGISTRY_MONITOR_ENTRY_REQUEST_CHOSEN:
|
||
ProcessRegistryRequestPDU( gcc_pdu,
|
||
send_data_info);
|
||
break;
|
||
|
||
default:
|
||
ERROR_OUT(("User::ProcessSendDataIndication this pdu choice is not supported"));
|
||
break;
|
||
} // switch(gcc_pdu->u.request.choice)
|
||
break;
|
||
|
||
case RESPONSE_CHOSEN: // Connection(control) PDU
|
||
switch(gcc_pdu->u.response.choice)
|
||
{
|
||
case CONFERENCE_JOIN_RESPONSE_CHOSEN:
|
||
/* This comes from top provider to the intermediate
|
||
* gcc provider which has to pass it on to the node
|
||
* that made a join request.
|
||
*/
|
||
ProcessConferenceJoinResponsePDU(
|
||
&gcc_pdu->u.response.u.
|
||
conference_join_response);
|
||
break;
|
||
|
||
case CONFERENCE_TERMINATE_RESPONSE_CHOSEN:
|
||
ProcessConferenceTerminateResponsePDU(
|
||
&gcc_pdu->u.response.u.
|
||
conference_terminate_response);
|
||
break;
|
||
|
||
case CONFERENCE_EJECT_USER_RESPONSE_CHOSEN:
|
||
ProcessConferenceEjectUserResponsePDU(
|
||
&gcc_pdu->u.response.u.
|
||
conference_eject_user_response);
|
||
break;
|
||
|
||
case REGISTRY_RESPONSE_CHOSEN:
|
||
ProcessRegistryResponsePDU(
|
||
&gcc_pdu->u.response.u.registry_response);
|
||
break;
|
||
|
||
case REGISTRY_ALLOCATE_HANDLE_RESPONSE_CHOSEN:
|
||
ProcessRegistryAllocateHandleResponsePDU(
|
||
&gcc_pdu->u.response.u.
|
||
registry_allocate_handle_response);
|
||
break;
|
||
|
||
case CONFERENCE_LOCK_RESPONSE_CHOSEN:
|
||
#ifdef JASPER
|
||
{
|
||
GCCResult result;
|
||
result = ::TranslateLockResultToGCCResult(gcc_pdu->u.response.u.conference_lock_response.result);
|
||
g_pControlSap->ConfLockConfirm(result, m_pConf->GetConfID());
|
||
}
|
||
#endif // JASPER
|
||
break;
|
||
|
||
case CONFERENCE_UNLOCK_RESPONSE_CHOSEN:
|
||
#ifdef JASPER
|
||
{
|
||
GCCResult result;
|
||
result = ::TranslateUnlockResultToGCCResult(gcc_pdu->u.response.u.conference_unlock_response.result);
|
||
g_pControlSap->ConfUnlockConfirm(result, m_pConf->GetConfID());
|
||
}
|
||
#endif // JASPER
|
||
break;
|
||
|
||
case CONFERENCE_TRANSFER_RESPONSE_CHOSEN:
|
||
#ifdef JASPER
|
||
ProcessTransferResponsePDU(
|
||
&gcc_pdu->u.response.u.conference_transfer_response);
|
||
#endif // JASPER
|
||
break;
|
||
|
||
case CONFERENCE_ADD_RESPONSE_CHOSEN:
|
||
ProcessAddResponsePDU(
|
||
&gcc_pdu->u.response.u.conference_add_response);
|
||
break;
|
||
|
||
case FUNCTION_NOT_SUPPORTED_RESPONSE_CHOSEN:
|
||
ProcessFunctionNotSupported (
|
||
(UINT) gcc_pdu->u.response.u.function_not_supported_response.request.choice);
|
||
break;
|
||
|
||
// other cases to be added as we go along.
|
||
default:
|
||
ERROR_OUT(("User::ProcessSendDataIndication this pdu choice is not supported"));
|
||
break;
|
||
} // switch(gcc_pdu->u.response.choice)
|
||
break;
|
||
|
||
default:
|
||
ERROR_OUT(("User::ProcessSendDataIndication this pdu type"));
|
||
break;
|
||
} // switch(gcc_pdu->choice)
|
||
packet->Unlock();
|
||
}
|
||
else
|
||
{
|
||
delete packet;
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
|
||
return(MCS_NO_ERROR);
|
||
}
|
||
|
||
/*
|
||
* void ProcessConferenceJoinRequestPDU ()
|
||
*
|
||
* Private Function Description:
|
||
* This PDU comes from below (intermediate directly connected node) to the
|
||
* top gcc provider. Pull out the tag number and user id from the
|
||
* pdu and store in a list.
|
||
*
|
||
* Formal Parameters:
|
||
* join_request - (i) Join request PDU structure to process.
|
||
* send_data_info - (i) Send data structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::ProcessConferenceJoinRequestPDU(
|
||
PConferenceJoinRequest join_request,
|
||
PSendData send_data_info)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
UserJoinRequestInfo join_request_info;
|
||
|
||
/*
|
||
** Build all the containers to be used in the join request info structure.
|
||
*/
|
||
|
||
// Build the convener password container
|
||
if ((join_request->bit_mask & CJRQ_CONVENER_PASSWORD_PRESENT) &&
|
||
(rc == GCC_NO_ERROR))
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
join_request_info.convener_password = new CPassword(
|
||
&join_request->cjrq_convener_password,
|
||
&rc);
|
||
|
||
if (join_request_info.convener_password == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
join_request_info.convener_password = NULL;
|
||
}
|
||
|
||
// Build the password challenge container
|
||
if ((join_request->bit_mask & CJRQ_PASSWORD_PRESENT) &&
|
||
(rc == GCC_NO_ERROR))
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
join_request_info.password_challenge = new CPassword(
|
||
&join_request->cjrq_password,
|
||
&rc);
|
||
|
||
if (join_request_info.password_challenge == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
join_request_info.password_challenge = NULL;
|
||
}
|
||
|
||
// Build the caller identifier container
|
||
if ((join_request->bit_mask & CJRQ_CALLER_ID_PRESENT) &&
|
||
(rc == GCC_NO_ERROR))
|
||
{
|
||
if (NULL == (join_request_info.pwszCallerID = ::My_strdupW2(
|
||
join_request->cjrq_caller_id.length,
|
||
join_request->cjrq_caller_id.value)))
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
join_request_info.pwszCallerID = NULL;
|
||
}
|
||
|
||
// Build the password challenge container
|
||
if ((join_request->bit_mask & CJRQ_USER_DATA_PRESENT) &&
|
||
(rc == GCC_NO_ERROR))
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
join_request_info.user_data_list = new CUserDataListContainer(join_request->cjrq_user_data, &rc);
|
||
if (join_request_info.user_data_list == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
join_request_info.user_data_list = NULL;
|
||
}
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
m_ConfJoinResponseList2.Append(send_data_info->initiator, join_request->tag);
|
||
|
||
join_request_info.sender_id = send_data_info->initiator;
|
||
|
||
g_pControlSap->ForwardedConfJoinIndication(
|
||
join_request_info.sender_id,
|
||
m_pConf->GetConfID(),
|
||
join_request_info.convener_password,
|
||
join_request_info.password_challenge,
|
||
join_request_info.pwszCallerID,
|
||
join_request_info.user_data_list);
|
||
}
|
||
|
||
// Free up the containers allocated above
|
||
if (join_request_info.convener_password != NULL)
|
||
{
|
||
join_request_info.convener_password->Release();
|
||
}
|
||
|
||
if (join_request_info.password_challenge != NULL)
|
||
{
|
||
join_request_info.password_challenge->Release();
|
||
}
|
||
|
||
delete join_request_info.pwszCallerID;
|
||
|
||
if (join_request_info.user_data_list != NULL)
|
||
{
|
||
join_request_info.user_data_list->Release();
|
||
}
|
||
|
||
if (rc == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void ProcessConferenceJoinResponsePDU ()
|
||
*
|
||
* Private Function Description:
|
||
* This comes from top provider to the intermediate gcc provider which has
|
||
* to pass it on to the node that made a join request.
|
||
*
|
||
* Formal Parameters:
|
||
* join_response - (i) Join response PDU structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::ProcessConferenceJoinResponsePDU(
|
||
PConferenceJoinResponse join_response)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
UserJoinResponseInfo join_response_info;
|
||
|
||
// Store the password data in the join response info structure
|
||
if ((join_response->bit_mask & CJRS_PASSWORD_PRESENT) &&
|
||
(rc == GCC_NO_ERROR))
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
join_response_info.password_challenge = new CPassword(
|
||
&join_response->cjrs_password,
|
||
&rc);
|
||
if (join_response_info.password_challenge == NULL)
|
||
{
|
||
rc = GCC_NO_ERROR;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
join_response_info.password_challenge = NULL;
|
||
}
|
||
|
||
// Store the user data in the join response info structure
|
||
if ((join_response->bit_mask & CJRS_USER_DATA_PRESENT) &&
|
||
(rc == GCC_NO_ERROR))
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
join_response_info.user_data_list = new CUserDataListContainer(join_response->cjrs_user_data, &rc);
|
||
if (join_response_info.user_data_list == NULL)
|
||
{
|
||
rc = GCC_NO_ERROR;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
join_response_info.user_data_list = NULL;
|
||
}
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
join_response_info.connection_handle = (ConnectionHandle)join_response->tag;
|
||
join_response_info.result = ::TranslateJoinResultToGCCResult(join_response->result);
|
||
|
||
m_pConf->ProcessConfJoinResponse(&join_response_info);
|
||
}
|
||
|
||
// Free up the containers allocated above
|
||
if (join_response_info.password_challenge != NULL)
|
||
join_response_info.password_challenge->Release();
|
||
|
||
if (join_response_info.user_data_list != NULL)
|
||
join_response_info.user_data_list->Release();
|
||
|
||
// Cleanup after any allocation failures.
|
||
if (rc == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void ProcessConferenceTerminateRequestPDU()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* Terminate Request PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* terminate_request - (i) Terminate request PDU structure to process.
|
||
* send_data_info - (i) Send data structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::
|
||
ProcessConferenceTerminateRequestPDU
|
||
(
|
||
PConferenceTerminateRequest terminate_request,
|
||
PSendData send_data_info
|
||
)
|
||
{
|
||
m_pConf->ProcessTerminateRequest(
|
||
send_data_info->initiator,
|
||
::TranslateTerminateRqReasonToGCCReason(terminate_request->reason));
|
||
}
|
||
|
||
/*
|
||
* void ProcessConferenceEjectUserRequestPDU()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* eject user request PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* eject_user_request - (i) Eject user request PDU structure to process.
|
||
* send_data_info - (i) Send data structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::ProcessConferenceEjectUserRequestPDU(
|
||
PConferenceEjectUserRequest eject_user_request,
|
||
PSendData send_data_info)
|
||
{
|
||
UserEjectNodeRequestInfo eject_node_request;
|
||
|
||
eject_node_request.requester_id = send_data_info->initiator;
|
||
eject_node_request.node_to_eject = eject_user_request->node_to_eject;
|
||
eject_node_request.reason = GCC_REASON_NODE_EJECTED;
|
||
|
||
m_pConf->ProcessEjectUserRequest(&eject_node_request);
|
||
}
|
||
|
||
/*
|
||
* void ProcessConferenceTerminateResponsePDU()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* terminate response PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* terminate_response - (i) Terminate response PDU structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::ProcessConferenceTerminateResponsePDU(
|
||
PConferenceTerminateResponse terminate_response)
|
||
{
|
||
GCCResult result = ::TranslateTerminateResultToGCCResult(terminate_response->result);
|
||
|
||
//
|
||
// If the terminate was successful, go ahead and set the
|
||
// conference to not established.
|
||
//
|
||
if (result == GCC_RESULT_SUCCESSFUL)
|
||
{
|
||
m_pConf->ConfIsOver();
|
||
}
|
||
|
||
g_pControlSap->ConfTerminateConfirm(m_pConf->GetConfID(), result);
|
||
}
|
||
|
||
|
||
/*
|
||
* void ProcessConferenceEjectUserResponsePDU()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* Eject User response PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* eject_user_response - (i) Eject user response PDU structure to
|
||
* process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::ProcessConferenceEjectUserResponsePDU(
|
||
PConferenceEjectUserResponse eject_user_response)
|
||
{
|
||
UserEjectNodeResponseInfo eject_node_response;
|
||
|
||
eject_node_response.node_to_eject = eject_user_response->node_to_eject;
|
||
|
||
eject_node_response.result = ::TranslateEjectResultToGCCResult(
|
||
eject_user_response->result);
|
||
|
||
m_pConf->ProcessEjectUserResponse(&eject_node_response);
|
||
}
|
||
|
||
/*
|
||
* void ProcessRegistryRequest()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Registry
|
||
* request PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* gcc_pdu - (i) This is the PDU structure to process.
|
||
* send_data_info - (i) Send data structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::
|
||
ProcessRegistryRequestPDU
|
||
(
|
||
PGCCPDU gcc_pdu,
|
||
PSendData send_data_info
|
||
)
|
||
{
|
||
CRegistry *pAppReg = m_pConf->GetRegistry();
|
||
|
||
if (NULL != pAppReg)
|
||
{
|
||
GCCError rc = GCC_ALLOCATION_FAILURE;
|
||
CRegKeyContainer *pRegKey = NULL;
|
||
|
||
switch (gcc_pdu->u.request.choice)
|
||
{
|
||
case REGISTRY_REGISTER_CHANNEL_REQUEST_CHOSEN:
|
||
DBG_SAVE_FILE_LINE
|
||
pRegKey = new CRegKeyContainer(
|
||
&gcc_pdu->u.request.u.registry_register_channel_request.key,
|
||
&rc);
|
||
if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
pAppReg->ProcessRegisterChannelPDU(
|
||
pRegKey,
|
||
gcc_pdu->u.request.u.registry_register_channel_request.channel_id,
|
||
send_data_info->initiator, // Requester node id
|
||
gcc_pdu->u.request.u.registry_register_channel_request.entity_id);
|
||
}
|
||
else
|
||
{
|
||
// rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
break;
|
||
|
||
case REGISTRY_ASSIGN_TOKEN_REQUEST_CHOSEN:
|
||
DBG_SAVE_FILE_LINE
|
||
pRegKey = new CRegKeyContainer(
|
||
&gcc_pdu->u.request.u.registry_assign_token_request.registry_key,
|
||
&rc);
|
||
if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
pAppReg->ProcessAssignTokenPDU(
|
||
pRegKey,
|
||
send_data_info->initiator, // Requester node id
|
||
gcc_pdu->u.request.u.registry_assign_token_request.entity_id);
|
||
}
|
||
else
|
||
{
|
||
// rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
break;
|
||
|
||
case REGISTRY_SET_PARAMETER_REQUEST_CHOSEN:
|
||
DBG_SAVE_FILE_LINE
|
||
pRegKey = new CRegKeyContainer(
|
||
&gcc_pdu->u.request.u.registry_set_parameter_request.key,
|
||
&rc);
|
||
if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
OSTR oszParamValue;
|
||
LPOSTR poszParamValue;
|
||
GCCModificationRights eRights;
|
||
|
||
if (gcc_pdu->u.request.u.registry_set_parameter_request.
|
||
registry_set_parameter.length != 0)
|
||
{
|
||
poszParamValue = &oszParamValue;
|
||
oszParamValue.length = gcc_pdu->u.request.u.registry_set_parameter_request.
|
||
registry_set_parameter.length;
|
||
oszParamValue.value = gcc_pdu->u.request.u.registry_set_parameter_request.
|
||
registry_set_parameter.value;
|
||
}
|
||
else
|
||
{
|
||
poszParamValue = NULL;
|
||
}
|
||
|
||
if (gcc_pdu->u.request.u.registry_set_parameter_request.
|
||
bit_mask & PARAMETER_MODIFY_RIGHTS_PRESENT)
|
||
{
|
||
eRights = (GCCModificationRights)gcc_pdu->u.request.u.
|
||
registry_set_parameter_request.parameter_modify_rights;
|
||
}
|
||
else
|
||
{
|
||
eRights = GCC_NO_MODIFICATION_RIGHTS_SPECIFIED;
|
||
}
|
||
|
||
pAppReg->ProcessSetParameterPDU(
|
||
pRegKey,
|
||
poszParamValue,
|
||
eRights,
|
||
send_data_info->initiator, // Requester node id
|
||
gcc_pdu->u.request.u.registry_set_parameter_request.entity_id);
|
||
|
||
}
|
||
else
|
||
{
|
||
// rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
break;
|
||
|
||
case REGISTRY_RETRIEVE_ENTRY_REQUEST_CHOSEN:
|
||
DBG_SAVE_FILE_LINE
|
||
pRegKey = new CRegKeyContainer(
|
||
&gcc_pdu->u.request.u.registry_retrieve_entry_request.key,
|
||
&rc);
|
||
if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
pAppReg->ProcessRetrieveEntryPDU(
|
||
pRegKey,
|
||
send_data_info->initiator, // Requester node id
|
||
gcc_pdu->u.request.u.registry_retrieve_entry_request.entity_id);
|
||
}
|
||
else
|
||
{
|
||
// rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
break;
|
||
|
||
case REGISTRY_DELETE_ENTRY_REQUEST_CHOSEN:
|
||
DBG_SAVE_FILE_LINE
|
||
pRegKey = new CRegKeyContainer(
|
||
&gcc_pdu->u.request.u.registry_delete_entry_request.key,
|
||
&rc);
|
||
if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
pAppReg->ProcessDeleteEntryPDU (
|
||
pRegKey,
|
||
send_data_info->initiator, // Requester node id
|
||
gcc_pdu->u.request.u.registry_delete_entry_request.entity_id);
|
||
}
|
||
else
|
||
{
|
||
// rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
break;
|
||
|
||
case REGISTRY_MONITOR_ENTRY_REQUEST_CHOSEN:
|
||
DBG_SAVE_FILE_LINE
|
||
pRegKey = new CRegKeyContainer(
|
||
&gcc_pdu->u.request.u.registry_monitor_entry_request.key,
|
||
&rc);
|
||
if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
pAppReg->ProcessMonitorEntryPDU(
|
||
pRegKey,
|
||
send_data_info->initiator, // Requester node id
|
||
gcc_pdu->u.request.u.registry_monitor_entry_request.entity_id);
|
||
}
|
||
else
|
||
{
|
||
// rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (NULL != pRegKey)
|
||
{
|
||
pRegKey->Release();
|
||
}
|
||
|
||
// Handle resource errors
|
||
if (rc == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
} // if pAppReg != NULL
|
||
}
|
||
|
||
/*
|
||
* void ProcessRegistryAllocateHandleRequestPDU()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Allocate
|
||
* Handle request PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* allocate_handle_request - (i) This is the PDU structure to process.
|
||
* send_data_info - (i) Send data structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::
|
||
ProcessRegistryAllocateHandleRequestPDU
|
||
(
|
||
PRegistryAllocateHandleRequest allocate_handle_request,
|
||
PSendData send_data_info
|
||
)
|
||
{
|
||
CRegistry *pAppReg = m_pConf->GetRegistry();
|
||
|
||
if (NULL != pAppReg)
|
||
{
|
||
pAppReg->ProcessAllocateHandleRequestPDU(
|
||
allocate_handle_request->number_of_handles,
|
||
allocate_handle_request->entity_id,
|
||
send_data_info->initiator);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void ProcessRegistryResponsePDU()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Registry
|
||
* Response PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* registry_response - (i) This is the PDU structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::
|
||
ProcessRegistryResponsePDU ( PRegistryResponse registry_response )
|
||
{
|
||
CRegistry *pAppReg = m_pConf->GetRegistry();
|
||
|
||
if (NULL != pAppReg)
|
||
{
|
||
GCCError rc;
|
||
UserRegistryResponseInfo urri;
|
||
|
||
::ZeroMemory(&urri, sizeof(urri));
|
||
// urri.registry_key = NULL;
|
||
// urri.registry_item = NULL;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
urri.registry_key = new CRegKeyContainer(®istry_response->key, &rc);
|
||
if ((urri.registry_key != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
urri.registry_item = new CRegItem(®istry_response->item, &rc);
|
||
if ((urri.registry_item != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
// Set up the original requester entity id
|
||
urri.requester_entity_id = registry_response->entity_id;
|
||
|
||
// Set up the primitive type being responded to
|
||
urri.primitive_type = registry_response->primitive_type;
|
||
|
||
// Set up the owner related variables
|
||
if (registry_response->owner.choice == OWNED_CHOSEN)
|
||
{
|
||
urri.owner_node_id = registry_response->owner.u.owned.node_id;
|
||
urri.owner_entity_id = registry_response->owner.u.owned.entity_id;
|
||
}
|
||
else
|
||
{
|
||
// urri.owner_node_id = 0;
|
||
// urri.owner_entity_id = 0;
|
||
}
|
||
|
||
// Set up the modification rights
|
||
if (registry_response->bit_mask & RESPONSE_MODIFY_RIGHTS_PRESENT)
|
||
{
|
||
urri.modification_rights = (GCCModificationRights)registry_response->response_modify_rights;
|
||
}
|
||
else
|
||
{
|
||
urri.modification_rights = GCC_NO_MODIFICATION_RIGHTS_SPECIFIED;
|
||
}
|
||
|
||
// Translate the result to a GCC result
|
||
urri.result = ::TranslateRegistryRespToGCCResult(registry_response->result);
|
||
|
||
pAppReg->ProcessRegistryResponsePDU(
|
||
urri.primitive_type,
|
||
urri.registry_key,
|
||
urri.registry_item,
|
||
urri.modification_rights,
|
||
urri.requester_entity_id,
|
||
urri.owner_node_id,
|
||
urri.owner_entity_id,
|
||
urri.result);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
|
||
if (NULL != urri.registry_key)
|
||
{
|
||
urri.registry_key->Release();
|
||
}
|
||
if (NULL != urri.registry_item)
|
||
{
|
||
urri.registry_item->Release();
|
||
}
|
||
|
||
// Handle any resource errors
|
||
if (rc == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
} // if pAppReg != NULL
|
||
}
|
||
|
||
/*
|
||
* void ProcessAllocateHandleResponsePDU()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Allocate
|
||
* Handle Response PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* allocate_handle_response- (i) This is the PDU structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::
|
||
ProcessRegistryAllocateHandleResponsePDU
|
||
(
|
||
PRegistryAllocateHandleResponse allocate_handle_response
|
||
)
|
||
{
|
||
CRegistry *pAppReg = m_pConf->GetRegistry();
|
||
|
||
if (NULL != pAppReg)
|
||
{
|
||
pAppReg->ProcessAllocateHandleResponsePDU(
|
||
allocate_handle_response->number_of_handles,
|
||
allocate_handle_response->first_handle,
|
||
allocate_handle_response->entity_id,
|
||
(allocate_handle_response->result == RARS_RESULT_SUCCESS) ?
|
||
GCC_RESULT_SUCCESSFUL :
|
||
GCC_RESULT_NO_HANDLES_AVAILABLE);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void ProcessTransferRequestPDU()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Transfer
|
||
* request PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* transfer_request - (i) This is the PDU structure to process.
|
||
* send_data_info - (i) Send data structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::
|
||
ProcessTransferRequestPDU
|
||
(
|
||
PConferenceTransferRequest transfer_request,
|
||
PSendData send_data_info
|
||
)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
TransferInfo transfer_info;
|
||
PSetOfTransferringNodesRq set_of_nodes;
|
||
LPBYTE sub_node_list_memory = NULL;
|
||
Int i;
|
||
|
||
// Make sure that this node is the top provider
|
||
if (GetMyNodeID() != GetTopNodeID())
|
||
return;
|
||
|
||
::ZeroMemory(&transfer_info, sizeof(transfer_info));
|
||
|
||
// First set up the conference name
|
||
if (transfer_request->conference_name.choice ==
|
||
NAME_SELECTOR_NUMERIC_CHOSEN)
|
||
{
|
||
transfer_info.destination_conference_name.numeric_string =
|
||
(LPSTR) transfer_request->conference_name.u.name_selector_numeric;
|
||
// transfer_info.destination_conference_name.text_string = NULL;
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.destination_conference_name.numeric_string = NULL;
|
||
if (NULL == (transfer_info.destination_conference_name.text_string = ::My_strdupW2(
|
||
transfer_request->conference_name.u.name_selector_text.length,
|
||
transfer_request->conference_name.u.name_selector_text.value)))
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
|
||
|
||
// Next set up the conference name modifier
|
||
if (transfer_request->bit_mask & CTRQ_CONFERENCE_MODIFIER_PRESENT)
|
||
{
|
||
transfer_info.destination_conference_modifier =
|
||
(LPSTR) transfer_request->ctrq_conference_modifier;
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.destination_conference_modifier = NULL;
|
||
}
|
||
|
||
// Next set up the network address
|
||
if (transfer_request->bit_mask & CTRQ_NETWORK_ADDRESS_PRESENT)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
transfer_info.destination_address_list = new CNetAddrListContainer(
|
||
transfer_request->ctrq_net_address,
|
||
&rc);
|
||
if (transfer_info.destination_address_list == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.destination_address_list = NULL;
|
||
}
|
||
|
||
|
||
// Set up the transferring nodes list
|
||
if (transfer_request->bit_mask & CTRQ_TRANSFERRING_NODES_PRESENT)
|
||
{
|
||
// First determine the number of nodes.
|
||
set_of_nodes = transfer_request->ctrq_transferring_nodes;
|
||
// transfer_info.number_of_destination_nodes = 0;
|
||
while (set_of_nodes != NULL)
|
||
{
|
||
transfer_info.number_of_destination_nodes++;
|
||
set_of_nodes = set_of_nodes->next;
|
||
}
|
||
|
||
// Next allocate the memory required to hold the sub nodes
|
||
DBG_SAVE_FILE_LINE
|
||
sub_node_list_memory = new BYTE[sizeof(UserID) * transfer_info.number_of_destination_nodes];
|
||
|
||
// Now fill in the permission list
|
||
if (sub_node_list_memory != NULL)
|
||
{
|
||
transfer_info.destination_node_list = (PUserID) sub_node_list_memory;
|
||
|
||
set_of_nodes = transfer_request->ctrq_transferring_nodes;
|
||
for (i = 0; i < transfer_info.number_of_destination_nodes; i++)
|
||
{
|
||
transfer_info.destination_node_list[i] = set_of_nodes->value;
|
||
set_of_nodes = set_of_nodes->next;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser: ProcessTransferRequestPDU: Memory Manager Alloc Failure"));
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.number_of_destination_nodes = 0;
|
||
// transfer_info.destination_node_list = NULL;
|
||
}
|
||
|
||
// Set up the password
|
||
if (transfer_request->bit_mask & CTRQ_PASSWORD_PRESENT)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
transfer_info.password = new CPassword(&transfer_request->ctrq_password, &rc);
|
||
if (transfer_info.password == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.password = NULL;
|
||
}
|
||
|
||
// Save the sender ID
|
||
transfer_info.requesting_node_id = send_data_info->initiator;
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
m_pConf->ProcessConferenceTransferRequest(
|
||
transfer_info.requesting_node_id,
|
||
&transfer_info.destination_conference_name,
|
||
transfer_info.destination_conference_modifier,
|
||
transfer_info.destination_address_list,
|
||
transfer_info.number_of_destination_nodes,
|
||
transfer_info.destination_node_list,
|
||
transfer_info.password);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser::ProcessTransferRequestPDU: Allocation Failure"));
|
||
if (GCC_ALLOCATION_FAILURE == rc)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
// Now cleanup any allocated memory
|
||
if (transfer_info.destination_address_list != NULL)
|
||
{
|
||
transfer_info.destination_address_list->Release();
|
||
}
|
||
|
||
delete sub_node_list_memory;
|
||
|
||
if (transfer_info.password != NULL)
|
||
{
|
||
transfer_info.password->Release();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void ProcessAddRequestPDU ()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference Add
|
||
* request PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* conference_add_request - (i) This is the PDU structure to process.
|
||
* send_data_info - (i) Send data structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::ProcessAddRequestPDU (
|
||
PConferenceAddRequest conference_add_request,
|
||
PSendData send_data_info)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
AddRequestInfo add_request_info;
|
||
|
||
/*
|
||
** Ignore this request if this node is NOT the Top Provider and the request
|
||
** did not come from the Top Provider.
|
||
*/
|
||
if (m_nidTopProvider != m_nidMyself)
|
||
{
|
||
if (m_nidTopProvider != send_data_info->initiator)
|
||
return;
|
||
}
|
||
|
||
::ZeroMemory(&add_request_info, sizeof(add_request_info));
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
add_request_info.network_address_list = new CNetAddrListContainer(
|
||
conference_add_request->add_request_net_address,
|
||
&rc);
|
||
if (add_request_info.network_address_list == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
|
||
if ((rc == GCC_NO_ERROR) &&
|
||
(conference_add_request->bit_mask & CARQ_USER_DATA_PRESENT))
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
add_request_info.user_data_list = new CUserDataListContainer(conference_add_request->carq_user_data, &rc);
|
||
if (add_request_info.user_data_list == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// add_request_info.user_data_list = NULL;
|
||
}
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
add_request_info.adding_node = (conference_add_request->bit_mask & ADDING_MCU_PRESENT) ?
|
||
conference_add_request->adding_mcu : 0;
|
||
add_request_info.requesting_node = conference_add_request->requesting_node;
|
||
add_request_info.add_request_tag = (TagNumber)conference_add_request->tag;
|
||
|
||
m_pConf->ProcessConferenceAddRequest(
|
||
add_request_info.network_address_list,
|
||
add_request_info.user_data_list,
|
||
add_request_info.adding_node,
|
||
add_request_info.add_request_tag,
|
||
add_request_info.requesting_node);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser::ProcessAddRequestPDU: Allocation Failure"));
|
||
if (GCC_ALLOCATION_FAILURE == rc)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
if (add_request_info.network_address_list != NULL)
|
||
{
|
||
add_request_info.network_address_list->Release();
|
||
}
|
||
|
||
if (add_request_info.user_data_list != NULL)
|
||
{
|
||
add_request_info.user_data_list->Release();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void ProcessTransferResponsePDU()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* Transfer response PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* transfer_response - (i) This is the PDU structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
#ifdef JASPER
|
||
void MCSUser::ProcessTransferResponsePDU (
|
||
PConferenceTransferResponse transfer_response)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
TransferInfo transfer_info;
|
||
PSetOfTransferringNodesRs set_of_nodes;
|
||
LPBYTE sub_node_list_memory = NULL;
|
||
Int i;
|
||
|
||
::ZeroMemory(&transfer_info, sizeof(transfer_info));
|
||
|
||
// First set up the conference name
|
||
if (transfer_response->conference_name.choice ==
|
||
NAME_SELECTOR_NUMERIC_CHOSEN)
|
||
{
|
||
transfer_info.destination_conference_name.numeric_string =
|
||
(LPSTR) transfer_response->conference_name.u.name_selector_numeric;
|
||
// transfer_info.destination_conference_name.text_string = NULL;
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.destination_conference_name.numeric_string = NULL;
|
||
if (NULL == (transfer_info.destination_conference_name.text_string = ::My_strdupW2(
|
||
transfer_response->conference_name.u.name_selector_text.length,
|
||
transfer_response->conference_name.u.name_selector_text.value)))
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
|
||
// Next set up the conference name modifier
|
||
if (transfer_response->bit_mask & CTRS_CONFERENCE_MODIFIER_PRESENT)
|
||
{
|
||
transfer_info.destination_conference_modifier =
|
||
(LPSTR) transfer_response->ctrs_conference_modifier;
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.destination_conference_modifier = NULL;
|
||
}
|
||
|
||
// Set up the transferring nodes list
|
||
if (transfer_response->bit_mask & CTRS_TRANSFERRING_NODES_PRESENT)
|
||
{
|
||
// First determine the number of nodes.
|
||
set_of_nodes = transfer_response->ctrs_transferring_nodes;
|
||
// transfer_info.number_of_destination_nodes = 0;
|
||
while (set_of_nodes != NULL)
|
||
{
|
||
transfer_info.number_of_destination_nodes++;
|
||
set_of_nodes = set_of_nodes->next;
|
||
}
|
||
|
||
// Next allocate the memory required to hold the sub nodes
|
||
DBG_SAVE_FILE_LINE
|
||
sub_node_list_memory = new BYTE[sizeof(UserID) * transfer_info.number_of_destination_nodes];
|
||
|
||
// Now fill in the permission list
|
||
if (sub_node_list_memory != NULL)
|
||
{
|
||
transfer_info.destination_node_list = (PUserID) sub_node_list_memory;
|
||
|
||
set_of_nodes = transfer_response->ctrs_transferring_nodes;
|
||
for (i = 0; i < transfer_info.number_of_destination_nodes; i++)
|
||
{
|
||
transfer_info.destination_node_list[i] = set_of_nodes->value;
|
||
set_of_nodes = set_of_nodes->next;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser: ProcessTransferResponsePDU: Memory Manager Alloc Failure"));
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.number_of_destination_nodes = 0;
|
||
// transfer_info.destination_node_list = NULL;
|
||
}
|
||
|
||
|
||
// Save the result
|
||
transfer_info.result = (transfer_response->result == CTRANS_RESULT_SUCCESS) ?
|
||
GCC_RESULT_SUCCESSFUL :
|
||
GCC_RESULT_INVALID_REQUESTER;
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
g_pControlSap->ConfTransferConfirm(
|
||
m_pConf->GetConfID(),
|
||
&transfer_info.destination_conference_name,
|
||
transfer_info.destination_conference_modifier,
|
||
transfer_info.number_of_destination_nodes,
|
||
transfer_info.destination_node_list,
|
||
transfer_info.result);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser::ProcessTransferResponsePDU: Allocation Failure"));
|
||
if (GCC_ALLOCATION_FAILURE == rc)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
// Now cleanup any allocated memory
|
||
delete sub_node_list_memory;
|
||
}
|
||
#endif // JASPER
|
||
|
||
|
||
/*
|
||
* void ProcessAddResponsePDU ()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* Add response PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* conference_add_response - (i) This is the PDU structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::ProcessAddResponsePDU (
|
||
PConferenceAddResponse conference_add_response)
|
||
{
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
AddResponseInfo add_response_info;
|
||
|
||
if (conference_add_response->bit_mask & CARS_USER_DATA_PRESENT)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
add_response_info.user_data_list = new CUserDataListContainer(conference_add_response->cars_user_data, &error_value);
|
||
if (add_response_info.user_data_list == NULL)
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
add_response_info.user_data_list = NULL;
|
||
}
|
||
|
||
if (error_value == GCC_NO_ERROR)
|
||
{
|
||
add_response_info.add_request_tag = (TagNumber)conference_add_response->tag;
|
||
add_response_info.result = ::TranslateAddResultToGCCResult(conference_add_response->result);
|
||
|
||
m_pConf->ProcessConfAddResponse(&add_response_info);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser::ProcessAddResponsePDU: Allocation Failure"));
|
||
if (GCC_ALLOCATION_FAILURE == error_value)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
if (add_response_info.user_data_list != NULL)
|
||
{
|
||
add_response_info.user_data_list->Release();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void ProcessFunctionNotSupported ()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing responses for request that
|
||
* are not supported at the node that the request was directed toward.
|
||
*
|
||
* Formal Parameters:
|
||
* request_choice - (i) This is the request that is not supported.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* The existance of this routine does not mean that this provider does
|
||
* not support it. It only means that the node which received the
|
||
* request does not support it.
|
||
*/
|
||
void MCSUser::
|
||
ProcessFunctionNotSupported ( UINT request_choice )
|
||
{
|
||
switch (request_choice)
|
||
{
|
||
case CONFERENCE_LOCK_REQUEST_CHOSEN:
|
||
#ifdef JASPER
|
||
g_pControlSap->ConfLockConfirm(GCC_RESULT_LOCKED_NOT_SUPPORTED, m_pConf->GetConfID());
|
||
#endif // JASPER
|
||
break;
|
||
|
||
case CONFERENCE_UNLOCK_REQUEST_CHOSEN:
|
||
#ifdef JASPER
|
||
g_pControlSap->ConfUnlockConfirm(GCC_RESULT_UNLOCK_NOT_SUPPORTED, m_pConf->GetConfID());
|
||
#endif // JASPER
|
||
break;
|
||
|
||
default:
|
||
ERROR_OUT(("MCSUser: ProcessFunctionNotSupported: "
|
||
"Error: Illegal request is unsupported"));
|
||
break;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* UINT ProcessUniformSendDataIndication ()
|
||
*
|
||
* Private Function Description:
|
||
* This function is called when the user object gets send data indications
|
||
* from below. It finds out the message type and decodes the pdu in the
|
||
* user data field of send data indications. Based on the type of decoded
|
||
* pdu it take the necessary actions.
|
||
* This routine is responsible for processing responses for request that
|
||
* are not supported at the node that the request was directed toward.
|
||
*
|
||
* Formal Parameters:
|
||
* send_data_info - (i) This is the MCS data structure to process.
|
||
*
|
||
* Return Value
|
||
* MCS_NO_ERROR is always returned.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
UINT MCSUser::ProcessUniformSendDataIndication(
|
||
PSendData send_data_info)
|
||
{
|
||
PPacket packet;
|
||
PacketError packet_error;
|
||
PGCCPDU gcc_pdu;
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
UserID initiator;
|
||
|
||
TRACE_OUT(("User: UniformSendDataInd: length = %d",
|
||
send_data_info->user_data.length));
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
packet = new Packet((PPacketCoder) g_GCCCoder,
|
||
PACKED_ENCODING_RULES,
|
||
(LPBYTE)send_data_info->user_data.value,
|
||
send_data_info->user_data.length,
|
||
GCC_PDU,
|
||
TRUE,
|
||
&packet_error);
|
||
if((packet != NULL) && (packet_error == PACKET_NO_ERROR))
|
||
{
|
||
initiator = send_data_info->initiator;
|
||
gcc_pdu = (PGCCPDU)packet->GetDecodedData();
|
||
switch (gcc_pdu->choice)
|
||
{
|
||
case INDICATION_CHOSEN: // Data PDU
|
||
switch(gcc_pdu->u.indication.choice)
|
||
{
|
||
case CONFERENCE_TERMINATE_INDICATION_CHOSEN:
|
||
/*
|
||
** Note that we allow the top provider to process
|
||
** this message so that it can set up its own
|
||
** node for termination in a generic way.
|
||
*/
|
||
ProcessConferenceTerminateIndicationPDU (
|
||
&gcc_pdu->u.indication.u.
|
||
conference_terminate_indication,
|
||
initiator);
|
||
break;
|
||
|
||
case CONFERENCE_EJECT_USER_INDICATION_CHOSEN:
|
||
/*
|
||
** Do not decode a packet that was sent uniformly
|
||
** from this node.
|
||
*/
|
||
if (initiator != m_nidMyself)
|
||
{
|
||
ProcessConferenceEjectUserIndicationPDU (
|
||
&gcc_pdu->u.indication.u.
|
||
conference_eject_user_indication,
|
||
initiator);
|
||
}
|
||
break;
|
||
|
||
case ROSTER_UPDATE_INDICATION_CHOSEN:
|
||
/*
|
||
** Do not decode a packet that was sent uniformly
|
||
** from this node.
|
||
*/
|
||
if ((initiator != m_nidMyself) &&
|
||
(send_data_info->channel_id ==
|
||
BROADCAST_CHANNEL_ID))
|
||
{
|
||
//
|
||
// We only process the roster update if the conference is
|
||
// established.
|
||
//
|
||
if (m_pConf->IsConfEstablished())
|
||
{
|
||
m_pConf->ProcessRosterUpdatePDU(gcc_pdu, initiator);
|
||
}
|
||
}
|
||
break;
|
||
|
||
case CONFERENCE_LOCK_INDICATION_CHOSEN:
|
||
m_pConf->ProcessConferenceLockIndication(initiator);
|
||
break;
|
||
|
||
case CONFERENCE_UNLOCK_INDICATION_CHOSEN:
|
||
m_pConf->ProcessConferenceUnlockIndication(initiator);
|
||
break;
|
||
|
||
case CONDUCTOR_ASSIGN_INDICATION_CHOSEN:
|
||
m_pConf->ProcessConductorAssignIndication(
|
||
gcc_pdu->u.indication.u.conductor_assign_indication.user_id,
|
||
initiator);
|
||
break;
|
||
|
||
case CONDUCTOR_RELEASE_INDICATION_CHOSEN:
|
||
if (initiator != m_nidMyself)
|
||
{
|
||
m_pConf->ProcessConductorReleaseIndication(initiator);
|
||
}
|
||
break;
|
||
|
||
case CONDUCTOR_PERMISSION_ASK_INDICATION_CHOSEN:
|
||
#ifdef JASPER
|
||
/*
|
||
** Do not decode a packet that was sent uniformly
|
||
** from this node.
|
||
*/
|
||
if (initiator != m_nidMyself)
|
||
{
|
||
PermitAskIndicationInfo indication_info;
|
||
|
||
indication_info.sender_id = initiator;
|
||
|
||
indication_info.permission_is_granted =
|
||
gcc_pdu->u.indication.u.
|
||
conductor_permission_ask_indication.
|
||
permission_is_granted;
|
||
|
||
m_pConf->ProcessConductorPermitAskIndication(&indication_info);
|
||
}
|
||
#endif // JASPER
|
||
break;
|
||
|
||
case CONDUCTOR_PERMISSION_GRANT_INDICATION_CHOSEN:
|
||
ProcessPermissionGrantIndication(
|
||
&(gcc_pdu->u.indication.u.
|
||
conductor_permission_grant_indication),
|
||
initiator);
|
||
break;
|
||
|
||
case CONFERENCE_TIME_REMAINING_INDICATION_CHOSEN:
|
||
#ifdef JASPER
|
||
ProcessTimeRemainingIndicationPDU (
|
||
&gcc_pdu->u.indication.u.
|
||
conference_time_remaining_indication,
|
||
initiator);
|
||
#endif // JASPER
|
||
break;
|
||
|
||
case APPLICATION_INVOKE_INDICATION_CHOSEN:
|
||
ProcessApplicationInvokeIndication(
|
||
&gcc_pdu->u.indication.u.
|
||
application_invoke_indication,
|
||
initiator);
|
||
break;
|
||
|
||
case TEXT_MESSAGE_INDICATION_CHOSEN:
|
||
#ifdef JASPER
|
||
if (ProcessTextMessageIndication(
|
||
&gcc_pdu->u.indication.u.
|
||
text_message_indication,
|
||
initiator) != GCC_NO_ERROR)
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
#endif // JASPER
|
||
break;
|
||
|
||
case CONFERENCE_ASSISTANCE_INDICATION_CHOSEN:
|
||
#ifdef JASPER
|
||
ProcessConferenceAssistanceIndicationPDU(
|
||
&gcc_pdu->u.indication.u.
|
||
conference_assistance_indication,
|
||
initiator);
|
||
#endif // JASPER
|
||
break;
|
||
|
||
case REGISTRY_MONITOR_ENTRY_INDICATION_CHOSEN:
|
||
/*
|
||
** Do not decode this packet if it was sent
|
||
** uniformly from this node.
|
||
*/
|
||
if (initiator != m_nidMyself)
|
||
{
|
||
ProcessRegistryMonitorIndicationPDU (
|
||
&gcc_pdu->u.indication.u.
|
||
registry_monitor_entry_indication,
|
||
initiator);
|
||
}
|
||
break;
|
||
|
||
case CONFERENCE_TRANSFER_INDICATION_CHOSEN:
|
||
#ifdef JASPER
|
||
/*
|
||
** Do not decode this packet if it was not sent
|
||
** from the top provider.
|
||
*/
|
||
if (initiator == m_nidTopProvider)
|
||
{
|
||
ProcessTransferIndicationPDU (
|
||
&gcc_pdu->u.indication.u.
|
||
conference_transfer_indication);
|
||
}
|
||
#endif // JASPER
|
||
break;
|
||
|
||
default:
|
||
ERROR_OUT(("MCSUser::ProcessSendDataIndication"
|
||
"Unsupported PDU"));
|
||
break;
|
||
} // switch(gcc_pdu->u.indication.choice)
|
||
break;
|
||
|
||
default:
|
||
ERROR_OUT(("MCSUser::ProcessUniformSendDataIndication. wrong pdu type "));
|
||
break;
|
||
}
|
||
packet->Unlock();
|
||
}
|
||
else
|
||
{
|
||
delete packet;
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
|
||
return (MCS_NO_ERROR);
|
||
}
|
||
|
||
/*
|
||
* void ProcessTransferIndicationPDU ()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* Transfer indication PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* transfer_indication - (i) This is the PDU structure to process.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
#ifdef JASPER
|
||
void MCSUser::
|
||
ProcessTransferIndicationPDU
|
||
(
|
||
PConferenceTransferIndication transfer_indication
|
||
)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
TransferInfo transfer_info;
|
||
PSetOfTransferringNodesIn set_of_nodes;
|
||
LPBYTE sub_node_list_memory = NULL;
|
||
Int i;
|
||
BOOL process_pdu = FALSE;
|
||
|
||
::ZeroMemory(&transfer_info, sizeof(transfer_info));
|
||
|
||
/*
|
||
** If there is a transferring node list we must determine if this node
|
||
** is in the list. If it isn't then the request is ignored.
|
||
*/
|
||
if (transfer_indication->bit_mask & CTIN_TRANSFERRING_NODES_PRESENT)
|
||
{
|
||
set_of_nodes = transfer_indication->ctin_transferring_nodes;
|
||
while (set_of_nodes != NULL)
|
||
{
|
||
if (set_of_nodes->value == GetMyNodeID())
|
||
{
|
||
process_pdu = TRUE;
|
||
break;
|
||
}
|
||
|
||
set_of_nodes = set_of_nodes->next;
|
||
}
|
||
|
||
if (process_pdu == FALSE)
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
|
||
// First set up the conference name
|
||
if (transfer_indication->conference_name.choice == NAME_SELECTOR_NUMERIC_CHOSEN)
|
||
{
|
||
transfer_info.destination_conference_name.numeric_string =
|
||
(LPSTR) transfer_indication->conference_name.u.name_selector_numeric;
|
||
// transfer_info.destination_conference_name.text_string = NULL;
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.destination_conference_name.numeric_string = NULL;
|
||
if (NULL == (transfer_info.destination_conference_name.text_string = ::My_strdupW2(
|
||
transfer_indication->conference_name.u.name_selector_text.length,
|
||
transfer_indication->conference_name.u.name_selector_text.value)))
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
|
||
// Next set up the conference name modifier
|
||
if (transfer_indication->bit_mask & CTIN_CONFERENCE_MODIFIER_PRESENT)
|
||
{
|
||
transfer_info.destination_conference_modifier =
|
||
(LPSTR) transfer_indication->ctin_conference_modifier;
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.destination_conference_modifier = NULL;
|
||
}
|
||
|
||
// Next set up the network address
|
||
if (transfer_indication->bit_mask & CTIN_NETWORK_ADDRESS_PRESENT)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
transfer_info.destination_address_list = new CNetAddrListContainer(
|
||
transfer_indication->ctin_net_address,
|
||
&rc);
|
||
if (transfer_info.destination_address_list == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.destination_address_list = NULL;
|
||
}
|
||
|
||
// Set up the transferring nodes list
|
||
if (transfer_indication->bit_mask & CTIN_TRANSFERRING_NODES_PRESENT)
|
||
{
|
||
// First determine the number of nodes.
|
||
set_of_nodes = transfer_indication->ctin_transferring_nodes;
|
||
// transfer_info.number_of_destination_nodes = 0;
|
||
while (set_of_nodes != NULL)
|
||
{
|
||
transfer_info.number_of_destination_nodes++;
|
||
set_of_nodes = set_of_nodes->next;
|
||
}
|
||
|
||
// Next allocate the memory required to hold the sub nodes
|
||
DBG_SAVE_FILE_LINE
|
||
sub_node_list_memory = new BYTE[sizeof(UserID) * transfer_info.number_of_destination_nodes];
|
||
|
||
// Now fill in the permission list
|
||
if (sub_node_list_memory != NULL)
|
||
{
|
||
transfer_info.destination_node_list = (PUserID) sub_node_list_memory;
|
||
|
||
set_of_nodes = transfer_indication->ctin_transferring_nodes;
|
||
for (i = 0; i < transfer_info.number_of_destination_nodes; i++)
|
||
{
|
||
transfer_info.destination_node_list[i] = set_of_nodes->value;
|
||
set_of_nodes = set_of_nodes->next;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser: ProcessTransferIndicationPDU: Memory Manager Alloc Failure"));
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.number_of_destination_nodes = 0;
|
||
// transfer_info.destination_node_list = NULL;
|
||
}
|
||
|
||
|
||
// Set up the password
|
||
if (transfer_indication->bit_mask & CTIN_PASSWORD_PRESENT)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
transfer_info.password = new CPassword(&transfer_indication->ctin_password, &rc);
|
||
if (transfer_info.password == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// transfer_info.password = NULL;
|
||
}
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
g_pControlSap->ConfTransferIndication(
|
||
m_pConf->GetConfID(),
|
||
&transfer_info.destination_conference_name,
|
||
transfer_info.destination_conference_modifier,
|
||
transfer_info.destination_address_list,
|
||
transfer_info.password);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser::ProcessTransferIndicationPDU: Allocation Failure"));
|
||
if (GCC_ALLOCATION_FAILURE == rc)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
// Now cleanup any allocated memory
|
||
if (NULL != transfer_info.destination_address_list)
|
||
{
|
||
transfer_info.destination_address_list->Release();
|
||
}
|
||
|
||
delete sub_node_list_memory;
|
||
|
||
if (NULL != transfer_info.password)
|
||
{
|
||
transfer_info.password->Release();
|
||
}
|
||
}
|
||
#endif // JASPER
|
||
|
||
/*
|
||
* void ProcessConferenceTerminateIndicationPDU()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* Terminate indication PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* terminate_indication - (i) This is the PDU structure to process.
|
||
* sender_id - (i) Node ID of node that sent this PDU.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::ProcessConferenceTerminateIndicationPDU (
|
||
PConferenceTerminateIndication terminate_indication,
|
||
UserID sender_id)
|
||
{
|
||
if (sender_id == m_nidTopProvider)
|
||
{
|
||
m_pConf->ProcessTerminateIndication(
|
||
::TranslateTerminateInReasonToGCCReason(terminate_indication->reason));
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void ProcessTimeRemainingIndicationPDU ()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* Time remaining indication PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* time_remaining_indication - (i) This is the PDU structure to process
|
||
* sender_id - (i) Node ID of node that sent this PDU.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
#ifdef JASPER
|
||
void MCSUser::
|
||
ProcessTimeRemainingIndicationPDU
|
||
(
|
||
PConferenceTimeRemainingIndication time_remaining_indication,
|
||
UserID sender_id
|
||
)
|
||
{
|
||
g_pControlSap->ConfTimeRemainingIndication(
|
||
m_pConf->GetConfID(),
|
||
sender_id,
|
||
(time_remaining_indication->bit_mask & TIME_REMAINING_NODE_ID_PRESENT) ?
|
||
time_remaining_indication->time_remaining_node_id : 0,
|
||
time_remaining_indication->time_remaining);
|
||
}
|
||
#endif // JASPER
|
||
|
||
/*
|
||
* void ProcessConferenceAssistanceIndicationPDU ()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* assistance indication PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* conf_assistance_indication - (i) This is the PDU structure to process
|
||
* sender_id - (i) Node ID of node that sent this PDU.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
#ifdef JASPER
|
||
void MCSUser::
|
||
ProcessConferenceAssistanceIndicationPDU
|
||
(
|
||
PConferenceAssistanceIndication conf_assistance_indication,
|
||
UserID sender_id
|
||
)
|
||
{
|
||
GCCError rc = GCC_NO_ERROR;
|
||
CUserDataListContainer *user_data_list = NULL;
|
||
|
||
DebugEntry(MCSUser::ProcessConferenceAssistanceIndication);
|
||
|
||
// Unpack the user data list if it exists
|
||
if (conf_assistance_indication->bit_mask & CAIN_USER_DATA_PRESENT)
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
user_data_list = new CUserDataListContainer(conf_assistance_indication->cain_user_data, &rc);
|
||
if (user_data_list == NULL)
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
|
||
if (rc == GCC_NO_ERROR)
|
||
{
|
||
g_pControlSap->ConfAssistanceIndication(
|
||
m_pConf->GetConfID(),
|
||
user_data_list,
|
||
sender_id);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser::ProcessConferenceAssistanceIndication: can't create CUserDataListContainer"));
|
||
if (GCC_ALLOCATION_FAILURE == rc)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
}
|
||
#endif // JASPER
|
||
|
||
|
||
/*
|
||
* void ProcessConferenceExtendIndicationPDU()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* extend indication PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* conf_time_extend_indication - (i) This is the PDU structure to process
|
||
* sender_id - (i) Node ID of node that sent this PDU.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
#ifdef JASPER
|
||
void MCSUser::
|
||
ProcessConferenceExtendIndicationPDU
|
||
(
|
||
PConferenceTimeExtendIndication conf_time_extend_indication,
|
||
UserID sender_id
|
||
)
|
||
{
|
||
g_pControlSap->ConfExtendIndication(
|
||
m_pConf->GetConfID(),
|
||
conf_time_extend_indication->time_to_extend,
|
||
conf_time_extend_indication->time_is_node_specific,
|
||
sender_id);
|
||
}
|
||
#endif // JASPER
|
||
|
||
/*
|
||
* void ProcessConferenceEjectUserIndicationPDU ()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Conference
|
||
* eject user indication PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* eject_user_indication - (i) This is the PDU structure to process
|
||
* sender_id - (i) Node ID of node that sent this PDU.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::ProcessConferenceEjectUserIndicationPDU (
|
||
PConferenceEjectUserIndication eject_user_indication,
|
||
UserID sender_id)
|
||
{
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
PAlarm alarm = NULL;
|
||
|
||
// First check to make sure that this is the node being ejected
|
||
if (eject_user_indication->node_to_eject == m_nidMyself)
|
||
{
|
||
/*
|
||
** Next make sure the ejection came from either the Top Provider or
|
||
** the Parent Node.
|
||
*/
|
||
if ((sender_id == m_nidParent) || (sender_id == m_nidTopProvider))
|
||
{
|
||
TRACE_OUT(("MCSUser:ProcessEjectUserIndication: This node is ejected"));
|
||
error_value = InitiateEjectionFromConference (
|
||
::TranslateEjectIndReasonToGCCReason(
|
||
eject_user_indication->reason));
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser: ProcessEjectUserIndication: Received eject from illegal node"));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
TRACE_OUT(("MCSUser: ProcessEjectUserIndication: Received eject for node other than mine"));
|
||
|
||
/*
|
||
** If this node is a directly connected child node we insert an
|
||
** alarm in the list m_EjectedNodeAlarmList2 to disconnect it if
|
||
** it misbehaves and does not disconnect itself. Otherwise, we save
|
||
** the ejected user id in the m_EjectedNodeList to inform the local
|
||
** node of the correct reason for disconnecting (user ejected) when the
|
||
** detch user indication comes in.
|
||
*/
|
||
if (m_ChildUidConnHdlList2.Find(eject_user_indication->node_to_eject))
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
alarm = new Alarm (EJECTED_NODE_TIMER_DURATION);
|
||
if (alarm != NULL)
|
||
{
|
||
m_EjectedNodeAlarmList2.Append(eject_user_indication->node_to_eject, alarm);
|
||
}
|
||
else
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
** Here we save the alarm in a list of ejected nodes. This
|
||
** alarm is used to cleanup any misbehaving node. Note that
|
||
** if the ejected node is not a child of this node then no
|
||
** alarm is set up to monitor the ejection.
|
||
*/
|
||
m_EjectedNodeList.Append(eject_user_indication->node_to_eject);
|
||
}
|
||
}
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ERROR_OUT(("MCSUser::ProcessEjectUserIndication: Allocation Failure"));
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* void ProcessPermissionGrantIndication ()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Permission
|
||
* grant indication PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* permission_grant_indication - (i) This is the PDU structure to process
|
||
* sender_id - (i) Node ID of node that sent this PDU.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::ProcessPermissionGrantIndication(
|
||
PConductorPermissionGrantIndication permission_grant_indication,
|
||
UserID sender_id)
|
||
{
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
UserPermissionGrantIndicationInfo grant_indication_info;
|
||
PPermissionList permission_list;
|
||
LPBYTE permission_list_memory = NULL;
|
||
PWaitingList waiting_list;
|
||
LPBYTE waiting_list_memory = NULL;
|
||
UINT i;
|
||
|
||
// First count the number of entries in the permission list
|
||
grant_indication_info.number_granted = 0;
|
||
permission_list = permission_grant_indication->permission_list;
|
||
while (permission_list != NULL)
|
||
{
|
||
permission_list = permission_list->next;
|
||
grant_indication_info.number_granted++;
|
||
}
|
||
|
||
TRACE_OUT(("MCSUser: ProcessPermissionGrantIndication: number_granted=%d", (UINT) grant_indication_info.number_granted));
|
||
|
||
// If a list exist allocate memory for it and copy it over.
|
||
if (grant_indication_info.number_granted != 0)
|
||
{
|
||
// allocating space to hold permission list.
|
||
DBG_SAVE_FILE_LINE
|
||
permission_list_memory = new BYTE[sizeof(UserID) * grant_indication_info.number_granted];
|
||
|
||
// Now fill in the permission list
|
||
if (permission_list_memory != NULL)
|
||
{
|
||
grant_indication_info.granted_node_list = (PUserID) permission_list_memory;
|
||
|
||
permission_list = permission_grant_indication->permission_list;
|
||
for (i = 0; i < grant_indication_info.number_granted; i++)
|
||
{
|
||
grant_indication_info.granted_node_list[i] = permission_list->value;
|
||
permission_list = permission_list->next;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser: ProcessPermissionGrantIndication: Memory Manager Alloc Failure"));
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
grant_indication_info.granted_node_list = NULL;
|
||
}
|
||
|
||
// Now extract the waiting list information if any exist
|
||
if ((error_value == GCC_NO_ERROR) &&
|
||
(permission_grant_indication->bit_mask & WAITING_LIST_PRESENT))
|
||
{
|
||
// First count the number of entries in the waiting list
|
||
grant_indication_info.number_waiting = 0;
|
||
waiting_list = permission_grant_indication->waiting_list;
|
||
while (waiting_list != NULL)
|
||
{
|
||
waiting_list = waiting_list->next;
|
||
grant_indication_info.number_waiting++;
|
||
}
|
||
|
||
TRACE_OUT(("MCSUser: ProcessPermissionGrantIndication: number_waiting=%d", (UINT) grant_indication_info.number_waiting));
|
||
|
||
// allocating space to hold waiting list.
|
||
DBG_SAVE_FILE_LINE
|
||
waiting_list_memory = new BYTE[sizeof(UserID) * grant_indication_info.number_waiting];
|
||
|
||
// Now fill in the permission list
|
||
if (waiting_list_memory != NULL)
|
||
{
|
||
grant_indication_info.waiting_node_list = (PUserID) waiting_list_memory;
|
||
|
||
waiting_list = permission_grant_indication->waiting_list;
|
||
for (i = 0; i < grant_indication_info.number_waiting; i++)
|
||
{
|
||
grant_indication_info.waiting_node_list[i] = waiting_list->value;
|
||
waiting_list = waiting_list->next;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
grant_indication_info.number_waiting = 0;
|
||
grant_indication_info.waiting_node_list = NULL;
|
||
}
|
||
|
||
/*
|
||
** If there were no memory errors, send the indication back to the
|
||
** owner object.
|
||
*/
|
||
if (error_value == GCC_NO_ERROR)
|
||
{
|
||
m_pConf->ProcessConductorPermitGrantInd(&grant_indication_info, sender_id);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser::ProcessPermissionGrantIndication: Alloc Failed"));
|
||
if (GCC_ALLOCATION_FAILURE == error_value)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
|
||
// Free up any memory used in this call
|
||
delete permission_list_memory;
|
||
delete waiting_list_memory;
|
||
}
|
||
|
||
/*
|
||
* MCSUser::GetUserIDFromConnection()
|
||
*
|
||
* Public Function Description:
|
||
* This function returns the Node ID associated with the specified
|
||
* connection handle. It returns zero if the connection handle is
|
||
* not a child connection of this node.
|
||
*/
|
||
UserID MCSUser::GetUserIDFromConnection(ConnectionHandle connection_handle)
|
||
{
|
||
ConnectionHandle hConn;
|
||
UserID uid;
|
||
|
||
m_ChildUidConnHdlList2.Reset();
|
||
while (NULL != (hConn = m_ChildUidConnHdlList2.Iterate(&uid)))
|
||
{
|
||
if (hConn == connection_handle)
|
||
{
|
||
return uid;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
/*
|
||
* MCSUser::UserDisconnectIndication()
|
||
*
|
||
* Public Function Description:
|
||
* This function informs the user object when a Node disconnects from
|
||
* the conference. This gives the user object a chance to clean up
|
||
* its internal information base.
|
||
*/
|
||
void MCSUser::UserDisconnectIndication(UserID disconnected_user)
|
||
{
|
||
PAlarm lpAlarm;
|
||
|
||
/*
|
||
** If this node has a pending ejection we will go ahead and remove the
|
||
** ejected node from the list. Once all child nodes have disconnected
|
||
** we will inform the owner object of the ejection.
|
||
*/
|
||
if (m_fEjectionPending)
|
||
{
|
||
// Delete the Alarm if it exists
|
||
if (NULL != (lpAlarm = m_EjectedNodeAlarmList2.Remove(disconnected_user)))
|
||
{
|
||
delete lpAlarm;
|
||
/*
|
||
** Here we must check to see if there are anymore active alarms
|
||
** in the list. If so we wait until that node disconnects before
|
||
** informing the owner object that this node has been ejected.
|
||
** Otherwise, we complete the ejection process.
|
||
*/
|
||
if (m_EjectedNodeAlarmList2.IsEmpty())
|
||
{
|
||
m_pConf->ProcessEjectUserIndication(m_eEjectReason);
|
||
}
|
||
}
|
||
}
|
||
// If we are the top provider, just clean the eject alarm list.
|
||
else if (TOP_PROVIDER_AND_CONVENER_NODE == m_pConf->GetConfNodeType() &&
|
||
NULL != (lpAlarm = m_EjectedNodeAlarmList2.Remove(disconnected_user)))
|
||
{
|
||
delete lpAlarm;
|
||
}
|
||
|
||
/*
|
||
** Here we remove the entry from the list of child connections if
|
||
** it is included in this list.
|
||
*/
|
||
m_ChildUidConnHdlList2.Remove(disconnected_user);
|
||
}
|
||
|
||
/*
|
||
* void ProcessApplicationInvokeIndication ()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Invoke
|
||
* indication PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* invoke_indication - (i) This is the PDU structure to process
|
||
* sender_id - (i) Node ID of node that sent this PDU.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::ProcessApplicationInvokeIndication(
|
||
PApplicationInvokeIndication invoke_indication,
|
||
UserID sender_id)
|
||
{
|
||
GCCError error_value = GCC_NO_ERROR;
|
||
BOOL process_pdu = FALSE;
|
||
CInvokeSpecifierListContainer *invoke_list;
|
||
PSetOfDestinationNodes set_of_destination_nodes;
|
||
|
||
if (invoke_indication->bit_mask & DESTINATION_NODES_PRESENT)
|
||
{
|
||
set_of_destination_nodes = invoke_indication->destination_nodes;
|
||
while (set_of_destination_nodes != NULL)
|
||
{
|
||
if (set_of_destination_nodes->value == m_nidMyself)
|
||
{
|
||
process_pdu = TRUE;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
set_of_destination_nodes = set_of_destination_nodes->next;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
process_pdu = TRUE;
|
||
}
|
||
|
||
if (process_pdu)
|
||
{
|
||
TRACE_OUT(("MCSUser: ProcessApplicationInvokeIndication: Process PDU"));
|
||
DBG_SAVE_FILE_LINE
|
||
invoke_list = new CInvokeSpecifierListContainer(
|
||
invoke_indication->application_protocol_entity_list,
|
||
&error_value);
|
||
if ((invoke_list != NULL) && (error_value == GCC_NO_ERROR))
|
||
{
|
||
m_pConf->ProcessAppInvokeIndication(invoke_list, sender_id);
|
||
invoke_list->Release();
|
||
}
|
||
else if (invoke_list == NULL)
|
||
{
|
||
error_value = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
invoke_list->Release();
|
||
}
|
||
|
||
if (error_value == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ERROR_OUT(("MCSUser::ProcessApplicationInvokeIndication: Allocation Failure"));
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
WARNING_OUT(("MCSUser:ProcessApplicationInvokeIndication: Don't Process PDU"));
|
||
}
|
||
}
|
||
|
||
/*
|
||
* GCCError ProcessTextMessageIndication ()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Text
|
||
* message indication PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* text_message_indication - (i) This is the PDU structure to process
|
||
* sender_id - (i) Node ID of node that sent this PDU.
|
||
*
|
||
* Return Value
|
||
* GCC_NO_ERROR - No error occured.
|
||
* GCC_ALLOCATION_FAILURE - A resource error occured.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
#ifdef JASPER
|
||
GCCError MCSUser::ProcessTextMessageIndication(
|
||
PTextMessageIndication text_message_indication,
|
||
UserID sender_id)
|
||
{
|
||
LPWSTR gcc_unicode_string;
|
||
GCCError rc;
|
||
|
||
if (NULL != (gcc_unicode_string = ::My_strdupW2(
|
||
text_message_indication->message.length,
|
||
text_message_indication->message.value)))
|
||
{
|
||
rc = g_pControlSap->TextMessageIndication(
|
||
m_pConf->GetConfID(),
|
||
gcc_unicode_string,
|
||
sender_id);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
#endif // JASPER
|
||
|
||
/*
|
||
* void ProcessRegistryMonitorIndication ()
|
||
*
|
||
* Private Function Description:
|
||
* This routine is responsible for processing an incoming Registry
|
||
* monitor indication PDU.
|
||
*
|
||
* Formal Parameters:
|
||
* monitor_indication - (i) This is the PDU structure to process
|
||
* sender_id - (i) Node ID of node that sent this PDU.
|
||
*
|
||
* Return Value
|
||
* None.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
void MCSUser::
|
||
ProcessRegistryMonitorIndicationPDU
|
||
(
|
||
PRegistryMonitorEntryIndication monitor_indication,
|
||
UserID sender_id
|
||
)
|
||
{
|
||
if (sender_id == m_nidTopProvider)
|
||
{
|
||
CRegistry *pAppReg = m_pConf->GetRegistry();
|
||
if (NULL != pAppReg)
|
||
{
|
||
GCCError rc;
|
||
UserRegistryMonitorInfo urmi;
|
||
|
||
::ZeroMemory(&urmi, sizeof(urmi));
|
||
// urmi.registry_key = NULL;
|
||
// urmi.registry_item = NULL;
|
||
|
||
DBG_SAVE_FILE_LINE
|
||
urmi.registry_key = new CRegKeyContainer(&monitor_indication->key, &rc);
|
||
if ((urmi.registry_key != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
DBG_SAVE_FILE_LINE
|
||
urmi.registry_item = new CRegItem(&monitor_indication->item, &rc);
|
||
if ((urmi.registry_item != NULL) && (rc == GCC_NO_ERROR))
|
||
{
|
||
// Set up the owner related variables
|
||
if (monitor_indication->owner.choice == OWNED_CHOSEN)
|
||
{
|
||
urmi.owner_node_id = monitor_indication->owner.u.owned.node_id;
|
||
urmi.owner_entity_id = monitor_indication->owner.u.owned.entity_id;
|
||
}
|
||
else
|
||
{
|
||
// urmi.owner_node_id = 0;
|
||
// urmi.owner_entity_id = 0;
|
||
}
|
||
|
||
// Set up the modification rights
|
||
if (monitor_indication->bit_mask & RESPONSE_MODIFY_RIGHTS_PRESENT)
|
||
{
|
||
urmi.modification_rights = (GCCModificationRights)monitor_indication->entry_modify_rights;
|
||
}
|
||
else
|
||
{
|
||
urmi.modification_rights = GCC_NO_MODIFICATION_RIGHTS_SPECIFIED;
|
||
}
|
||
|
||
pAppReg->ProcessMonitorIndicationPDU(
|
||
urmi.registry_key,
|
||
urmi.registry_item,
|
||
urmi.modification_rights,
|
||
urmi.owner_node_id,
|
||
urmi.owner_entity_id);
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
rc = GCC_ALLOCATION_FAILURE;
|
||
}
|
||
|
||
if (NULL != urmi.registry_key)
|
||
{
|
||
urmi.registry_key->Release();
|
||
}
|
||
if (NULL != urmi.registry_item)
|
||
{
|
||
urmi.registry_item->Release();
|
||
}
|
||
|
||
// Handle any resource errors
|
||
if (rc == GCC_ALLOCATION_FAILURE)
|
||
{
|
||
ResourceFailureHandler();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
WARNING_OUT(("MCSUser:ProcessRegistryMonitorIndication: invalid app registry"));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
WARNING_OUT(("MCSUser:ProcessRegistryMonitorIndication:"
|
||
"Monitor Indication received from NON Top Provider"));
|
||
}
|
||
}
|
||
|
||
/*
|
||
* UINT ProcessDetachUserIndication()
|
||
*
|
||
* Private Function Description:
|
||
* This function is called when the user object gets detach user
|
||
* indications from nodes in it's subtree or it's parent node.
|
||
* Depending upon the reason of the indication it sends to the
|
||
* conference object the appropriate owner callback.
|
||
* If the reason contained in the indication is UserInitiated or
|
||
* provider initiated a DETACH USER INDICATION is sent to the con-
|
||
* ference. The MCS reason is converted to GCC reason. If MCS
|
||
* reason in indication is neither user initiated nor provider initiated
|
||
* then the above owner callback carries a GCC reason ERROR_TERMINATION
|
||
* else it carries a GCC reason USER_INITIATED.
|
||
* If the detach user indication reveals the user id of the sendar as
|
||
* the parent user id of this node a CONFERENCE_TERMINATE_INDICATION
|
||
* is sent to the conference object.
|
||
*
|
||
* Formal Parameters:
|
||
* mcs_reason - (i) MCS reason for being detached.
|
||
* sender_id - (i) User ID of user being detached.
|
||
*
|
||
* Return Value
|
||
* MCS_NO_ERROR is always returned fro this routine.
|
||
*
|
||
* Side Effects
|
||
* None.
|
||
*
|
||
* Caveats
|
||
* None.
|
||
*/
|
||
UINT MCSUser::ProcessDetachUserIndication( Reason mcs_reason,
|
||
UserID detached_user)
|
||
{
|
||
GCCReason gcc_reason;
|
||
|
||
if (detached_user == m_nidParent)
|
||
{
|
||
WARNING_OUT(("MCSUser: Fatal Error: Parent User Detached"));
|
||
m_pConf->ProcessTerminateIndication(GCC_REASON_PARENT_DISCONNECTED);
|
||
}
|
||
else
|
||
{
|
||
TRACE_OUT(("MCSUser: User Detached: uid=0x%04x", (UINT) detached_user));
|
||
|
||
/*
|
||
** First, we check to see if the detching node was ejected.
|
||
** If not, translate the mcs reason to a gcc reason.
|
||
*/
|
||
if (m_EjectedNodeList.Find(detached_user))
|
||
{
|
||
gcc_reason = GCC_REASON_NODE_EJECTED;
|
||
|
||
// Remove this entry from the ejected node list.
|
||
m_EjectedNodeList.Remove(detached_user);
|
||
}
|
||
else if (m_EjectedNodeAlarmList2.Find(detached_user))
|
||
{
|
||
// Here we wait for the disconnect before removing the entry.
|
||
gcc_reason = GCC_REASON_NODE_EJECTED;
|
||
}
|
||
else if ((mcs_reason == REASON_USER_REQUESTED) ||
|
||
(mcs_reason == REASON_PROVIDER_INITIATED))
|
||
{
|
||
gcc_reason = GCC_REASON_USER_INITIATED;
|
||
}
|
||
else
|
||
{
|
||
gcc_reason = GCC_REASON_ERROR_TERMINATION;
|
||
}
|
||
|
||
m_pConf->ProcessDetachUserIndication(detached_user, gcc_reason);
|
||
}
|
||
return (MCS_NO_ERROR);
|
||
}
|
||
|
||
|
||
void MCSUser::
|
||
ProcessTokenGrabConfirm
|
||
(
|
||
TokenID tidConductor,
|
||
Result result
|
||
)
|
||
{
|
||
if (tidConductor == CONDUCTOR_TOKEN_ID)
|
||
{
|
||
m_pConf->ProcessConductorGrabConfirm(::TranslateMCSResultToGCCResult(result));
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Grab Confirm"));
|
||
}
|
||
}
|
||
|
||
|
||
void MCSUser::
|
||
ProcessTokenGiveIndication
|
||
(
|
||
TokenID tidConductor,
|
||
UserID uidRecipient
|
||
)
|
||
{
|
||
if (tidConductor == CONDUCTOR_TOKEN_ID)
|
||
{
|
||
m_pConf->ProcessConductorGiveIndication(uidRecipient);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Please Ind"));
|
||
}
|
||
}
|
||
|
||
|
||
void MCSUser::
|
||
ProcessTokenGiveConfirm
|
||
(
|
||
TokenID tidConductor,
|
||
Result result
|
||
)
|
||
{
|
||
if (tidConductor == CONDUCTOR_TOKEN_ID)
|
||
{
|
||
m_pConf->ProcessConductorGiveConfirm(::TranslateMCSResultToGCCResult(result));
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Grab Confirm"));
|
||
}
|
||
}
|
||
|
||
|
||
#ifdef JASPER
|
||
void MCSUser::
|
||
ProcessTokenPleaseIndication
|
||
(
|
||
TokenID tidConductor,
|
||
UserID uidRequester
|
||
)
|
||
{
|
||
if (tidConductor == CONDUCTOR_TOKEN_ID)
|
||
{
|
||
if (m_pConf->IsConfConductible())
|
||
{
|
||
// Inform the control SAP.
|
||
g_pControlSap->ConductorPleaseIndication(
|
||
m_pConf->GetConfID(),
|
||
uidRequester);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Please Ind"));
|
||
}
|
||
}
|
||
#endif // JASPER
|
||
|
||
|
||
#ifdef JASPER
|
||
void MCSUser::
|
||
ProcessTokenReleaseConfirm
|
||
(
|
||
TokenID tidConductor,
|
||
Result result
|
||
)
|
||
{
|
||
if (tidConductor == CONDUCTOR_TOKEN_ID)
|
||
{
|
||
g_pControlSap->ConductorReleaseConfirm(::TranslateMCSResultToGCCResult(result),
|
||
m_pConf->GetConfID());
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Release Cfrm"));
|
||
}
|
||
}
|
||
#endif // JASPER
|
||
|
||
|
||
void MCSUser::
|
||
ProcessTokenTestConfirm
|
||
(
|
||
TokenID tidConductor,
|
||
TokenStatus eStatus
|
||
)
|
||
{
|
||
if (tidConductor == CONDUCTOR_TOKEN_ID)
|
||
{
|
||
m_pConf->ProcessConductorTestConfirm((eStatus == TOKEN_NOT_IN_USE) ?
|
||
GCC_RESULT_NOT_IN_CONDUCTED_MODE :
|
||
GCC_RESULT_SUCCESSFUL);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Release Cfrm"));
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void MCSUser::ResourceFailureHandler(void)
|
||
{
|
||
ERROR_OUT(("MCSUser::ResourceFailureHandler: terminating the conference"));
|
||
m_pConf->InitiateTermination(GCC_REASON_ERROR_LOW_RESOURCES, 0);
|
||
}
|
||
|
||
|
||
|