windows-nt/Source/XPSP1/NT/enduser/netmeeting/as/h/ast120.h

1381 lines
34 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
//
// AppSharing T.120 Layer
// * GCC (conference management)
// * MCS (data)
// * FLOW (data queuing, flow control)
//
// This is also used by ObMan for old Whiteboard, but old Whiteboard will
// disappear in the next version of NM.
//
// Copyright (c) Microsoft 1998-
//
#ifndef _H_AST120
#define _H_AST120
#include <confreg.h>
// REAL T.120 headers
#include <t120.h>
#include <igccapp.h>
#include <imcsapp.h>
#include <iappldr.h>
#include <mtgset.h>
//
// GCC PART
//
//
// Call Manager Secondaries
//
#define CMTASK_FIRST 0
typedef enum
{
CMTASK_OM = CMTASK_FIRST,
CMTASK_AL,
CMTASK_DCS,
CMTASK_WB,
CMTASK_MAX
}
CMTASK;
//
// The GCC Application Registry Key. This is used for enrolling Groupware
// with GCC and for assigning tokens: for all tokens the registration key
// is the Groupware application key followed by the specific tokenKey for
// this secondary.
//
// The MFGCODE portion of this key has been assigned by the ITU.
//
// USACode1 0xb5
// USACode2 0x00
// MFGCode1 0x53
// MFGCode2 0x4c
// "Groupware" 0x02
//
// The length of the key in bytes including the NULLTERM.
//
//
#define GROUPWARE_GCC_APPLICATION_KEY "\xb5\x00\x53\x4c\x02"
//
// Call Manager Events
//
enum
{
CMS_NEW_CALL = CM_BASE_EVENT,
CMS_END_CALL,
CMS_PERSON_JOINED,
CMS_PERSON_LEFT,
CMS_CHANNEL_REGISTER_CONFIRM,
CMS_TOKEN_ASSIGN_CONFIRM
};
//
// CM_STATUS
//
typedef struct tagCM_STATUS
{
UINT_PTR callID;
UINT peopleCount;
BOOL fTopProvider;
UINT topProviderID;
NM30_MTG_PERMISSIONS attendeePermissions;
TSHR_PERSONID localHandle;
char localName[TSHR_MAX_PERSON_NAME_LEN];
}
CM_STATUS;
typedef CM_STATUS * PCM_STATUS;
//
// Secondary instance data
//
typedef struct tagCM_CLIENT
{
STRUCTURE_STAMP
PUT_CLIENT putTask;
CMTASK taskType;
UINT useCount;
// Registering Channel
UINT channelKey;
// Assigning Token
UINT tokenKey;
BOOL exitProcRegistered:1;
}
CM_CLIENT;
typedef CM_CLIENT * PCM_CLIENT;
//
// Person element in linked list of people currently in conference
//
typedef struct tagCM_PERSON
{
BASEDLIST chain;
TSHR_PERSONID netID;
}
CM_PERSON;
typedef CM_PERSON * PCM_PERSON;
//
// Primary data
//
typedef struct tagCM_PRIMARY
{
STRUCTURE_STAMP
PUT_CLIENT putTask;
BOOL exitProcRegistered;
//
// Secondary tasks
//
PCM_CLIENT tasks[CMTASK_MAX];
//
// T.120/call state stuff
//
UINT_PTR callID;
BOOL currentCall;
BOOL fTopProvider;
BOOL bGCCEnrolled;
IGCCAppSap * pIAppSap;
UserID gccUserID;
UserID gccTopProviderID;
//
// People conference stuff
//
char localName[TSHR_MAX_PERSON_NAME_LEN];
UINT peopleCount;
BASEDLIST people;
}
CM_PRIMARY;
typedef CM_PRIMARY * PCM_PRIMARY;
__inline void ValidateCMP(PCM_PRIMARY pcmPrimary)
{
ASSERT(!IsBadWritePtr(pcmPrimary, sizeof(CM_PRIMARY)));
ASSERT(pcmPrimary->putTask);
}
__inline void ValidateCMS(PCM_CLIENT pcm)
{
extern PCM_PRIMARY g_pcmPrimary;
ValidateCMP(g_pcmPrimary);
ASSERT(!IsBadWritePtr(pcm, sizeof(CM_CLIENT)));
ASSERT(pcm->putTask);
ASSERT(pcm->taskType >= CMTASK_FIRST);
ASSERT(pcm->taskType < CMTASK_MAX);
ASSERT(g_pcmPrimary->tasks[pcm->taskType] == pcm);
}
//
// CM Primary Functions
//
BOOL CMP_Init(BOOL * pfCleanup);
void CMP_Term(void);
void CMPCallEnded(PCM_PRIMARY pcmPrimary);
void CMPBroadcast(PCM_PRIMARY pcmPrimary, UINT event, UINT param1, UINT_PTR param2);
void CALLBACK CMPExitProc(LPVOID pcmPrimary);
BOOL CMPGCCEnroll(PCM_PRIMARY pcmPrimary,
GCCConferenceID conferenceID,
BOOL fEnroll);
void CMPProcessPermitToEnroll(PCM_PRIMARY pcmPrimary,
GCCAppPermissionToEnrollInd FAR * pMsg);
void CMPProcessEnrollConfirm(PCM_PRIMARY pcmPrimary,
GCCAppEnrollConfirm FAR * pMsg);
void CMPProcessRegistryConfirm(PCM_PRIMARY pcmPrimary,
GCCMessageType messageType,
GCCRegistryConfirm FAR * pMsg);
void CMPProcessAppRoster(PCM_PRIMARY pcmPrimary,
GCCConferenceID confID,
GCCApplicationRoster FAR * pAppRoster);
//
// Process GCC callbacks
//
void CALLBACK CMPGCCCallback(GCCAppSapMsg FAR * pMsg);
void CMPBuildGCCRegistryKey(UINT dcgKeyNum, GCCRegistryKey FAR * pGCCKey, LPSTR dcgKeyStr);
//
// CM Secondary
//
BOOL CMS_Register(PUT_CLIENT putTask, CMTASK taskType, PCM_CLIENT * pCmHandle);
void CMS_Deregister(PCM_CLIENT * pCmHandle);
#ifdef __cplusplus
extern "C"
{
#endif
BOOL WINAPI CMS_GetStatus(PCM_STATUS pCmStats);
#ifdef __cplusplus
}
#endif
BOOL CMS_ChannelRegister(PCM_CLIENT pcmClient, UINT channelKey, UINT channelID);
BOOL CMS_AssignTokenId(PCM_CLIENT pcmClient, UINT tokenKey);
void CALLBACK CMSExitProc(LPVOID pcmClient);
//
// MCS PART
//
//
// Errors
//
enum
{
// Generic errors
NET_RC_NO_MEMORY = NET_BASE_RC,
NET_RC_INVALID_STATE,
// S20 errors
NET_RC_S20_FAIL,
// MGC errors
NET_RC_MGC_ALREADY_INITIALIZED,
NET_RC_MGC_INVALID_USER_HANDLE,
NET_RC_MGC_INVALID_LENGTH,
NET_RC_MGC_INVALID_DOMAIN,
NET_RC_MGC_TOO_MUCH_IN_USE,
NET_RC_MGC_NOT_YOUR_BUFFER,
NET_RC_MGC_LIST_FAIL,
NET_RC_MGC_NOT_CONNECTED,
NET_RC_MGC_NOT_SUPPORTED,
NET_RC_MGC_NOT_INITIALIZED,
NET_RC_MGC_INIT_FAIL,
NET_RC_MGC_DOMAIN_IN_USE,
NET_RC_MGC_NOT_ATTACHED,
NET_RC_MGC_INVALID_CONN_HANDLE,
NET_RC_MGC_INVALID_UP_DOWN_PARM,
NET_RC_MGC_INVALID_REMOTE_ADDRESS,
NET_RC_MGC_CALL_FAILED
};
//
// Results
//
typedef TSHR_UINT16 NET_RESULT;
enum
{
NET_RESULT_OK = 0,
NET_RESULT_NOK,
NET_RESULT_CHANNEL_UNAVAILABLE,
NET_RESULT_DOMAIN_UNAVAILABLE,
NET_RESULT_REJECTED,
NET_RESULT_TOKEN_ALREADY_GRABBED,
NET_RESULT_TOKEN_NOT_OWNED,
NET_RESULT_NOT_SPECIFIED,
NET_RESULT_UNKNOWN,
NET_RESULT_USER_REJECTED
};
//
// Reaons
//
typedef enum
{
NET_REASON_DOMAIN_DISCONNECTED = 1,
NET_REASON_DOMAIN_UNAVAILABLE,
NET_REASON_TOKEN_NONEXISTENT,
NET_REASON_USER_REQUESTED,
NET_REASON_CHANNEL_UNAVAILABLE,
NET_REASON_UNKNOWN
}
NET_REASON;
//
// Events
//
enum
{
NET_EVENT_USER_ATTACH = NET_BASE_EVENT,
NET_EVENT_USER_DETACH,
NET_EVENT_CHANNEL_JOIN,
NET_EVENT_CHANNEL_LEAVE,
NET_EVENT_TOKEN_GRAB,
NET_EVENT_TOKEN_INHIBIT,
NET_EVENT_DATA_RECEIVED,
NET_FEEDBACK,
NET_FLOW,
NET_MG_SCHEDULE,
NET_MG_WATCHDOG
};
//
// FOR MCS USERS (ALL APPS, INCLUDING CALL MANAGER)
//
// state->| 0 | 1 | 2 | 3 | 4 | 5
// |CTRLR |CTRLR |CTLR |CTLR |CTLR |CTLR
// |state |state 2,|state2, |state2, |state 3, |state 3
// | 0/1 |user not|user |user |user |user
// verb/event | |attached|pending |attached |attached |pending
// | |......|........|........|..........|.........|.........
// V | | | | | |
// _get_buffer | X | X | X | - | ** | X
// _free_buffer | X | X | X | - | - | -
// _realloc_bfr | X | X | X | - | - | -
// _attach_user | X | ->2 | X | X | X | X
// _detach_user | X | X | X | ->1 | ->0 | X
// _channel_join | X | X | X | - | X | X
// _channel_leave | X | X | X | - | - | X
// _send_data | X | X | X | - | X | X
// | | | | | |
// _STOP_CONTRLR* | | ->0 | ->5 | ->4 | |
// | | | | | |
// _ATTACH_CNF OK | | | ->3 | | | ->4
// _ATTACH_CNF FAIL| | | ->1 | | | ->0
// _DETACH_IND-SELF| | | ->1 | ->1 | ->0 |
// _DETACH_IND-othr| | | | - | - |
// _JOIN_CONFIRM | | | | - | - |
// _LEAVE_INDICAT | | | | - | - |
// _SEND_INDICAT | | | | - | - |
// =======================================================================
//
// NOTES ** when the controller is STOPPING the NET_GetBuffer
// verb is valid but always returns a NULL buffer (no memory)
//
// * the STOP_CONTROLLER event is internally generated, and is
// not seen across the API. It is generated when the controller
// issues the NET_StopController verb and causes the state change
// (to state 0, 4 or 5) such that the NET_AttachUser,
// ChannelJoin and NET_SendData verbs are rejected.
//
//
//
//
// Priorities
//
#define NET_INVALID_PRIORITY ((NET_PRIORITY)-1)
enum
{
NET_TOP_PRIORITY = 0,
NET_HIGH_PRIORITY,
NET_MEDIUM_PRIORITY,
NET_LOW_PRIORITY,
NET_NUM_PRIORITIES
};
//
// SFR6025: This flag is or-ed with the priority bit to indicate to the MCS
// glue that it should send data on all channels.
//
//
// FOR OBMAN ONLY -- REMOVE IN NM 4.0
//
#define NET_SEND_ALL_PRIORITIES 0x8000
#define NET_ALL_REMOTES ((NET_UID)1)
#define NET_INVALID_DOMAIN_ID (0xFFFFFFFF)
#define NET_UNUSED_IDMCS 1
typedef TSHR_UINT16 NET_UID; // MCS user IDs
typedef TSHR_UINT16 NET_CHANNEL_ID; // MCS channel IDs
typedef TSHR_UINT16 NET_TOKEN_ID; // MCS token IDs
typedef TSHR_UINT16 NET_PRIORITY; // MCS priorities
//
// Forward decls of MGC structures
//
typedef struct tagMG_BUFFER * PMG_BUFFER;
typedef struct tagMG_CLIENT * PMG_CLIENT;
//
// Flow control structure - This contains the target latency (in mS) and
// stream size (in bytes) for each User Attachment
// lonchanc: used by S20, MG, and OM.
//
typedef struct tag_NET_FLOW_CONTROL
{
UINT latency[NET_NUM_PRIORITIES];
UINT streamSize[NET_NUM_PRIORITIES];
}
NET_FLOW_CONTROL, * PNET_FLOW_CONTROL;
//
// NET_EV_JOIN_CONFIRM and NET_EV_JOIN_CONFIRM_BY_KEY
// join_channel confirm:
// lonchanc: used by S20, MG, and OM.
//
typedef struct tagNET_JOIN_CNF_EVENT
{
UINT_PTR callID;
NET_RESULT result; // NET_RESULT_USER_ACCEPTED/REJECTED
TSHR_UINT16 pad1;
NET_CHANNEL_ID correlator;
NET_CHANNEL_ID channel;
}
NET_JOIN_CNF_EVENT;
typedef NET_JOIN_CNF_EVENT * PNET_JOIN_CNF_EVENT;
//
// NET_EV_SEND_INDICATION
// send data indication: see MG_SendData()
// Despite its name, this event indicates that data has been RECEIVED!
// lonchanc: used by MG and S20
//
typedef struct tag_NET_SEND_IND_EVENT
{
UINT_PTR callID;
NET_PRIORITY priority;
NET_CHANNEL_ID channel;
UINT lengthOfData;
LPBYTE data_ptr; // Pointer to the real data.
}
NET_SEND_IND_EVENT;
typedef NET_SEND_IND_EVENT * PNET_SEND_IND_EVENT;
//
// MGC, FLOW CONTROL
//
//
// MG tasks
//
#define MGTASK_FIRST 0
typedef enum
{
MGTASK_OM = MGTASK_FIRST,
MGTASK_DCS,
MGTASK_MAX
}
MGTASK;
//
// Buffer types
//
enum
{
MG_TX_BUFFER = 1,
MG_RX_BUFFER,
MG_EV_BUFFER,
MG_TX_PING,
MG_TX_PONG,
MG_TX_PANG,
MG_RQ_CHANNEL_JOIN,
MG_RQ_CHANNEL_JOIN_BY_KEY,
MG_RQ_CHANNEL_LEAVE,
MG_RQ_TOKEN_GRAB,
MG_RQ_TOKEN_INHIBIT,
MG_RQ_TOKEN_RELEASE
};
//
// Period of watchdog timer to detect lost connections
//
#define MG_TIMER_PERIOD 1000
//
// MG priorities:
//
#define MG_HIGH_PRIORITY NET_HIGH_PRIORITY
#define MG_MEDIUM_PRIORITY NET_MEDIUM_PRIORITY
#define MG_LOW_PRIORITY NET_LOW_PRIORITY
#define MG_PRIORITY_HIGHEST MG_HIGH_PRIORITY
#define MG_PRIORITY_LOWEST MG_LOW_PRIORITY
#define MG_NUM_PRIORITIES (MG_PRIORITY_LOWEST - MG_PRIORITY_HIGHEST + 1)
//
// MCS priority validation.
// Priorities are contiguous numbers in the range NET_PRIORITY_HIGHEST..
// NETPRIORITY_LOWEST. Priorities supplied to MG may also have the
// NET_SEND_ALL_PRIORITIES flag set. So, to validate a priority:
// - knock off the NET_SEND_ALL_PRIORITIES flag to give the raw priority
// - set the valid raw prioririty to
// NET_PRIORITY_HIGHEST if the raw priority is less than ...ITY_HIGHEST
// NET_PRIORITY_LOWEST if the raw priority is more than ...ITY_LOWEST
// the raw priority if it is in the valid range
// - add the original ...ALL_PRIORITIES flag to the valid raw priority
//
#define MG_VALID_PRIORITY(p) \
((((p)&~NET_SEND_ALL_PRIORITIES)<MG_HIGH_PRIORITY)? \
(MG_HIGH_PRIORITY|((p)&NET_SEND_ALL_PRIORITIES)): \
(((p)&~NET_SEND_ALL_PRIORITIES)>MG_LOW_PRIORITY)? \
(MG_LOW_PRIORITY|((p)&NET_SEND_ALL_PRIORITIES)): \
(p))
//
//
// The initial stream size setting may appear high, but it is set so that
// in a LAN scenario we do not require the app to place a lot of forward
// pressure on the pipe before it opens up. In a non-LAN scenario we may
// not do enough spoiling to start with, but in actual fact DCS tends
// to send less data than this limit anyway, so we should reduce it
// quite quickly without flooding the buffers.
//
#define FLO_INIT_STREAMSIZE 8000
#define FLO_MIN_STREAMSIZE 500
#define FLO_MAX_STREAMSIZE 256000
#define FLO_MIN_PINGTIME 100
#define FLO_INIT_PINGTIME 1000
//
// This is the max number of bytes that can be allocated per stream if a
// pong has not been received (i.e. FC is not operational).
//
#define FLO_MAX_PRE_FC_ALLOC 16000
//
// This is the max number of pkts outstanding before we apply back
// pressure:
//
#define FLO_MAX_RCV_PACKETS 5
//
// This is the max number of pkts outstanding before we get worried about
// creep:
//
#define FLO_MAX_RCV_PKTS_CREEP 250
//
// The maximum number of flow controlled streams.
//
#define FLO_MAX_STREAMS 128
#define FLO_NOT_CONTROLLED FLO_MAX_STREAMS
//
// STRUCTURE : FLO_STREAM_DATA
//
// DESCRIPTION:
//
// This structure holds all the static data for a flow control stream
//
// FIELDS:
//
// channel
// priority
// pingValue - Next ping value to be sent on the pipe
// eventNeeded - We need to wake up the app because we have rejected
// a buffer allocation request
// backlog - the allowable backlog in mS bejond which we apply
// back pressure
// pingNeeded - Send a ping at the next opportunity
// pingTime - Minimum time, in mS, between each ping
// gotPong - Indicates we have received a pong from some remote
// party and so flow control can commence
// lastPingTime - Time for last ping, in timer ticks
// nextPingTime - Time for next ping, in timer ticks
// lastDenialTime - Previous time (in ticks) that we started denying
// buffer requests
// curDenialTime - Time in ticks that we most recently started denying
// buffer requests
// DC_ABSMaxBytesInPipe
// - Absolute maximum buffer allocation for this stream
// maxBytesInPipe - Current buffer allocation limit
// bytesInPipe - Current amount of data outstanding on this stream.
// This includes data currently waiting to be sent.
// users - Base for queue of User correlators
// bytesAllocated - The current amount of data in the glue for this
// stream which has not been sent. This is different
// to bytesInPipe which is the amount of unacknowledged
// data in this stream.
//
//
typedef struct tagFLO_STREAM_DATA
{
STRUCTURE_STAMP
NET_CHANNEL_ID channel;
WORD gotPong:1;
WORD eventNeeded:1;
WORD pingNeeded:1;
UINT priority;
UINT pingValue;
UINT backlog;
UINT pingTime;
UINT lastPingTime;
UINT nextPingTime;
UINT lastDenialTime;
UINT curDenialTime;
UINT DC_ABSMaxBytesInPipe;
UINT maxBytesInPipe;
UINT bytesInPipe;
UINT bytesAllocated;
BASEDLIST users;
}
FLO_STREAM_DATA;
typedef FLO_STREAM_DATA * PFLO_STREAM_DATA;
void __inline ValidateFLOStr(PFLO_STREAM_DATA pStr)
{
if (pStr != NULL)
{
ASSERT(!IsBadWritePtr(pStr, sizeof(FLO_STREAM_DATA)));
}
}
//
// The FLO callback function
//
// A wakeup type callback indicates that a back pressure situation has
// been relieved.
//
// A buffermod callback indicates this as well, but also indicates that
// the buffer size for controlling flow on the designated channel/priority
// has changed.
//
#define FLO_WAKEUP 1
#define FLO_BUFFERMOD 2
typedef void (* PFLOCALLBACK)(PMG_CLIENT pmgClient,
UINT callbackType,
UINT priority,
UINT newBufferSize);
//
// STRUCTURE : FLO_STATIC_DATA
//
// DESCRIPTION:
//
// This structure holds all the instance specific static data for the
// Flow Control DLL
//
// FIELDS:
//
// numStreams - ID of the highest allocated stream
// rsvd - reserved
// callback - pointer to a callback function
// pStrData - an array of FLO_STREAM_DATA pointers.
//
//
typedef struct FLO_STATIC_DATA
{
UINT numStreams;
PFLOCALLBACK callBack;
PFLO_STREAM_DATA pStrData[FLO_MAX_STREAMS];
}
FLO_STATIC_DATA;
typedef FLO_STATIC_DATA * PFLO_STATIC_DATA;
typedef struct FLO_USER
{
BASEDLIST list;
STRUCTURE_STAMP
WORD userID;
WORD lastPongRcvd;
WORD pongNeeded;
BYTE sendPongID;
BYTE pad1;
UINT sentPongTime; // Time we actually sent the pong
WORD rxPackets; // Count of packets outstanding
WORD gotPong; // Indicates this user has ponged
// and they are permitted to apply
// back pressure to our sends
UINT numPongs; // total number of pongs from user
UINT pongDelay; // total latency across pongs
}
FLO_USER;
typedef FLO_USER * PFLO_USER;
void __inline ValidateFLOUser(PFLO_USER pFloUser)
{
ASSERT(!IsBadWritePtr(pFloUser, sizeof(FLO_USER)));
}
//
// Maximum wait time before assuming a user is offline
// We need to keep this high until the apps become "well behaved" and
// respond to the flow control buffer size recommendations.
//
#define FLO_MAX_WAIT_TIME 20000
//
//
// Client Control Block
//
//
typedef struct tagMG_CLIENT
{
PUT_CLIENT putTask;
PCM_CLIENT pcmClient;
BASEDLIST buffers; // list of children buffers
BASEDLIST pendChain; // Chain of pending request from client
BASEDLIST joinChain; // Chain of pending join-by-key requests
//
// MCS user attachment info
//
PIMCSSap m_piMCSSap; // user interface ptr returned by MCS
UserID userIDMCS; // user ID returned by MCS
FLO_STATIC_DATA flo; // flow control structure
WORD eventProcReg:1;
WORD lowEventProcReg:1;
WORD exitProcReg:1;
WORD joinPending:1; // Is there a channel join outstanding ?
WORD userAttached:1;
WORD joinNextCorr;
NET_FLOW_CONTROL flowControl; // flow control latency/backlog params
}
MG_CLIENT;
void __inline ValidateMGClient(PMG_CLIENT pmgc)
{
ASSERT(!IsBadWritePtr(pmgc, sizeof(MG_CLIENT)));
ValidateUTClient(pmgc->putTask);
}
typedef struct tagMG_INT_PKT_HEADER
{
TSHR_UINT16 useCount; // The use count of this packet. This
// is required for sending the same
// data on multiple channels.
TSHR_NET_PKT_HEADER header;
}
MG_INT_PKT_HEADER;
typedef MG_INT_PKT_HEADER * PMG_INT_PKT_HEADER;
//
//
// Buffer Control Block
//
//
typedef struct tagMG_BUFFER
{
STRUCTURE_STAMP
UINT type;
BASEDLIST pendChain; // Used when the buffer is added to the
BASEDLIST clientChain;
PMG_INT_PKT_HEADER pPktHeader; // Pointer to MCS control info
void * pDataBuffer; // Pointer passed to apps
UINT length; // length of the associated packet
ChannelID channelId; // Send destination, or token grab req
ChannelID channelKey;
UserID senderId;
NET_PRIORITY priority;
BOOL eventPosted;
UINT work; // work field for misc use
PFLO_STREAM_DATA pStr; // Pointer to the FC stream
}
MG_BUFFER;
void __inline ValidateMGBuffer(PMG_BUFFER pmgb)
{
ASSERT(!IsBadWritePtr(pmgb, sizeof(MG_BUFFER)));
}
//
//
//
// MACROS
//
//
//
//
// MCS priority validation.
// Priorities are contiguous numbers in the range NET_PRIORITY_HIGHEST..
// NET_PRIORITY_LOWEST. Priorities supplied to MG may also have the
// NET_SEND_ALL_PRIORITIES flag set. So, to validate a priority:
// - knock off the NET_SEND_ALL_PRIORITIES flag to give the raw priority
// - set the valid raw priority to
// - NET_PRIORITY_HIGHEST if the raw priority is less than ...ITY_HIGHEST
// - NET_PRIORITY_LOWEST if the raw priority is more than ...ITY_LOWEST
// - the raw priority if it is in the valid range
// - add the original ...ALL_PRIORITIES flag to the valid raw priority.
//
//
//
//
// FUNCTION PROTOTYPES
//
//
//
//
//
// MGLongStopHandler(...)
//
// This function is registered as a low priority event handler for each
// client. It catches any unprocessed network events and frees any
// associated memory.
//
//
BOOL CALLBACK MGLongStopHandler(LPVOID pmgClient, UINT event, UINT_PTR param1, UINT_PTR param2);
//
//
// MGEventHandler(...)
//
// This function is registered as a high priority event handler for the
// processing of MG_ChannelJoinByKey, MCS request handling and scheduling.
// It catches NET channel join confirm and CMS register channel confirm
// events, and massages them into the correct return events for the app.
// It queues requests coming from the app context into the glue context
// and schedules queued requests.
//
//
BOOL CALLBACK MGEventHandler(LPVOID pmgClient, UINT event, UINT_PTR param1, UINT_PTR param2);
//
UINT MGHandleSendInd(PMG_CLIENT pmgClient, PSendData pSendInfo);
//
//
// MGNewBuffer(...)
// NewTxBuffer(...)
// NewRxBuffer(...)
// FreeBuffer(...)
//
// The New function allocates and initialises a buffer , allocates buffer
// memory of the specified size and type and adds the to the client's
// list of buffer s.
//
// The Tx version performs flow control on the buffer allocation request
// The Rx version just allocates a receive buffer
//
// The Free function discards a buffer , discards the associated buffer
// memory, decrements the client's count of memory in use and removes the
// from the client's list of buffer s.
//
//
void MGNewCorrelator(PMG_CLIENT ppmgClient, WORD * pCorrelator);
UINT MGNewBuffer(PMG_CLIENT pmgClient, UINT typeOfBuffer,
PMG_BUFFER * ppBuffer);
UINT MGNewDataBuffer(PMG_CLIENT pmgClient,
UINT typeOfBuffer,
UINT sizeOfBuffer,
PMG_BUFFER * ppBuffer);
UINT MGNewTxBuffer(PMG_CLIENT pmgClient,
NET_PRIORITY priority,
NET_CHANNEL_ID channel,
UINT sizeOfBuffer,
PMG_BUFFER * ppBuffer);
UINT MGNewRxBuffer(PMG_CLIENT pmgClient,
NET_PRIORITY priority,
NET_CHANNEL_ID channel,
NET_CHANNEL_ID senderID,
PMG_BUFFER * ppBuffer);
void MGFreeBuffer(PMG_CLIENT pmgClient, PMG_BUFFER * ppBuffer);
//
//
// MGProcessDomainWatchdog(...)
//
// Handle domain watchdog timer ticks.
//
//
void MGProcessDomainWatchdog(PMG_CLIENT pmgClient);
void MGProcessEndFlow(PMG_CLIENT pmgClient, ChannelID channel);
UINT MGPostJoinConfirm(PMG_CLIENT pmgClient,
NET_RESULT result,
NET_CHANNEL_ID channel,
NET_CHANNEL_ID correlator);
NET_RESULT TranslateResult(WORD Result);
//
//
// MGFLOCallBack(...)
//
// Callback poked by flow control to trigger the app to retry buffer
// requests thet were previously rejected
//
//
void MGFLOCallBack(PMG_CLIENT pmgClient,
UINT callbackType,
UINT priority,
UINT newBufferSize);
//
//
// MGProcessPendingQueue(...)
//
// Called whenever MG wants to try and execute pending requests. Requests
// are queued because they may fail for a transient reason, such as MCS
// buffer shortage.
//
//
UINT MGProcessPendingQueue(PMG_CLIENT pmgClient);
BOOL MG_Register(MGTASK task, PMG_CLIENT * pmgClient, PUT_CLIENT putTask);
void MG_Deregister(PMG_CLIENT * ppmgClient);
void CALLBACK MGExitProc(LPVOID uData);
UINT MG_Attach(PMG_CLIENT pmgClient, UINT_PTR callID, PNET_FLOW_CONTROL pFlowControl);
void MG_Detach(PMG_CLIENT pmgClient);
void MGDetach(PMG_CLIENT pmgClient);
UINT MG_ChannelJoin(PMG_CLIENT pmgClient, NET_CHANNEL_ID * pCorrelator,
NET_CHANNEL_ID channel);
UINT MG_ChannelJoinByKey(PMG_CLIENT pmgClient,
NET_CHANNEL_ID * pCorrelator,
WORD channelKey);
void MG_ChannelLeave(PMG_CLIENT pmgClient, NET_CHANNEL_ID channel);
UINT MG_GetBuffer(PMG_CLIENT pmgClient, UINT length,
NET_PRIORITY priority,
NET_CHANNEL_ID channel,
void ** buffer);
void MG_FreeBuffer(PMG_CLIENT pmgClient,
void ** buffer);
UINT MG_SendData(PMG_CLIENT pmgClient,
NET_PRIORITY priority,
NET_CHANNEL_ID channel,
UINT length,
void ** data);
UINT MG_TokenGrab(PMG_CLIENT pmgClient, NET_TOKEN_ID token);
UINT MG_TokenInhibit(PMG_CLIENT pmgClient, NET_TOKEN_ID token);
void MG_FlowControlStart(PMG_CLIENT pmgClient,
NET_CHANNEL_ID channel,
NET_PRIORITY priority,
UINT backlog,
UINT maxBytesOutstanding);
//
// API FUNCTION: FLO_UserTerm
//
// DESCRIPTION:
//
// Called by an application to end flow control on all the channels
// associated with a particular user.
//
// PARAMETERS:
//
// pUser - MCS Glue User attachment
//
// RETURNS: Nothing.
//
//
void FLO_UserTerm(PMG_CLIENT pmgClient);
//
// API FUNCTION: FLO_StartControl
//
// DESCRIPTION:
//
// The application calls this function whenever it wants a data stream to
// be flow controlled
//
// PARAMETERS:
//
// pUser - MCS Glue User attachment
// channel - channel id of channel to be flow controlled
// priority - priority of the stream to be controlled
// backlog - the maximum backlog (in mS) allowed for this stream
// maxBytesOutstanding - the maximum number of bytes allowed in the stream
// irrespective of the backlog. 0 = use default of
// 64 KBytes
//
// RETURNS:
// None
//
//
void FLO_StartControl(PMG_CLIENT pmgClient,
NET_CHANNEL_ID channel,
UINT priority,
UINT backlog,
UINT maxBytesOutstanding);
void FLO_EndControl
(
PMG_CLIENT pmgClient,
NET_CHANNEL_ID channel,
UINT priority
);
//
// API FUNCTION: FLO_AllocSend
//
// DESCRIPTION:
//
// The application is requesting a buffer in order to send a packet. This
// may trigger a flow control packet in advance of the application packet.
// Flow control may choose to reject the packet with NET_OUT_OF_RESOURCE in
// which case the application must reschedule the allocation at a ater
// date. To assist the rescheduling, if ever a send is rejected then flow
// control will call the application callback to trigger the reschedule.
//
// PARAMETERS:
//
// pUser - MCS Glue User attachment
// priority - The priority for this buffer
// channel - The channnel on which to send the packet
// size - The size of the packet
// ppStr - Pointer to the pointer to the FC stream. This is a
// return value.
//
//
UINT FLO_AllocSend(PMG_CLIENT pmgClient,
UINT priority,
NET_CHANNEL_ID channel,
UINT size,
PFLO_STREAM_DATA * ppStr);
//
// API FUNCTION: FLO_ReallocSend
//
// DESCRIPTION:
//
// The application has requested that the glue send a packet, but the
// packet contains less data than originally requested.
// Flow control heuristics get thrown out unless we logically free the
// unused portion of the packet for reuse for other allocations.
// If we didn't do this then we might see a 8K packet, for example,
// complete in 1 second because the app only put 1K of data in it.
//
// PARAMETERS:
//
// pUser - MCS Glue User attachment
// pStr - The flow control stream to be corrected
// size - The size of the packet that has been unused
//
// RETURNS:
//
// None
//
//
void FLO_ReallocSend(PMG_CLIENT pmgClient,
PFLO_STREAM_DATA pStr,
UINT size);
//
// API FUNCTION: FLO_DecrementAlloc
//
// DESCRIPTION:
//
// This function decrements the bytesAllocated count for a given stream.
// It is called whenever a packet is sent or removed from the send chain.
//
// PARAMETERS:
//
// pStr - The flow control stream to be decremented
// size - The size to decrement
//
// RETURNS:
//
// None
//
//
void FLO_DecrementAlloc( PFLO_STREAM_DATA pStr,
UINT size);
//
// API FUNCTION: FLO_ReceivedPacket
//
// DESCRIPTION:
//
// Upon receipt of a flow control packet the MCS glue calls this function
// and then ignores the packet.
//
// PARAMETERS:
//
// pUser - MCS Glue User attachment
// pPkt - pointer to the packet, for FLO to process
//
// RETURNS:
//
// None
//
//
void FLO_ReceivedPacket(PMG_CLIENT pmgClient, PTSHR_FLO_CONTROL pPkt);
//
// API FUNCTION: FLO_AllocReceive
//
// DESCRIPTION:
//
// Called to indicate that a receive buffer is now in use by the application
//
// PARAMETERS:
//
// pmg - pointer to the glue user attacgment cb
// priority
// channel
// size - size of the buffer just been allocated
//
// RETURNS:
//
// None
//
//
void FLO_AllocReceive(PMG_CLIENT pmgClient,
UINT priority,
NET_CHANNEL_ID channel,
UINT senderID);
//
// API FUNCTION: FLO_FreeReceive
//
// DESCRIPTION:
//
// Called to indicate that a receive buffer has ben handed back by the
// application.
//
// PARAMETERS:
//
// pmg - pointer to the glue user attachment cb
// priority
// channel
// size - size of the buffer just been freed
//
// RETURNS:
//
// None
//
//
void FLO_FreeReceive(PMG_CLIENT pmgClient,
NET_PRIORITY priority,
NET_CHANNEL_ID channel,
UINT senderID);
//
// API FUNCTION: FLO_CheckUsers
//
// DESCRIPTION:
//
// Called periodically by each client to allow flow control to determine if
// remote users have left the channel
//
// PARAMETERS:
//
// pmg - pointer to the user
//
// RETURNS:
//
// None
//
//
void FLO_CheckUsers(PMG_CLIENT pmgClient);
//
// FLOGetStream()
//
UINT FLOGetStream(PMG_CLIENT pmgClient, NET_CHANNEL_ID channel, UINT priority,
PFLO_STREAM_DATA * ppStr);
void FLOStreamEndControl(PMG_CLIENT pmgClient, UINT stream);
void FLOPing(PMG_CLIENT pmgClient, UINT stream, UINT curtime);
void FLOPang(PMG_CLIENT pmgClient, UINT stream, UINT userID);
void FLOPong(PMG_CLIENT pmgClient, UINT stream, UINT userID, UINT pongID);
//
// API FUNCTION: FLOAddUser
//
// DESCRIPTION:
//
// Add a user to a flow controlled stream
//
// PARAMETERS:
//
// userID - ID of the new user (single member channel ID)
// pStr - pointer to the stream to receive the new user
//
// RETURNS:
//
// None
//
//
PFLO_USER FLOAddUser(UINT userID,
PFLO_STREAM_DATA pStr);
//
// API FUNCTION: FLO_RemoveUser
//
// DESCRIPTION:
//
// Remove a user from a flow controlled stream
//
// PARAMETERS:
//
// pmg - pointer to the MCS glue user
// userID - ID of the bad user (single member channel ID)
//
// RETURNS:
//
// None
//
//
void FLO_RemoveUser(PMG_CLIENT pmgClient, UINT userID);
//
// FUNCTION: MGCallback
//
// DESCRIPTION:
//
// This function is the callback passed to MCS. The glue layer receives
// all communication from MCS via this function. It converts MCS messages
// into DC-Groupware events and posts them to the relevant client(s).
//
//
void CALLBACK MGCallback( unsigned int mcsMessageType,
UINT_PTR eventData,
UINT_PTR pUser );
#endif // _H_AST120