|
|
//
// 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
|