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.
318 lines
8.6 KiB
318 lines
8.6 KiB
#include "precomp.h"
|
|
#include "fsdiag.h"
|
|
DEBUG_FILEZONE(ZONE_T120_MCSNC);
|
|
/*
|
|
* userchnl.cpp
|
|
*
|
|
* Copyright (c) 1993 - 1995 by DataBeam Corporation, Lexington, KY
|
|
*
|
|
* Abstract:
|
|
* This is the implementation file for the UserChannel class. It contains
|
|
* the code that distinguishes this class from that of its parent, Channel.
|
|
*
|
|
* The main difference between this class and that of its parent is how
|
|
* the join and data requests are handled. There is also a new instance
|
|
* variable that keeps track of what attachment leads to the user being
|
|
* represented by this class. Merge requests are also generated as is
|
|
* appropriate for a user channel
|
|
*
|
|
* The data primitives are overridden, allowing this object to decide
|
|
* not to send data upward, if it is known that the user lies in the
|
|
* sub-tree of this provider.
|
|
*
|
|
* Private Instance Variables:
|
|
* m_pUserAttachment
|
|
* This is a pointer to the attachment that leads to the user being
|
|
* represented by this object.
|
|
*
|
|
* Private Member Functions:
|
|
* None.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*
|
|
* Author:
|
|
* James P. Galvin, Jr.
|
|
*/
|
|
|
|
/*
|
|
* External Interfaces
|
|
*/
|
|
|
|
#include "userchnl.h"
|
|
|
|
|
|
/*
|
|
* UserChannel ()
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* This is the primary constructor for UserChannel objects. It creates
|
|
* an object with all instance variable initialized, but with no
|
|
* attachments (i.e. the user is not joined to the channel automatically).
|
|
*
|
|
* Note that most instance variable initialization is done by invoking the
|
|
* equivalent constructor in the base class.
|
|
*
|
|
* Upon successful completion, an attach user confirm is automtically
|
|
* issued to the new user.
|
|
*/
|
|
UserChannel::UserChannel (
|
|
ChannelID channel_id,
|
|
CAttachment *user_attachment,
|
|
PDomain local_provider,
|
|
PConnection top_provider,
|
|
CChannelList2 *channel_list,
|
|
CAttachmentList *attachment_list)
|
|
:
|
|
Channel(channel_id, local_provider, top_provider, channel_list, attachment_list),
|
|
m_pUserAttachment(user_attachment)
|
|
{
|
|
/*
|
|
* Issue an attach user confirm to the new user.
|
|
*/
|
|
m_pUserAttachment->AttachUserConfirm(RESULT_SUCCESSFUL, channel_id);
|
|
}
|
|
|
|
/*
|
|
* UserChannel ()
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* This is a secondary constructor that is only used during merge
|
|
* operations. The intent of this constructor is to create an equivalent
|
|
* object without issuing any of the confirms.
|
|
*
|
|
* Note that the additional constructor allows for the creator to specify
|
|
* that the user is to be already joined to the channel upon creation.
|
|
* The value of user_attachment and attachment should either be the same
|
|
* or attachment should be NULL.
|
|
*/
|
|
UserChannel::UserChannel (
|
|
ChannelID channel_id,
|
|
CAttachment *user_attachment,
|
|
PDomain local_provider,
|
|
PConnection top_provider,
|
|
CChannelList2 *channel_list,
|
|
CAttachmentList *attachment_list,
|
|
PConnection pConn)
|
|
:
|
|
Channel(channel_id, local_provider, top_provider, channel_list, attachment_list, pConn),
|
|
m_pUserAttachment(user_attachment)
|
|
{
|
|
}
|
|
|
|
/*
|
|
* ~UserChannel ()
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* This destructor does nothing more than clear the joined attachment list.
|
|
* This is important because it prevents the base class destructor from
|
|
* trying to issue channel leave indications to the user if the user is
|
|
* locally attached.
|
|
*/
|
|
UserChannel::~UserChannel ()
|
|
{
|
|
}
|
|
|
|
/*
|
|
* Channel_Type GetChannelType ()
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* Objects of this class are always user channels, so simply return
|
|
* USER_CHANNEL.
|
|
*/
|
|
Channel_Type UserChannel::GetChannelType ()
|
|
{
|
|
return (USER_CHANNEL);
|
|
}
|
|
|
|
/*
|
|
* BOOL IsValid ()
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* User ID channels are always valid, so return TRUE.
|
|
*/
|
|
BOOL UserChannel::IsValid ()
|
|
{
|
|
return (TRUE);
|
|
}
|
|
|
|
/*
|
|
* CAttachment *GetAttachment ()
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* Return the pointer to the attachment leading to the user.
|
|
*/
|
|
CAttachment *UserChannel::GetAttachment(void)
|
|
{
|
|
return m_pUserAttachment;
|
|
}
|
|
|
|
/*
|
|
* Void IssueMergeRequest ()
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* This member function is used to cause the Channel object to issue a
|
|
* merge request to the pending top provier.
|
|
*/
|
|
Void UserChannel::IssueMergeRequest ()
|
|
{
|
|
ChannelAttributes channel_attributes;
|
|
CChannelAttributesList merge_channel_list;
|
|
CChannelIDList purge_channel_list;
|
|
|
|
if (m_pConnToTopProvider != NULL)
|
|
{
|
|
/*
|
|
* Fill in the fields of the channel attributes structure so that it
|
|
* accurately describes this channel. Then put the structure into the
|
|
* merge channel list.
|
|
*/
|
|
channel_attributes.channel_type = USER_CHANNEL;
|
|
if (m_JoinedAttachmentList.IsEmpty() == FALSE)
|
|
channel_attributes.u.user_channel_attributes.joined = TRUE;
|
|
else
|
|
channel_attributes.u.user_channel_attributes.joined = FALSE;
|
|
channel_attributes.u.user_channel_attributes.user_id = Channel_ID;
|
|
|
|
merge_channel_list.Append(&channel_attributes);
|
|
|
|
/*
|
|
* Send the merge request to the indicated provider.
|
|
*/
|
|
m_pConnToTopProvider->MergeChannelsRequest(&merge_channel_list, &purge_channel_list);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Void ChannelJoinRequest ()
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* This function overrides the base class implementation. The main
|
|
* difference is that this implementation only allows a user to join
|
|
* their own channel. No one else is allowed to join it.
|
|
*
|
|
* Also, since it is possible to have a user channel object with no one
|
|
* joined to it, this request will be forwarded upward to the Top
|
|
* Provider from here (unless this is the Top Provider).
|
|
*/
|
|
Void UserChannel::ChannelJoinRequest (
|
|
CAttachment *pOrigAtt,
|
|
UserID uidInitiator,
|
|
ChannelID channel_id)
|
|
{
|
|
/*
|
|
* See if the requesting user ID is the same as that of the user this
|
|
* UserChannel object represents.
|
|
*/
|
|
if (uidInitiator == Channel_ID)
|
|
{
|
|
/*
|
|
* See if the user is already joined to the channel.
|
|
*/
|
|
if (m_JoinedAttachmentList.Find(pOrigAtt) == FALSE)
|
|
{
|
|
/*
|
|
* The user is not joined to the channel. If this is the Top
|
|
* Provider, then the request can be processed here.
|
|
*/
|
|
if (IsTopProvider())
|
|
{
|
|
/*
|
|
* Add the user to its own channel, and issue a successful
|
|
* channel join confirm to the user.
|
|
*/
|
|
TRACE_OUT (("UserChannel::ChannelJoinRequest: "
|
|
"user joining own user ID channel = %04X",
|
|
uidInitiator));
|
|
|
|
m_JoinedAttachmentList.Append(pOrigAtt);
|
|
|
|
pOrigAtt->ChannelJoinConfirm(RESULT_SUCCESSFUL, uidInitiator, channel_id, Channel_ID);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* This is not the Top Provider. Forward the join request
|
|
* upward to the Top Provider.
|
|
*/
|
|
TRACE_OUT (("UserChannel::ChannelJoinRequest: "
|
|
"forwarding join request to Top Provider"));
|
|
|
|
m_pConnToTopProvider->ChannelJoinRequest(uidInitiator, Channel_ID);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* The user is already joined to their channel. Go ahead and
|
|
* issue a successful channel join confirm.
|
|
*/
|
|
WARNING_OUT (("UserChannel::ChannelJoinRequest: "
|
|
"user already joined to own user channel"));
|
|
|
|
pOrigAtt->ChannelJoinConfirm(RESULT_SUCCESSFUL, uidInitiator, channel_id, Channel_ID);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* Someone is trying to join someone elses channel. This is not
|
|
* valid. Reject the request without further processing.
|
|
*/
|
|
WARNING_OUT (("UserChannel::ChannelJoinRequest: "
|
|
"rejecting attempt to join someone elses user channel"));
|
|
|
|
pOrigAtt->ChannelJoinConfirm(RESULT_OTHER_USER_ID, uidInitiator, channel_id, 0);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Void SendDataRequest ()
|
|
*
|
|
* Public
|
|
*
|
|
* Functional Description:
|
|
* This function is used to send data through the channel. Note that data
|
|
* is NEVER sent upward, since the user (who is the only one who can be
|
|
* joined to this channel) is in the sub-tree of this provider. This helps
|
|
* to optimize network traffic.
|
|
*/
|
|
Void UserChannel::SendDataRequest (
|
|
CAttachment *pOrigAtt,
|
|
UINT type,
|
|
PDataPacket data_packet)
|
|
{
|
|
CAttachment *pAtt;
|
|
|
|
ASSERT (Channel_ID == data_packet->GetChannelID());
|
|
|
|
/*
|
|
* Iterate through the attachment list, sending the data to all
|
|
* the attachments (except for one from whence the data came).
|
|
*/
|
|
m_JoinedAttachmentList.Reset();
|
|
while (NULL != (pAtt = m_JoinedAttachmentList.Iterate()))
|
|
{
|
|
if (pAtt != pOrigAtt)
|
|
{
|
|
pAtt->SendDataIndication(type, data_packet);
|
|
}
|
|
}
|
|
}
|
|
|