mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6624 lines
176 KiB
6624 lines
176 KiB
#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);
|
|
}
|
|
|
|
|
|
|