617 lines
23 KiB
C
617 lines
23 KiB
C
|
/*
|
|||
|
* control.h
|
|||
|
*
|
|||
|
* Copyright (c) 1993 - 1996 by DataBeam Corporation, Lexington, KY
|
|||
|
*
|
|||
|
* Abstract:
|
|||
|
* This is the interface file for the MCS Controller class. There will
|
|||
|
* be exactly one instance of this class at run-time, whose job it is
|
|||
|
* to coordinate the creation, deletion, and linking of other objects
|
|||
|
* in the system.
|
|||
|
*
|
|||
|
* The controller is primarily responsible for managing five "layers"
|
|||
|
* of objects in the system at run-time. These layers can be depicted
|
|||
|
* as follows:
|
|||
|
*
|
|||
|
* +---+ +------------------------+
|
|||
|
* | | <---> | Application Interfaces |
|
|||
|
* | | +------------------------+
|
|||
|
* | | |
|
|||
|
* | C | +------------------------+
|
|||
|
* | o | <---> | User Attachments |
|
|||
|
* | n | +------------------------+
|
|||
|
* | t | |
|
|||
|
* | r | +------------------------+
|
|||
|
* | o | <---> | Domains |
|
|||
|
* | l | +------------------------+
|
|||
|
* | l | |
|
|||
|
* | e | +------------------------+
|
|||
|
* | r | <---> | MCS Connections |
|
|||
|
* | | +------------------------+
|
|||
|
* | | |
|
|||
|
* | | +------------------------+
|
|||
|
* | | <---> | Transport Interfaces |
|
|||
|
* +---+ +------------------------+
|
|||
|
*
|
|||
|
* The controller is the first object created in the MCS system. It is
|
|||
|
* responsible for creating all other objects during initialization. In
|
|||
|
* the constructor, the controller creates all necessary application
|
|||
|
* interface and transport interface objects. These are the objects
|
|||
|
* through which MCS communicates with the outside world. They are
|
|||
|
* static in that they live throughout the lifetime of MCS itself.
|
|||
|
*
|
|||
|
* During initialization, the node controller must register itself with
|
|||
|
* the controller so that the controller knows which application interface
|
|||
|
* object to use when issuing indications and confirms back to the node
|
|||
|
* controller. Note that even though it is possible to have more than
|
|||
|
* one way to communicate with applications, there is still only one node
|
|||
|
* controller.
|
|||
|
*
|
|||
|
* Four of the five layers of objects communicate with the controller
|
|||
|
* through the owner callback facility. This mechanism is used to send
|
|||
|
* requests to the controller.
|
|||
|
*
|
|||
|
* User attachments (instances of class User) are created when the
|
|||
|
* controller receives an AttachUserRequest from one of the application
|
|||
|
* interface objects (with a valid domain selector). A new user object
|
|||
|
* is created, who in turn registers with the correct application interface
|
|||
|
* object to insure proper data flow at run-time.
|
|||
|
*
|
|||
|
* Domains (instances of class Domain) are created when the controller
|
|||
|
* receives a CreateDomain from one of the application interface objects.
|
|||
|
* Since both user attachments and MCS connections identify specific
|
|||
|
* domains, this must occur before any attaching or connecting can be
|
|||
|
* done.
|
|||
|
*
|
|||
|
* MCS connections (instances of class Connection) are created in two
|
|||
|
* possible ways. First, when a ConnectProviderRequest is received from
|
|||
|
* one of the application interface objects (with a valid local domain
|
|||
|
* selector and a valid transport address). Second, when a
|
|||
|
* ConnectProviderResponse is received from one of the application
|
|||
|
* interface objects in response to a previous connect provider indication.
|
|||
|
* Either way, a Connection object is created to represent the new MCS
|
|||
|
* connection.
|
|||
|
*
|
|||
|
* User attachments are deleted in one of two ways. First, when a
|
|||
|
* DetachUserRequest is received from an application interface with a
|
|||
|
* valid user handle. Second, if the user attachment is told by the
|
|||
|
* domain that the attachment is severed. In the latter case, the user
|
|||
|
* object asks the controller to delete it using the owner callback
|
|||
|
* facility.
|
|||
|
*
|
|||
|
* Domains are deleted when a DeleteDomain is received from an application
|
|||
|
* interface.
|
|||
|
*
|
|||
|
* Connections are deleted in one of three ways. First, when a
|
|||
|
* DisconnectProviderRequest is received from an application interface
|
|||
|
* with a valid connection handle. Second, if the transport interface
|
|||
|
* detects a loss of the connection at a lower layer. Third, if the
|
|||
|
* connection is told by the domain that the connection is to be severed.
|
|||
|
* In the latter two cases, the connection object asks the controller to
|
|||
|
* delete it using the owner callback facility.
|
|||
|
*
|
|||
|
* The primary role of the controller is to create and delete all of these
|
|||
|
* objects, and to "plug" them together as needed.
|
|||
|
*
|
|||
|
* During initialization, the controller also creates a single instance
|
|||
|
* of a memory manager. This objects is then passed on to all other
|
|||
|
* objects that require its services (in their constructors). A possible
|
|||
|
* way to improve upon this scheme would be to create a memory manager
|
|||
|
* for each domain, so that traffic in one domain does not influence
|
|||
|
* traffic in another.
|
|||
|
*
|
|||
|
* Portable:
|
|||
|
* Not completely. During initialization, the constructor "knows"
|
|||
|
* how to create application interface and transport interface objects
|
|||
|
* that are specific to the environment. In the case of the transport
|
|||
|
* interfaces, it actually reads a windows ".INI" file. It can also
|
|||
|
* optionally allocate a windows timer in order have a "heartbeat". Other
|
|||
|
* than initialization, everything else is portable.
|
|||
|
*
|
|||
|
* Caveats:
|
|||
|
* There can be only one instance of this class in an MCS provider.
|
|||
|
*
|
|||
|
* Author:
|
|||
|
* James P. Galvin, Jr.
|
|||
|
*/
|
|||
|
#ifndef _CONTROLLER_
|
|||
|
#define _CONTROLLER_
|
|||
|
|
|||
|
/*
|
|||
|
* Include files.
|
|||
|
*/
|
|||
|
#include "omcscode.h"
|
|||
|
|
|||
|
/*
|
|||
|
* This structure is used to hold information about an incoming connection,
|
|||
|
* while MCS waits for a connect provider response from the node controller.
|
|||
|
*/
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
TransportConnection transport_connection;
|
|||
|
BOOL upward_connection;
|
|||
|
DomainParameters domain_parameters;
|
|||
|
DomainParameters minimum_domain_parameters;
|
|||
|
DomainParameters maximum_domain_parameters;
|
|||
|
} ConnectionPending;
|
|||
|
typedef ConnectionPending * PConnectionPending;
|
|||
|
|
|||
|
/*
|
|||
|
* This is the set of container definitions defined using templates. All
|
|||
|
* containers are based on classes in the Rogue Wave Tools.h++ class
|
|||
|
* library.
|
|||
|
*
|
|||
|
* The controller keeps a list of objects at each of the five levels, as
|
|||
|
* follows:
|
|||
|
*
|
|||
|
* DomainList
|
|||
|
* This is a dictionary of currently existing domain objects, which is
|
|||
|
* keyed by DomainSelector.
|
|||
|
* CConnectionList2
|
|||
|
* This is a dictionary of currently existing connection objects, which is
|
|||
|
* keyed by connection handle.
|
|||
|
* TransportList
|
|||
|
* This is a dictionary of currently existing transport interface objects,
|
|||
|
* which is keyed by transport identifier. Note that the transport
|
|||
|
* identifier is just a character string.
|
|||
|
* ConnectionPendingList
|
|||
|
* This is a dictionary of pending connections. The key is the connection
|
|||
|
* handle, and the value is a pointer to a connection pending structure
|
|||
|
* that "remembers" details about a pending connection that are not
|
|||
|
* going to be passed back in the connect provider response.
|
|||
|
* ConnectionPollList
|
|||
|
* This is a singly-linked list that is used to hold all connection
|
|||
|
* objects. This list is used to iterate through the list, granting a time
|
|||
|
* slice to each object during the heartbeat.
|
|||
|
*/
|
|||
|
class CConnPendingList2 : public CList2
|
|||
|
{
|
|||
|
DEFINE_CLIST2_(CConnPendingList2, PConnectionPending, ConnectionHandle)
|
|||
|
};
|
|||
|
|
|||
|
class CConnPollList : public CList
|
|||
|
{
|
|||
|
DEFINE_CLIST(CConnPollList, PConnection)
|
|||
|
};
|
|||
|
|
|||
|
/*
|
|||
|
* The controller makes extensive use of the owner callback mechanism to
|
|||
|
* receive requests from the objects that it owns. In order for the
|
|||
|
* requests to be differentiated here in the controller, each object must
|
|||
|
* issue its message using a different message offset. The required message
|
|||
|
* offset is given to each object as it is created by the controller. The
|
|||
|
* message offsets for the five layers of objects are as follows.
|
|||
|
*
|
|||
|
* This allows the controller to easily determine what type of object a
|
|||
|
* given owner callback message is from (see the implementation of the
|
|||
|
* OwnerCallback member function for details).
|
|||
|
*/
|
|||
|
#define APPLICATION_MESSAGE_BASE 0
|
|||
|
#define USER_MESSAGE_BASE 100
|
|||
|
#define DOMAIN_MESSAGE_BASE 200
|
|||
|
#define CONNECTION_MESSAGE_BASE 300
|
|||
|
#ifndef TRANSPORT_MESSAGE_BASE
|
|||
|
#define TRANSPORT_MESSAGE_BASE 400
|
|||
|
#endif // !TRANSPORT_MESSAGE_BASE
|
|||
|
|
|||
|
/*
|
|||
|
** The following are timeout times that are used to set and test the
|
|||
|
** Controller_Wait_Timeout instance variable of a Controller object.
|
|||
|
** When the controller is signalled thru an event to process and send
|
|||
|
** msgs to an application, GCC, etc..., tries to process it. Sometimes
|
|||
|
** the event can't be processed immediately. In these cases, we make
|
|||
|
** the controller timeout in the WaitForMultipleObjects finite, and set
|
|||
|
** the Controller_Event_Mask to store which event we want to re-try
|
|||
|
** later. When the event is processed, the mask is reset.
|
|||
|
*/
|
|||
|
#define CONTROLLER_THREAD_TIMEOUT 200
|
|||
|
#define TRANSPORT_RECEIVE_TIMEOUT 300
|
|||
|
#define TRANSPORT_TRANSMIT_TIMEOUT 10000
|
|||
|
|
|||
|
/*
|
|||
|
** The following are the indices in the arrays of masks and timeouts.
|
|||
|
*/
|
|||
|
#define TRANSPORT_RECEIVE_INDEX 0
|
|||
|
#define TRANSPORT_TRANSMIT_INDEX 1
|
|||
|
#define GCC_FLUSH_OUTGOING_PDU_INDEX 3
|
|||
|
|
|||
|
/*
|
|||
|
** The following values are the masks used for checking against
|
|||
|
** the Controller_Event_Mask in the PollMCSDevices() member of the
|
|||
|
** MCS Controller.
|
|||
|
*/
|
|||
|
#define TRANSPORT_RECEIVE_MASK (0x1 << TRANSPORT_RECEIVE_INDEX)
|
|||
|
#define TRANSPORT_TRANSMIT_MASK (0x1 << TRANSPORT_TRANSMIT_INDEX)
|
|||
|
#define GCC_FLUSH_OUTGOING_PDU_MASK (0x1 << GCC_FLUSH_OUTGOING_PDU_INDEX)
|
|||
|
#define TRANSPORT_MASK (TRANSPORT_RECEIVE_MASK | TRANSPORT_TRANSMIT_MASK)
|
|||
|
|
|||
|
/*
|
|||
|
* These are the owner callback functions that an application interface object
|
|||
|
* can send to its creator (which is typically the MCS controller). The
|
|||
|
* first one allows an application interface object to tell the controller that
|
|||
|
* it represents the interface to the node controller application. The rest
|
|||
|
* are primitives that would generally come from the node controller
|
|||
|
* application, but must be acted upon internally by the MCS controller.
|
|||
|
*
|
|||
|
* When an object instantiates an application interface object (or any other
|
|||
|
* object that uses owner callbacks), it is accepting the responsibility of
|
|||
|
* receiving and handling those callbacks. For that reason, any object that
|
|||
|
* issues owner callbacks will have those callbacks defined as part of the
|
|||
|
* interface file (since they really are part of a bi-directional interface).
|
|||
|
*
|
|||
|
* Each owner callback function, along with a description of how its parameters
|
|||
|
* are packed, is described in the following section.
|
|||
|
*/
|
|||
|
#define REGISTER_NODE_CONTROLLER 0
|
|||
|
#define RESET_DEVICE 1
|
|||
|
#define CREATE_DOMAIN 2
|
|||
|
#define DELETE_DOMAIN 3
|
|||
|
#define CONNECT_PROVIDER_REQUEST 4
|
|||
|
#define CONNECT_PROVIDER_RESPONSE 5
|
|||
|
#define DISCONNECT_PROVIDER_REQUEST 6
|
|||
|
#define APPLICATION_ATTACH_USER_REQUEST 7
|
|||
|
|
|||
|
/*
|
|||
|
* These are the structures used by some of the owner callback function listed
|
|||
|
* above (for the case that the parameters to a function cannot fit into two
|
|||
|
* 32-bit parameters).
|
|||
|
*/
|
|||
|
|
|||
|
#ifdef NM_RESET_DEVICE
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
PChar device_identifier;
|
|||
|
} ResetDeviceInfo;
|
|||
|
typedef ResetDeviceInfo * PResetDeviceInfo;
|
|||
|
#endif // #ifdef NM_RESET_DEVICE
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
TransportAddress local_address;
|
|||
|
PInt local_address_length;
|
|||
|
} LocalAddressInfo;
|
|||
|
typedef LocalAddressInfo * PLocalAddressInfo;
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
GCCConfID *calling_domain;
|
|||
|
GCCConfID *called_domain;
|
|||
|
PChar calling_address;
|
|||
|
PChar called_address;
|
|||
|
BOOL fSecure;
|
|||
|
BOOL upward_connection;
|
|||
|
PDomainParameters domain_parameters;
|
|||
|
PUChar user_data;
|
|||
|
ULong user_data_length;
|
|||
|
PConnectionHandle connection_handle;
|
|||
|
} ConnectRequestInfo;
|
|||
|
typedef ConnectRequestInfo * PConnectRequestInfo;
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
ConnectionHandle connection_handle;
|
|||
|
GCCConfID *domain_selector;
|
|||
|
PDomainParameters domain_parameters;
|
|||
|
Result result;
|
|||
|
PUChar user_data;
|
|||
|
ULong user_data_length;
|
|||
|
} ConnectResponseInfo;
|
|||
|
typedef ConnectResponseInfo * PConnectResponseInfo;
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
GCCConfID *domain_selector;
|
|||
|
PUser *ppuser;
|
|||
|
} AttachRequestInfo;
|
|||
|
typedef AttachRequestInfo * PAttachRequestInfo;
|
|||
|
|
|||
|
/*
|
|||
|
* These structures are used to hold information that would not fit into
|
|||
|
* the one parameter defined as part of an MCS call back function. In the case
|
|||
|
* where these structures are used for call backs, the address of the structure
|
|||
|
* is passed as the only parameter.
|
|||
|
*/
|
|||
|
// LONCHANC: we dropped calling and called domain selectors here.
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
ConnectionHandle connection_handle;
|
|||
|
BOOL upward_connection;
|
|||
|
DomainParameters domain_parameters;
|
|||
|
unsigned char * user_data;
|
|||
|
unsigned long user_data_length;
|
|||
|
BOOL fSecure;
|
|||
|
} ConnectProviderIndication;
|
|||
|
typedef ConnectProviderIndication * PConnectProviderIndication;
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
ConnectionHandle connection_handle;
|
|||
|
DomainParameters domain_parameters;
|
|||
|
Result result;
|
|||
|
unsigned char * user_data;
|
|||
|
unsigned long user_data_length;
|
|||
|
PBYTE pb_cred;
|
|||
|
DWORD cb_cred;
|
|||
|
} ConnectProviderConfirm;
|
|||
|
typedef ConnectProviderConfirm * PConnectProviderConfirm;
|
|||
|
|
|||
|
/*
|
|||
|
* This is the class definition for the Controller class. It is worth
|
|||
|
* noting that there are only three public member functions defined in the
|
|||
|
* controller (besides the constructor and the destructor). The Owner
|
|||
|
* callback function is used by all "owned" objects to make requests
|
|||
|
* of the controller (who created them). The poll routine, which is
|
|||
|
* called from the windows timer event handler. This is the heartbeat
|
|||
|
* of MCS at the current time.
|
|||
|
*/
|
|||
|
class Controller : public CRefCount
|
|||
|
{
|
|||
|
public:
|
|||
|
Controller (
|
|||
|
PMCSError mcs_error);
|
|||
|
~Controller ();
|
|||
|
|
|||
|
Void CreateTCPWindow ();
|
|||
|
Void DestroyTCPWindow ();
|
|||
|
Void EventLoop ();
|
|||
|
BOOL FindSocketNumber(ConnectionHandle connection_handle, SOCKET * socket_number);
|
|||
|
BOOL GetLocalAddress(
|
|||
|
ConnectionHandle connection_handle,
|
|||
|
TransportAddress local_address,
|
|||
|
PInt local_address_length);
|
|||
|
|
|||
|
// the old owner callback
|
|||
|
void HandleTransportDataIndication(PTransportData);
|
|||
|
void HandleTransportWaitUpdateIndication(BOOL fMoreData);
|
|||
|
#ifdef NM_RESET_DEVICE
|
|||
|
MCSError HandleAppletResetDevice(PResetDeviceInfo);
|
|||
|
#endif
|
|||
|
MCSError HandleAppletCreateDomain(GCCConfID *domain_selector);
|
|||
|
MCSError HandleAppletDeleteDomain(GCCConfID *domain_selector);
|
|||
|
MCSError HandleAppletConnectProviderRequest(PConnectRequestInfo);
|
|||
|
MCSError HandleAppletConnectProviderResponse(PConnectResponseInfo);
|
|||
|
MCSError HandleAppletDisconnectProviderRequest(ConnectionHandle);
|
|||
|
MCSError HandleAppletAttachUserRequest(PAttachRequestInfo);
|
|||
|
void HandleConnDeleteConnection(ConnectionHandle);
|
|||
|
void HandleConnConnectProviderConfirm(PConnectConfirmInfo, ConnectionHandle);
|
|||
|
void HandleTransportDisconnectIndication(TransportConnection, ULONG *pnNotify);
|
|||
|
#ifdef TSTATUS_INDICATION
|
|||
|
void HandleTransportStatusIndication(PTransportStatus);
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
#ifdef NM_RESET_DEVICE
|
|||
|
ULong ApplicationResetDevice (
|
|||
|
PChar device_identifier);
|
|||
|
#endif // NM_RESET_DEVICE
|
|||
|
MCSError ApplicationCreateDomain(GCCConfID *domain_selector);
|
|||
|
MCSError ApplicationDeleteDomain(GCCConfID *domain_selector);
|
|||
|
MCSError ApplicationConnectProviderRequest (
|
|||
|
PConnectRequestInfo pcriConnectRequestInfo);
|
|||
|
MCSError ApplicationConnectProviderResponse (
|
|||
|
ConnectionHandle connection_handle,
|
|||
|
GCCConfID *domain_selector,
|
|||
|
PDomainParameters domain_parameters,
|
|||
|
Result result,
|
|||
|
PUChar user_data,
|
|||
|
ULong user_data_length);
|
|||
|
MCSError ApplicationDisconnectProviderRequest (
|
|||
|
ConnectionHandle connection_handle);
|
|||
|
MCSError ApplicationAttachUserRequest (
|
|||
|
GCCConfID *domain_selector,
|
|||
|
PUser *ppUser);
|
|||
|
Void ConnectionDeleteConnection (
|
|||
|
ConnectionHandle connection_handle);
|
|||
|
void ConnectionConnectProviderConfirm (
|
|||
|
ConnectionHandle connection_handle,
|
|||
|
PDomainParameters domain_parameters,
|
|||
|
Result result,
|
|||
|
PMemory memory);
|
|||
|
Void TransportDisconnectIndication (
|
|||
|
TransportConnection transport_connection);
|
|||
|
Void TransportDataIndication (
|
|||
|
TransportConnection transport_connection,
|
|||
|
PUChar user_data,
|
|||
|
ULong user_data_length);
|
|||
|
#ifdef TSTATUS_INDICATION
|
|||
|
Void TransportStatusIndication (
|
|||
|
PTransportStatus transport_status);
|
|||
|
#endif
|
|||
|
Void ProcessConnectInitial (
|
|||
|
TransportConnection transport_connection,
|
|||
|
ConnectInitialPDU *pdu_structure);
|
|||
|
Void ProcessConnectAdditional (
|
|||
|
TransportConnection transport_connection,
|
|||
|
ConnectAdditionalPDU *pdu_structure);
|
|||
|
Void ConnectResponse (
|
|||
|
TransportConnection transport_connection,
|
|||
|
Result result,
|
|||
|
PDomainParameters domain_parameters,
|
|||
|
ConnectID connect_id,
|
|||
|
PUChar user_data,
|
|||
|
ULong user_data_length);
|
|||
|
Void ConnectResult (
|
|||
|
TransportConnection transport_connection,
|
|||
|
Result result);
|
|||
|
ConnectionHandle AllocateConnectionHandle ();
|
|||
|
Void PollMCSDevices ();
|
|||
|
Void UpdateWaitInfo (
|
|||
|
BOOL bMoreData,
|
|||
|
UINT index);
|
|||
|
|
|||
|
ConnectionHandle Connection_Handle_Counter;
|
|||
|
HANDLE Transport_Transmit_Event;
|
|||
|
HANDLE Connection_Deletion_Pending_Event;
|
|||
|
BOOL Controller_Closing;
|
|||
|
BOOL m_fControllerThreadActive;
|
|||
|
|
|||
|
CDomainList2 m_DomainList2;
|
|||
|
CConnectionList2 m_ConnectionList2;
|
|||
|
|
|||
|
CConnPollList m_ConnPollList;
|
|||
|
CConnPendingList2 m_ConnPendingList2;
|
|||
|
|
|||
|
CConnectionList2 m_ConnectionDeletionList2;
|
|||
|
BOOL Connection_Deletion_Pending;
|
|||
|
BOOL Domain_Traffic_Allowed;
|
|||
|
|
|||
|
DWORD Controller_Wait_Timeout;
|
|||
|
DWORD Controller_Event_Mask;
|
|||
|
|
|||
|
#ifndef NO_TCP_TIMER
|
|||
|
UINT_PTR Timer_ID;
|
|||
|
#endif /* NO_TCP_TIMER */
|
|||
|
|
|||
|
public:
|
|||
|
HANDLE Synchronization_Event;
|
|||
|
};
|
|||
|
typedef Controller * PController;
|
|||
|
|
|||
|
/*
|
|||
|
* Controller (
|
|||
|
* UShort timer_duration,
|
|||
|
* PMCSError mcs_error)
|
|||
|
*
|
|||
|
* Functional Description:
|
|||
|
* This is the constructor for the MCS controller. Its primary
|
|||
|
* duty is to instantiate the application interface and transport
|
|||
|
* interface objects that will be used by this provider. These objects
|
|||
|
* are static in that they are created by the controller constructor
|
|||
|
* and destroyed by the controller destructor (below). Unlike other
|
|||
|
* objects in the system, they are NOT created and destroyed as needed.
|
|||
|
*
|
|||
|
* The constructor also instantiates the memory manager that will be
|
|||
|
* used throughout the MCS system.
|
|||
|
*
|
|||
|
* The constructor also allocates a windows timer that is used to
|
|||
|
* provide MCS with a "heartbeat". This is VERY platform specific and
|
|||
|
* will definitely change before final release.
|
|||
|
*
|
|||
|
* Note that if anything goes wrong, the mcs_error variable will be
|
|||
|
* set to the appropriate error. It is assumed that whoever is creating
|
|||
|
* the controller will check this return value and destroy the newly
|
|||
|
* created controller if something is wrong.
|
|||
|
*
|
|||
|
* Note that it is not possible to use MCS if there is not at least
|
|||
|
* one application interface object successfully created. However, it
|
|||
|
* is possible to use MCS if there are no transport interfaces. Multiple
|
|||
|
* user applications could use this to communicate with one another. On the
|
|||
|
* other hand, MCS_NO_TRANSPORT_STACKS is considered a fatal error.
|
|||
|
*
|
|||
|
* Formal Parameters:
|
|||
|
* timer_duration (i)
|
|||
|
* If non-zero, this causes the constructor to allocate a timer to
|
|||
|
* provide the heartbeat, and this variable is in milliseconds. If
|
|||
|
* zero, no timer is allocated, and the application is responsible
|
|||
|
* for providing the heartbeat.
|
|||
|
* mcs_error (o)
|
|||
|
* This is the return value for the constructor. In C++ constructors
|
|||
|
* cannot directly return a value, but this can be simulated by passing
|
|||
|
* in the address of a return value variable. This value should be
|
|||
|
* checked by whoever creates the controller. If it is anything but
|
|||
|
* MCS_NO_ERROR, the controller should be
|
|||
|
* deleted immediately, as this is a non-recoverable failure.
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
* MCS_NO_ERROR
|
|||
|
* Everything worked fine, and the controller is ready to be used.
|
|||
|
* MCS_NO_TRANSPORT_STACKS
|
|||
|
* The controller initialized okay, but the TCP transport did
|
|||
|
* not initialize.
|
|||
|
* MCS_ALLOCATION_FAILURE
|
|||
|
* MCS was unable to initialize properly due to a memory allocation
|
|||
|
* failure. The controller should be deleted immediately.
|
|||
|
*
|
|||
|
* Side Effects:
|
|||
|
* The proper initialization of the application interface and transport
|
|||
|
* interface objects will probably cause device initializations to occur
|
|||
|
* in readying for communication.
|
|||
|
*
|
|||
|
* Caveats:
|
|||
|
* None.
|
|||
|
*/
|
|||
|
/*
|
|||
|
* ~Controller ();
|
|||
|
*
|
|||
|
* Functional Description:
|
|||
|
* This is the controller destructor. Its primary purpose is to free up
|
|||
|
* all resources used by this MCS provider. It attempts to destroy all
|
|||
|
* objects in a controlled fashion so as to cleanly sever both user
|
|||
|
* attachments and MCS connections. It does this by destroying
|
|||
|
* connections first, and then transport interfaces. Next it deletes
|
|||
|
* user attachments, followed by application interfaces. Only then does
|
|||
|
* it destroy existing domains (which should be empty as a result of all
|
|||
|
* the previous destruction).
|
|||
|
*
|
|||
|
* Note that this is the ONLY place where application interface and
|
|||
|
* transport interface objects are destroyed.
|
|||
|
*
|
|||
|
* Formal Parameters:
|
|||
|
* Destructors have no parameters.
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
* Destructors have no return value.
|
|||
|
*
|
|||
|
* Side Effects:
|
|||
|
* All external connections are broken, and devices will be released.
|
|||
|
*
|
|||
|
* Caveats:
|
|||
|
* None.
|
|||
|
*/
|
|||
|
|
|||
|
/*
|
|||
|
* ULong OwnerCallback (
|
|||
|
* unsigned int message,
|
|||
|
* PVoid parameter1,
|
|||
|
* ULong parameter2)
|
|||
|
*
|
|||
|
* Functional Description:
|
|||
|
* This is the owner callback routine for the MCS controller. This member
|
|||
|
* function is used when it is necessary for an object created by the
|
|||
|
* controller to send a message back to it.
|
|||
|
* Essentially, it allows objects to make requests of their creators
|
|||
|
* without having to "tightly couple" the two classes by having them
|
|||
|
* both aware of the public interface of the other.
|
|||
|
*
|
|||
|
* When an object such as the controller creates an object that expects
|
|||
|
* to use the owner callback facility, the creator is accepting the
|
|||
|
* responsibility of handling owner callbacks. All owner callbacks
|
|||
|
* are defined as part of the interface specification for the object
|
|||
|
* that will issue them.
|
|||
|
*
|
|||
|
* How the controller handles each owner callback is considered an
|
|||
|
* implementation issue within the controller. As such, that information
|
|||
|
* can be found in the controller implementation file.
|
|||
|
*
|
|||
|
* Formal Parameters:
|
|||
|
* message (i)
|
|||
|
* This is the message to processed. Note that when the controller
|
|||
|
* creates each object, it gives it a message offset to use for owner
|
|||
|
* callbacks, so that the controller can differentiate between
|
|||
|
* callbacks from different classes.
|
|||
|
* parameter1 (i)
|
|||
|
* The meaning of this parameter varies according to the message being
|
|||
|
* processed. See the interface specification for the class issuing
|
|||
|
* the owner callback for a detailed explanation.
|
|||
|
* parameter2 (i)
|
|||
|
* The meaning of this parameter varies according to the message being
|
|||
|
* processed. See the interface specification for the class issuing
|
|||
|
* the owner callback for a detailed explanation.
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
* Each owner callback returns an unsigned long. The meaning of this
|
|||
|
* return value varies according to the message being processed. See the
|
|||
|
* interface specification for the class issuing the owner callback for a
|
|||
|
* detailed explanation.
|
|||
|
*
|
|||
|
* Side Effects:
|
|||
|
* Message specific.
|
|||
|
*
|
|||
|
* Caveats:
|
|||
|
* None.
|
|||
|
*/
|
|||
|
|
|||
|
#endif
|
|||
|
|