Source code of Windows XP (NT5)
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.

1371 lines
34 KiB

  1. //
  2. // AppSharing T.120 Layer
  3. // * GCC (conference management)
  4. // * MCS (data)
  5. // * FLOW (data queuing, flow control)
  6. //
  7. // This is also used by ObMan for old Whiteboard, but old Whiteboard will
  8. // disappear in the next version of NM.
  9. //
  10. // Copyright (c) Microsoft 1998-
  11. //
  12. #ifndef _H_AST120
  13. #define _H_AST120
  14. #include <confreg.h>
  15. // REAL T.120 headers
  16. #include <t120.h>
  17. #include <igccapp.h>
  18. #include <imcsapp.h>
  19. //
  20. // GCC PART
  21. //
  22. //
  23. // Call Manager Secondaries
  24. //
  25. #define CMTASK_FIRST 0
  26. typedef enum
  27. {
  28. CMTASK_OM = CMTASK_FIRST,
  29. CMTASK_AL,
  30. CMTASK_DCS,
  31. CMTASK_WB,
  32. CMTASK_MAX
  33. }
  34. CMTASK;
  35. //
  36. // The GCC Application Registry Key. This is used for enrolling Groupware
  37. // with GCC and for assigning tokens: for all tokens the registration key
  38. // is the Groupware application key followed by the specific tokenKey for
  39. // this secondary.
  40. //
  41. // The MFGCODE portion of this key has been assigned by the ITU.
  42. //
  43. // USACode1 0xb5
  44. // USACode2 0x00
  45. // MFGCode1 0x53
  46. // MFGCode2 0x4c
  47. // "Groupware" 0x02
  48. //
  49. // The length of the key in bytes including the NULLTERM.
  50. //
  51. //
  52. #define GROUPWARE_GCC_APPLICATION_KEY "\xb5\x00\x53\x4c\x02"
  53. //
  54. // Call Manager Events
  55. //
  56. enum
  57. {
  58. CMS_NEW_CALL = CM_BASE_EVENT,
  59. CMS_END_CALL,
  60. CMS_PERSON_JOINED,
  61. CMS_PERSON_LEFT,
  62. CMS_CHANNEL_REGISTER_CONFIRM,
  63. CMS_TOKEN_ASSIGN_CONFIRM
  64. };
  65. //
  66. // CM_STATUS
  67. //
  68. typedef struct tagCM_STATUS
  69. {
  70. UINT callID;
  71. UINT peopleCount;
  72. BOOL fTopProvider;
  73. UINT topProviderID;
  74. TSHR_PERSONID localHandle;
  75. char localName[TSHR_MAX_PERSON_NAME_LEN];
  76. }
  77. CM_STATUS;
  78. typedef CM_STATUS * PCM_STATUS;
  79. BOOL WINAPI CMS_GetStatus(PCM_STATUS pcmStatus);
  80. //
  81. // Secondary instance data
  82. //
  83. typedef struct tagCM_CLIENT
  84. {
  85. STRUCTURE_STAMP
  86. PUT_CLIENT putTask;
  87. CMTASK taskType;
  88. UINT useCount;
  89. // Registering Channel
  90. UINT channelKey;
  91. // Assigning Token
  92. UINT tokenKey;
  93. BOOL exitProcRegistered:1;
  94. }
  95. CM_CLIENT;
  96. typedef CM_CLIENT * PCM_CLIENT;
  97. //
  98. // Person element in linked list of people currently in conference
  99. //
  100. typedef struct tagCM_PERSON
  101. {
  102. BASEDLIST chain;
  103. TSHR_PERSONID netID;
  104. }
  105. CM_PERSON;
  106. typedef CM_PERSON * PCM_PERSON;
  107. //
  108. // Primary data
  109. //
  110. typedef struct tagCM_PRIMARY
  111. {
  112. STRUCTURE_STAMP
  113. PUT_CLIENT putTask;
  114. BOOL exitProcRegistered;
  115. //
  116. // Secondary tasks
  117. //
  118. PCM_CLIENT tasks[CMTASK_MAX];
  119. //
  120. // T.120/call state stuff
  121. //
  122. UINT callID;
  123. BOOL currentCall;
  124. BOOL fTopProvider;
  125. BOOL bGCCEnrolled;
  126. IGCCAppSap * pIAppSap;
  127. UserID gccUserID;
  128. UserID gccTopProviderID;
  129. //
  130. // People conference stuff
  131. //
  132. char localName[TSHR_MAX_PERSON_NAME_LEN];
  133. UINT peopleCount;
  134. BASEDLIST people;
  135. }
  136. CM_PRIMARY;
  137. typedef CM_PRIMARY * PCM_PRIMARY;
  138. __inline void ValidateCMP(PCM_PRIMARY pcmPrimary)
  139. {
  140. ASSERT(!IsBadWritePtr(pcmPrimary, sizeof(CM_PRIMARY)));
  141. ASSERT(pcmPrimary->putTask);
  142. }
  143. __inline void ValidateCMS(PCM_CLIENT pcm)
  144. {
  145. extern PCM_PRIMARY g_pcmPrimary;
  146. ValidateCMP(g_pcmPrimary);
  147. ASSERT(!IsBadWritePtr(pcm, sizeof(CM_CLIENT)));
  148. ASSERT(pcm->putTask);
  149. ASSERT(pcm->taskType >= CMTASK_FIRST);
  150. ASSERT(pcm->taskType < CMTASK_MAX);
  151. ASSERT(g_pcmPrimary->tasks[pcm->taskType] == pcm);
  152. }
  153. //
  154. // CM Primary Functions
  155. //
  156. BOOL CMP_Init(BOOL * pfCleanup);
  157. void CMP_Term(void);
  158. void CMPCallEnded(PCM_PRIMARY pcmPrimary);
  159. void CMPBroadcast(PCM_PRIMARY pcmPrimary, UINT event, UINT param1, UINT param2);
  160. void CALLBACK CMPExitProc(LPVOID pcmPrimary);
  161. BOOL CMPGCCEnroll(PCM_PRIMARY pcmPrimary,
  162. GCCConferenceID conferenceID,
  163. BOOL fEnroll);
  164. void CMPProcessPermitToEnroll(PCM_PRIMARY pcmPrimary,
  165. GCCAppPermissionToEnrollInd FAR * pMsg);
  166. void CMPProcessEnrollConfirm(PCM_PRIMARY pcmPrimary,
  167. GCCAppEnrollConfirm FAR * pMsg);
  168. void CMPProcessRegistryConfirm(PCM_PRIMARY pcmPrimary,
  169. GCCMessageType messageType,
  170. GCCRegistryConfirm FAR * pMsg);
  171. void CMPProcessAppRoster(PCM_PRIMARY pcmPrimary,
  172. GCCConferenceID confID,
  173. GCCApplicationRoster FAR * pAppRoster);
  174. //
  175. // Process GCC callbacks
  176. //
  177. void CALLBACK CMPGCCCallback(GCCAppSapMsg FAR * pMsg);
  178. void CMPBuildGCCRegistryKey(UINT dcgKeyNum, GCCRegistryKey FAR * pGCCKey, LPSTR dcgKeyStr);
  179. //
  180. // CM Secondary
  181. //
  182. BOOL CMS_Register(PUT_CLIENT putTask, CMTASK taskType, PCM_CLIENT * pCmHandle);
  183. void CMS_Deregister(PCM_CLIENT * pCmHandle);
  184. BOOL CMS_ChannelRegister(PCM_CLIENT pcmClient, UINT channelKey, UINT channelID);
  185. BOOL CMS_AssignTokenId(PCM_CLIENT pcmClient, UINT tokenKey);
  186. void CALLBACK CMSExitProc(LPVOID pcmClient);
  187. //
  188. // MCS PART
  189. //
  190. //
  191. // Errors
  192. //
  193. enum
  194. {
  195. // Generic errors
  196. NET_RC_NO_MEMORY = NET_BASE_RC,
  197. NET_RC_INVALID_STATE,
  198. // S20 errors
  199. NET_RC_S20_FAIL,
  200. // MGC errors
  201. NET_RC_MGC_ALREADY_INITIALIZED,
  202. NET_RC_MGC_INVALID_USER_HANDLE,
  203. NET_RC_MGC_INVALID_LENGTH,
  204. NET_RC_MGC_INVALID_DOMAIN,
  205. NET_RC_MGC_TOO_MUCH_IN_USE,
  206. NET_RC_MGC_NOT_YOUR_BUFFER,
  207. NET_RC_MGC_LIST_FAIL,
  208. NET_RC_MGC_NOT_CONNECTED,
  209. NET_RC_MGC_NOT_SUPPORTED,
  210. NET_RC_MGC_NOT_INITIALIZED,
  211. NET_RC_MGC_INIT_FAIL,
  212. NET_RC_MGC_DOMAIN_IN_USE,
  213. NET_RC_MGC_NOT_ATTACHED,
  214. NET_RC_MGC_INVALID_CONN_HANDLE,
  215. NET_RC_MGC_INVALID_UP_DOWN_PARM,
  216. NET_RC_MGC_INVALID_REMOTE_ADDRESS,
  217. NET_RC_MGC_CALL_FAILED
  218. };
  219. //
  220. // Results
  221. //
  222. typedef TSHR_UINT16 NET_RESULT;
  223. enum
  224. {
  225. NET_RESULT_OK = 0,
  226. NET_RESULT_NOK,
  227. NET_RESULT_CHANNEL_UNAVAILABLE,
  228. NET_RESULT_DOMAIN_UNAVAILABLE,
  229. NET_RESULT_REJECTED,
  230. NET_RESULT_TOKEN_ALREADY_GRABBED,
  231. NET_RESULT_TOKEN_NOT_OWNED,
  232. NET_RESULT_NOT_SPECIFIED,
  233. NET_RESULT_UNKNOWN,
  234. NET_RESULT_USER_REJECTED
  235. };
  236. //
  237. // Reaons
  238. //
  239. typedef enum
  240. {
  241. NET_REASON_DOMAIN_DISCONNECTED = 1,
  242. NET_REASON_DOMAIN_UNAVAILABLE,
  243. NET_REASON_TOKEN_NONEXISTENT,
  244. NET_REASON_USER_REQUESTED,
  245. NET_REASON_CHANNEL_UNAVAILABLE,
  246. NET_REASON_UNKNOWN
  247. }
  248. NET_REASON;
  249. //
  250. // Events
  251. //
  252. enum
  253. {
  254. NET_EVENT_USER_ATTACH = NET_BASE_EVENT,
  255. NET_EVENT_USER_DETACH,
  256. NET_EVENT_CHANNEL_JOIN,
  257. NET_EVENT_CHANNEL_LEAVE,
  258. NET_EVENT_TOKEN_GRAB,
  259. NET_EVENT_TOKEN_INHIBIT,
  260. NET_EVENT_DATA_RECEIVED,
  261. NET_FEEDBACK,
  262. NET_FLOW,
  263. NET_MG_SCHEDULE,
  264. NET_MG_WATCHDOG
  265. };
  266. //
  267. // FOR MCS USERS (ALL APPS, INCLUDING CALL MANAGER)
  268. //
  269. // state->| 0 | 1 | 2 | 3 | 4 | 5
  270. // |CTRLR |CTRLR |CTLR |CTLR |CTLR |CTLR
  271. // |state |state 2,|state2, |state2, |state 3, |state 3
  272. // | 0/1 |user not|user |user |user |user
  273. // verb/event | |attached|pending |attached |attached |pending
  274. // | |......|........|........|..........|.........|.........
  275. // V | | | | | |
  276. // _get_buffer | X | X | X | - | ** | X
  277. // _free_buffer | X | X | X | - | - | -
  278. // _realloc_bfr | X | X | X | - | - | -
  279. // _attach_user | X | ->2 | X | X | X | X
  280. // _detach_user | X | X | X | ->1 | ->0 | X
  281. // _channel_join | X | X | X | - | X | X
  282. // _channel_leave | X | X | X | - | - | X
  283. // _send_data | X | X | X | - | X | X
  284. // | | | | | |
  285. // _STOP_CONTRLR* | | ->0 | ->5 | ->4 | |
  286. // | | | | | |
  287. // _ATTACH_CNF OK | | | ->3 | | | ->4
  288. // _ATTACH_CNF FAIL| | | ->1 | | | ->0
  289. // _DETACH_IND-SELF| | | ->1 | ->1 | ->0 |
  290. // _DETACH_IND-othr| | | | - | - |
  291. // _JOIN_CONFIRM | | | | - | - |
  292. // _LEAVE_INDICAT | | | | - | - |
  293. // _SEND_INDICAT | | | | - | - |
  294. // =======================================================================
  295. //
  296. // NOTES ** when the controller is STOPPING the NET_GetBuffer
  297. // verb is valid but always returns a NULL buffer (no memory)
  298. //
  299. // * the STOP_CONTROLLER event is internally generated, and is
  300. // not seen across the API. It is generated when the controller
  301. // issues the NET_StopController verb and causes the state change
  302. // (to state 0, 4 or 5) such that the NET_AttachUser,
  303. // ChannelJoin and NET_SendData verbs are rejected.
  304. //
  305. //
  306. //
  307. //
  308. // Priorities
  309. //
  310. #define NET_INVALID_PRIORITY ((NET_PRIORITY)-1)
  311. enum
  312. {
  313. NET_TOP_PRIORITY = 0,
  314. NET_HIGH_PRIORITY,
  315. NET_MEDIUM_PRIORITY,
  316. NET_LOW_PRIORITY,
  317. NET_NUM_PRIORITIES
  318. };
  319. //
  320. // SFR6025: This flag is or-ed with the priority bit to indicate to the MCS
  321. // glue that it should send data on all channels.
  322. //
  323. //
  324. // FOR OBMAN ONLY -- REMOVE IN NM 4.0
  325. //
  326. #define NET_SEND_ALL_PRIORITIES 0x8000
  327. #define NET_ALL_REMOTES ((NET_UID)1)
  328. #define NET_INVALID_DOMAIN_ID (0xFFFFFFFF)
  329. #define NET_UNUSED_IDMCS 1
  330. typedef TSHR_UINT16 NET_UID; // MCS user IDs
  331. typedef TSHR_UINT16 NET_CHANNEL_ID; // MCS channel IDs
  332. typedef TSHR_UINT16 NET_TOKEN_ID; // MCS token IDs
  333. typedef TSHR_UINT16 NET_PRIORITY; // MCS priorities
  334. //
  335. // Forward decls of MGC structures
  336. //
  337. typedef struct tagMG_BUFFER * PMG_BUFFER;
  338. typedef struct tagMG_CLIENT * PMG_CLIENT;
  339. //
  340. // Flow control structure - This contains the target latency (in mS) and
  341. // stream size (in bytes) for each User Attachment
  342. // lonchanc: used by S20, MG, and OM.
  343. //
  344. typedef struct tag_NET_FLOW_CONTROL
  345. {
  346. UINT latency[NET_NUM_PRIORITIES];
  347. UINT streamSize[NET_NUM_PRIORITIES];
  348. }
  349. NET_FLOW_CONTROL, * PNET_FLOW_CONTROL;
  350. //
  351. // NET_EV_JOIN_CONFIRM and NET_EV_JOIN_CONFIRM_BY_KEY
  352. // join_channel confirm:
  353. // lonchanc: used by S20, MG, and OM.
  354. //
  355. typedef struct tagNET_JOIN_CNF_EVENT
  356. {
  357. UINT callID;
  358. NET_RESULT result; // NET_RESULT_USER_ACCEPTED/REJECTED
  359. TSHR_UINT16 pad1;
  360. NET_CHANNEL_ID correlator;
  361. NET_CHANNEL_ID channel;
  362. }
  363. NET_JOIN_CNF_EVENT;
  364. typedef NET_JOIN_CNF_EVENT * PNET_JOIN_CNF_EVENT;
  365. //
  366. // NET_EV_SEND_INDICATION
  367. // send data indication: see MG_SendData()
  368. // Despite its name, this event indicates that data has been RECEIVED!
  369. // lonchanc: used by MG and S20
  370. //
  371. typedef struct tag_NET_SEND_IND_EVENT
  372. {
  373. UINT callID;
  374. NET_PRIORITY priority;
  375. NET_CHANNEL_ID channel;
  376. UINT lengthOfData;
  377. LPBYTE data_ptr; // Pointer to the real data.
  378. }
  379. NET_SEND_IND_EVENT;
  380. typedef NET_SEND_IND_EVENT * PNET_SEND_IND_EVENT;
  381. //
  382. // MGC, FLOW CONTROL
  383. //
  384. //
  385. // MG tasks
  386. //
  387. #define MGTASK_FIRST 0
  388. typedef enum
  389. {
  390. MGTASK_OM = MGTASK_FIRST,
  391. MGTASK_DCS,
  392. MGTASK_MAX
  393. }
  394. MGTASK;
  395. //
  396. // Buffer types
  397. //
  398. enum
  399. {
  400. MG_TX_BUFFER = 1,
  401. MG_RX_BUFFER,
  402. MG_EV_BUFFER,
  403. MG_TX_PING,
  404. MG_TX_PONG,
  405. MG_TX_PANG,
  406. MG_RQ_CHANNEL_JOIN,
  407. MG_RQ_CHANNEL_JOIN_BY_KEY,
  408. MG_RQ_CHANNEL_LEAVE,
  409. MG_RQ_TOKEN_GRAB,
  410. MG_RQ_TOKEN_INHIBIT,
  411. MG_RQ_TOKEN_RELEASE
  412. };
  413. //
  414. // Period of watchdog timer to detect lost connections
  415. //
  416. #define MG_TIMER_PERIOD 1000
  417. //
  418. // MG priorities:
  419. //
  420. #define MG_HIGH_PRIORITY NET_HIGH_PRIORITY
  421. #define MG_MEDIUM_PRIORITY NET_MEDIUM_PRIORITY
  422. #define MG_LOW_PRIORITY NET_LOW_PRIORITY
  423. #define MG_PRIORITY_HIGHEST MG_HIGH_PRIORITY
  424. #define MG_PRIORITY_LOWEST MG_LOW_PRIORITY
  425. #define MG_NUM_PRIORITIES (MG_PRIORITY_LOWEST - MG_PRIORITY_HIGHEST + 1)
  426. //
  427. // MCS priority validation.
  428. // Priorities are contiguous numbers in the range NET_PRIORITY_HIGHEST..
  429. // NETPRIORITY_LOWEST. Priorities supplied to MG may also have the
  430. // NET_SEND_ALL_PRIORITIES flag set. So, to validate a priority:
  431. // - knock off the NET_SEND_ALL_PRIORITIES flag to give the raw priority
  432. // - set the valid raw prioririty to
  433. // NET_PRIORITY_HIGHEST if the raw priority is less than ...ITY_HIGHEST
  434. // NET_PRIORITY_LOWEST if the raw priority is more than ...ITY_LOWEST
  435. // the raw priority if it is in the valid range
  436. // - add the original ...ALL_PRIORITIES flag to the valid raw priority
  437. //
  438. #define MG_VALID_PRIORITY(p) \
  439. ((((p)&~NET_SEND_ALL_PRIORITIES)<MG_HIGH_PRIORITY)? \
  440. (MG_HIGH_PRIORITY|((p)&NET_SEND_ALL_PRIORITIES)): \
  441. (((p)&~NET_SEND_ALL_PRIORITIES)>MG_LOW_PRIORITY)? \
  442. (MG_LOW_PRIORITY|((p)&NET_SEND_ALL_PRIORITIES)): \
  443. (p))
  444. //
  445. //
  446. // The initial stream size setting may appear high, but it is set so that
  447. // in a LAN scenario we do not require the app to place a lot of forward
  448. // pressure on the pipe before it opens up. In a non-LAN scenario we may
  449. // not do enough spoiling to start with, but in actual fact DCS tends
  450. // to send less data than this limit anyway, so we should reduce it
  451. // quite quickly without flooding the buffers.
  452. //
  453. #define FLO_INIT_STREAMSIZE 8000
  454. #define FLO_MIN_STREAMSIZE 500
  455. #define FLO_MAX_STREAMSIZE 256000
  456. #define FLO_MIN_PINGTIME 100
  457. #define FLO_INIT_PINGTIME 1000
  458. //
  459. // This is the max number of bytes that can be allocated per stream if a
  460. // pong has not been received (i.e. FC is not operational).
  461. //
  462. #define FLO_MAX_PRE_FC_ALLOC 16000
  463. //
  464. // This is the max number of pkts outstanding before we apply back
  465. // pressure:
  466. //
  467. #define FLO_MAX_RCV_PACKETS 5
  468. //
  469. // This is the max number of pkts outstanding before we get worried about
  470. // creep:
  471. //
  472. #define FLO_MAX_RCV_PKTS_CREEP 250
  473. //
  474. // The maximum number of flow controlled streams.
  475. //
  476. #define FLO_MAX_STREAMS 128
  477. #define FLO_NOT_CONTROLLED FLO_MAX_STREAMS
  478. //
  479. // STRUCTURE : FLO_STREAM_DATA
  480. //
  481. // DESCRIPTION:
  482. //
  483. // This structure holds all the static data for a flow control stream
  484. //
  485. // FIELDS:
  486. //
  487. // channel
  488. // priority
  489. // pingValue - Next ping value to be sent on the pipe
  490. // eventNeeded - We need to wake up the app because we have rejected
  491. // a buffer allocation request
  492. // backlog - the allowable backlog in mS bejond which we apply
  493. // back pressure
  494. // pingNeeded - Send a ping at the next opportunity
  495. // pingTime - Minimum time, in mS, between each ping
  496. // gotPong - Indicates we have received a pong from some remote
  497. // party and so flow control can commence
  498. // lastPingTime - Time for last ping, in timer ticks
  499. // nextPingTime - Time for next ping, in timer ticks
  500. // lastDenialTime - Previous time (in ticks) that we started denying
  501. // buffer requests
  502. // curDenialTime - Time in ticks that we most recently started denying
  503. // buffer requests
  504. // DC_ABSMaxBytesInPipe
  505. // - Absolute maximum buffer allocation for this stream
  506. // maxBytesInPipe - Current buffer allocation limit
  507. // bytesInPipe - Current amount of data outstanding on this stream.
  508. // This includes data currently waiting to be sent.
  509. // users - Base for queue of User correlators
  510. // bytesAllocated - The current amount of data in the glue for this
  511. // stream which has not been sent. This is different
  512. // to bytesInPipe which is the amount of unacknowledged
  513. // data in this stream.
  514. //
  515. //
  516. typedef struct tagFLO_STREAM_DATA
  517. {
  518. STRUCTURE_STAMP
  519. NET_CHANNEL_ID channel;
  520. WORD gotPong:1;
  521. WORD eventNeeded:1;
  522. WORD pingNeeded:1;
  523. UINT priority;
  524. UINT pingValue;
  525. UINT backlog;
  526. UINT pingTime;
  527. UINT lastPingTime;
  528. UINT nextPingTime;
  529. UINT lastDenialTime;
  530. UINT curDenialTime;
  531. UINT DC_ABSMaxBytesInPipe;
  532. UINT maxBytesInPipe;
  533. UINT bytesInPipe;
  534. UINT bytesAllocated;
  535. BASEDLIST users;
  536. }
  537. FLO_STREAM_DATA;
  538. typedef FLO_STREAM_DATA * PFLO_STREAM_DATA;
  539. void __inline ValidateFLOStr(PFLO_STREAM_DATA pStr)
  540. {
  541. if (pStr != NULL)
  542. {
  543. ASSERT(!IsBadWritePtr(pStr, sizeof(FLO_STREAM_DATA)));
  544. }
  545. }
  546. //
  547. // The FLO callback function
  548. //
  549. // A wakeup type callback indicates that a back pressure situation has
  550. // been relieved.
  551. //
  552. // A buffermod callback indicates this as well, but also indicates that
  553. // the buffer size for controlling flow on the designated channel/priority
  554. // has changed.
  555. //
  556. #define FLO_WAKEUP 1
  557. #define FLO_BUFFERMOD 2
  558. typedef void (* PFLOCALLBACK)(PMG_CLIENT pmgClient,
  559. UINT callbackType,
  560. UINT priority,
  561. UINT newBufferSize);
  562. //
  563. // STRUCTURE : FLO_STATIC_DATA
  564. //
  565. // DESCRIPTION:
  566. //
  567. // This structure holds all the instance specific static data for the
  568. // Flow Control DLL
  569. //
  570. // FIELDS:
  571. //
  572. // numStreams - ID of the highest allocated stream
  573. // rsvd - reserved
  574. // callback - pointer to a callback function
  575. // pStrData - an array of FLO_STREAM_DATA pointers.
  576. //
  577. //
  578. typedef struct FLO_STATIC_DATA
  579. {
  580. UINT numStreams;
  581. PFLOCALLBACK callBack;
  582. PFLO_STREAM_DATA pStrData[FLO_MAX_STREAMS];
  583. }
  584. FLO_STATIC_DATA;
  585. typedef FLO_STATIC_DATA * PFLO_STATIC_DATA;
  586. typedef struct FLO_USER
  587. {
  588. BASEDLIST list;
  589. STRUCTURE_STAMP
  590. WORD userID;
  591. WORD lastPongRcvd;
  592. WORD pongNeeded;
  593. BYTE sendPongID;
  594. BYTE pad1;
  595. UINT sentPongTime; // Time we actually sent the pong
  596. WORD rxPackets; // Count of packets outstanding
  597. WORD gotPong; // Indicates this user has ponged
  598. // and they are permitted to apply
  599. // back pressure to our sends
  600. UINT numPongs; // total number of pongs from user
  601. UINT pongDelay; // total latency across pongs
  602. }
  603. FLO_USER;
  604. typedef FLO_USER * PFLO_USER;
  605. void __inline ValidateFLOUser(PFLO_USER pFloUser)
  606. {
  607. ASSERT(!IsBadWritePtr(pFloUser, sizeof(FLO_USER)));
  608. }
  609. //
  610. // Maximum wait time before assuming a user is offline
  611. // We need to keep this high until the apps become "well behaved" and
  612. // respond to the flow control buffer size recommendations.
  613. //
  614. #define FLO_MAX_WAIT_TIME 20000
  615. //
  616. //
  617. // Client Control Block
  618. //
  619. //
  620. typedef struct tagMG_CLIENT
  621. {
  622. PUT_CLIENT putTask;
  623. PCM_CLIENT pcmClient;
  624. BASEDLIST buffers; // list of children buffers
  625. BASEDLIST pendChain; // Chain of pending request from client
  626. BASEDLIST joinChain; // Chain of pending join-by-key requests
  627. //
  628. // MCS user attachment info
  629. //
  630. PIMCSSap m_piMCSSap; // user interface ptr returned by MCS
  631. UserID userIDMCS; // user ID returned by MCS
  632. FLO_STATIC_DATA flo; // flow control structure
  633. WORD eventProcReg:1;
  634. WORD lowEventProcReg:1;
  635. WORD exitProcReg:1;
  636. WORD joinPending:1; // Is there a channel join outstanding ?
  637. WORD userAttached:1;
  638. WORD joinNextCorr;
  639. NET_FLOW_CONTROL flowControl; // flow control latency/backlog params
  640. }
  641. MG_CLIENT;
  642. void __inline ValidateMGClient(PMG_CLIENT pmgc)
  643. {
  644. ASSERT(!IsBadWritePtr(pmgc, sizeof(MG_CLIENT)));
  645. ValidateUTClient(pmgc->putTask);
  646. }
  647. typedef struct tagMG_INT_PKT_HEADER
  648. {
  649. TSHR_UINT16 useCount; // The use count of this packet. This
  650. // is required for sending the same
  651. // data on multiple channels.
  652. TSHR_NET_PKT_HEADER header;
  653. }
  654. MG_INT_PKT_HEADER;
  655. typedef MG_INT_PKT_HEADER * PMG_INT_PKT_HEADER;
  656. //
  657. //
  658. // Buffer Control Block
  659. //
  660. //
  661. typedef struct tagMG_BUFFER
  662. {
  663. STRUCTURE_STAMP
  664. UINT type;
  665. BASEDLIST pendChain; // Used when the buffer is added to the
  666. BASEDLIST clientChain;
  667. PMG_INT_PKT_HEADER pPktHeader; // Pointer to MCS control info
  668. void * pDataBuffer; // Pointer passed to apps
  669. UINT length; // length of the associated packet
  670. ChannelID channelId; // Send destination, or token grab req
  671. ChannelID channelKey;
  672. UserID senderId;
  673. NET_PRIORITY priority;
  674. BOOL eventPosted;
  675. UINT work; // work field for misc use
  676. PFLO_STREAM_DATA pStr; // Pointer to the FC stream
  677. }
  678. MG_BUFFER;
  679. void __inline ValidateMGBuffer(PMG_BUFFER pmgb)
  680. {
  681. ASSERT(!IsBadWritePtr(pmgb, sizeof(MG_BUFFER)));
  682. }
  683. //
  684. //
  685. //
  686. // MACROS
  687. //
  688. //
  689. //
  690. //
  691. // MCS priority validation.
  692. // Priorities are contiguous numbers in the range NET_PRIORITY_HIGHEST..
  693. // NET_PRIORITY_LOWEST. Priorities supplied to MG may also have the
  694. // NET_SEND_ALL_PRIORITIES flag set. So, to validate a priority:
  695. // - knock off the NET_SEND_ALL_PRIORITIES flag to give the raw priority
  696. // - set the valid raw priority to
  697. // - NET_PRIORITY_HIGHEST if the raw priority is less than ...ITY_HIGHEST
  698. // - NET_PRIORITY_LOWEST if the raw priority is more than ...ITY_LOWEST
  699. // - the raw priority if it is in the valid range
  700. // - add the original ...ALL_PRIORITIES flag to the valid raw priority.
  701. //
  702. //
  703. //
  704. //
  705. // FUNCTION PROTOTYPES
  706. //
  707. //
  708. //
  709. //
  710. //
  711. // MGLongStopHandler(...)
  712. //
  713. // This function is registered as a low priority event handler for each
  714. // client. It catches any unprocessed network events and frees any
  715. // associated memory.
  716. //
  717. //
  718. BOOL CALLBACK MGLongStopHandler(LPVOID pmgClient, UINT event, UINT_PTR param1, UINT_PTR param2);
  719. //
  720. //
  721. // MGEventHandler(...)
  722. //
  723. // This function is registered as a high priority event handler for the
  724. // processing of MG_ChannelJoinByKey, MCS request handling and scheduling.
  725. // It catches NET channel join confirm and CMS register channel confirm
  726. // events, and massages them into the correct return events for the app.
  727. // It queues requests coming from the app context into the glue context
  728. // and schedules queued requests.
  729. //
  730. //
  731. BOOL CALLBACK MGEventHandler(LPVOID pmgClient, UINT event, UINT_PTR param1, UINT_PTR param2);
  732. //
  733. UINT MGHandleSendInd(PMG_CLIENT pmgClient, PSendData pSendInfo);
  734. //
  735. //
  736. // MGNewBuffer(...)
  737. // NewTxBuffer(...)
  738. // NewRxBuffer(...)
  739. // FreeBuffer(...)
  740. //
  741. // The New function allocates and initialises a buffer , allocates buffer
  742. // memory of the specified size and type and adds the to the client's
  743. // list of buffer s.
  744. //
  745. // The Tx version performs flow control on the buffer allocation request
  746. // The Rx version just allocates a receive buffer
  747. //
  748. // The Free function discards a buffer , discards the associated buffer
  749. // memory, decrements the client's count of memory in use and removes the
  750. // from the client's list of buffer s.
  751. //
  752. //
  753. void MGNewCorrelator(PMG_CLIENT ppmgClient, WORD * pCorrelator);
  754. UINT MGNewBuffer(PMG_CLIENT pmgClient, UINT typeOfBuffer,
  755. PMG_BUFFER * ppBuffer);
  756. UINT MGNewDataBuffer(PMG_CLIENT pmgClient,
  757. UINT typeOfBuffer,
  758. UINT sizeOfBuffer,
  759. PMG_BUFFER * ppBuffer);
  760. UINT MGNewTxBuffer(PMG_CLIENT pmgClient,
  761. NET_PRIORITY priority,
  762. NET_CHANNEL_ID channel,
  763. UINT sizeOfBuffer,
  764. PMG_BUFFER * ppBuffer);
  765. UINT MGNewRxBuffer(PMG_CLIENT pmgClient,
  766. NET_PRIORITY priority,
  767. NET_CHANNEL_ID channel,
  768. NET_CHANNEL_ID senderID,
  769. PMG_BUFFER * ppBuffer);
  770. void MGFreeBuffer(PMG_CLIENT pmgClient, PMG_BUFFER * ppBuffer);
  771. //
  772. //
  773. // MGProcessDomainWatchdog(...)
  774. //
  775. // Handle domain watchdog timer ticks.
  776. //
  777. //
  778. void MGProcessDomainWatchdog(PMG_CLIENT pmgClient);
  779. void MGProcessEndFlow(PMG_CLIENT pmgClient, ChannelID channel);
  780. UINT MGPostJoinConfirm(PMG_CLIENT pmgClient,
  781. NET_RESULT result,
  782. NET_CHANNEL_ID channel,
  783. NET_CHANNEL_ID correlator);
  784. NET_RESULT TranslateResult(WORD Result);
  785. //
  786. //
  787. // MGFLOCallBack(...)
  788. //
  789. // Callback poked by flow control to trigger the app to retry buffer
  790. // requests thet were previously rejected
  791. //
  792. //
  793. void MGFLOCallBack(PMG_CLIENT pmgClient,
  794. UINT callbackType,
  795. UINT priority,
  796. UINT newBufferSize);
  797. //
  798. //
  799. // MGProcessPendingQueue(...)
  800. //
  801. // Called whenever MG wants to try and execute pending requests. Requests
  802. // are queued because they may fail for a transient reason, such as MCS
  803. // buffer shortage.
  804. //
  805. //
  806. UINT MGProcessPendingQueue(PMG_CLIENT pmgClient);
  807. BOOL MG_Register(MGTASK task, PMG_CLIENT * pmgClient, PUT_CLIENT putTask);
  808. void MG_Deregister(PMG_CLIENT * ppmgClient);
  809. void CALLBACK MGExitProc(LPVOID uData);
  810. UINT MG_Attach(PMG_CLIENT pmgClient, UINT callID, PNET_FLOW_CONTROL pFlowControl);
  811. void MG_Detach(PMG_CLIENT pmgClient);
  812. void MGDetach(PMG_CLIENT pmgClient);
  813. UINT MG_ChannelJoin(PMG_CLIENT pmgClient, NET_CHANNEL_ID * pCorrelator,
  814. NET_CHANNEL_ID channel);
  815. UINT MG_ChannelJoinByKey(PMG_CLIENT pmgClient,
  816. NET_CHANNEL_ID * pCorrelator,
  817. WORD channelKey);
  818. void MG_ChannelLeave(PMG_CLIENT pmgClient, NET_CHANNEL_ID channel);
  819. UINT MG_GetBuffer(PMG_CLIENT pmgClient, UINT length,
  820. NET_PRIORITY priority,
  821. NET_CHANNEL_ID channel,
  822. void ** buffer);
  823. void MG_FreeBuffer(PMG_CLIENT pmgClient,
  824. void ** buffer);
  825. UINT MG_SendData(PMG_CLIENT pmgClient,
  826. NET_PRIORITY priority,
  827. NET_CHANNEL_ID channel,
  828. UINT length,
  829. void ** data);
  830. UINT MG_TokenGrab(PMG_CLIENT pmgClient, NET_TOKEN_ID token);
  831. UINT MG_TokenInhibit(PMG_CLIENT pmgClient, NET_TOKEN_ID token);
  832. void MG_FlowControlStart(PMG_CLIENT pmgClient,
  833. NET_CHANNEL_ID channel,
  834. NET_PRIORITY priority,
  835. UINT backlog,
  836. UINT maxBytesOutstanding);
  837. //
  838. // API FUNCTION: FLO_UserTerm
  839. //
  840. // DESCRIPTION:
  841. //
  842. // Called by an application to end flow control on all the channels
  843. // associated with a particular user.
  844. //
  845. // PARAMETERS:
  846. //
  847. // pUser - MCS Glue User attachment
  848. //
  849. // RETURNS: Nothing.
  850. //
  851. //
  852. void FLO_UserTerm(PMG_CLIENT pmgClient);
  853. //
  854. // API FUNCTION: FLO_StartControl
  855. //
  856. // DESCRIPTION:
  857. //
  858. // The application calls this function whenever it wants a data stream to
  859. // be flow controlled
  860. //
  861. // PARAMETERS:
  862. //
  863. // pUser - MCS Glue User attachment
  864. // channel - channel id of channel to be flow controlled
  865. // priority - priority of the stream to be controlled
  866. // backlog - the maximum backlog (in mS) allowed for this stream
  867. // maxBytesOutstanding - the maximum number of bytes allowed in the stream
  868. // irrespective of the backlog. 0 = use default of
  869. // 64 KBytes
  870. //
  871. // RETURNS:
  872. // None
  873. //
  874. //
  875. void FLO_StartControl(PMG_CLIENT pmgClient,
  876. NET_CHANNEL_ID channel,
  877. UINT priority,
  878. UINT backlog,
  879. UINT maxBytesOutstanding);
  880. void FLO_EndControl
  881. (
  882. PMG_CLIENT pmgClient,
  883. NET_CHANNEL_ID channel,
  884. UINT priority
  885. );
  886. //
  887. // API FUNCTION: FLO_AllocSend
  888. //
  889. // DESCRIPTION:
  890. //
  891. // The application is requesting a buffer in order to send a packet. This
  892. // may trigger a flow control packet in advance of the application packet.
  893. // Flow control may choose to reject the packet with NET_OUT_OF_RESOURCE in
  894. // which case the application must reschedule the allocation at a ater
  895. // date. To assist the rescheduling, if ever a send is rejected then flow
  896. // control will call the application callback to trigger the reschedule.
  897. //
  898. // PARAMETERS:
  899. //
  900. // pUser - MCS Glue User attachment
  901. // priority - The priority for this buffer
  902. // channel - The channnel on which to send the packet
  903. // size - The size of the packet
  904. // ppStr - Pointer to the pointer to the FC stream. This is a
  905. // return value.
  906. //
  907. //
  908. UINT FLO_AllocSend(PMG_CLIENT pmgClient,
  909. UINT priority,
  910. NET_CHANNEL_ID channel,
  911. UINT size,
  912. PFLO_STREAM_DATA * ppStr);
  913. //
  914. // API FUNCTION: FLO_ReallocSend
  915. //
  916. // DESCRIPTION:
  917. //
  918. // The application has requested that the glue send a packet, but the
  919. // packet contains less data than originally requested.
  920. // Flow control heuristics get thrown out unless we logically free the
  921. // unused portion of the packet for reuse for other allocations.
  922. // If we didn't do this then we might see a 8K packet, for example,
  923. // complete in 1 second because the app only put 1K of data in it.
  924. //
  925. // PARAMETERS:
  926. //
  927. // pUser - MCS Glue User attachment
  928. // pStr - The flow control stream to be corrected
  929. // size - The size of the packet that has been unused
  930. //
  931. // RETURNS:
  932. //
  933. // None
  934. //
  935. //
  936. void FLO_ReallocSend(PMG_CLIENT pmgClient,
  937. PFLO_STREAM_DATA pStr,
  938. UINT size);
  939. //
  940. // API FUNCTION: FLO_DecrementAlloc
  941. //
  942. // DESCRIPTION:
  943. //
  944. // This function decrements the bytesAllocated count for a given stream.
  945. // It is called whenever a packet is sent or removed from the send chain.
  946. //
  947. // PARAMETERS:
  948. //
  949. // pStr - The flow control stream to be decremented
  950. // size - The size to decrement
  951. //
  952. // RETURNS:
  953. //
  954. // None
  955. //
  956. //
  957. void FLO_DecrementAlloc( PFLO_STREAM_DATA pStr,
  958. UINT size);
  959. //
  960. // API FUNCTION: FLO_ReceivedPacket
  961. //
  962. // DESCRIPTION:
  963. //
  964. // Upon receipt of a flow control packet the MCS glue calls this function
  965. // and then ignores the packet.
  966. //
  967. // PARAMETERS:
  968. //
  969. // pUser - MCS Glue User attachment
  970. // pPkt - pointer to the packet, for FLO to process
  971. //
  972. // RETURNS:
  973. //
  974. // None
  975. //
  976. //
  977. void FLO_ReceivedPacket(PMG_CLIENT pmgClient, PTSHR_FLO_CONTROL pPkt);
  978. //
  979. // API FUNCTION: FLO_AllocReceive
  980. //
  981. // DESCRIPTION:
  982. //
  983. // Called to indicate that a receive buffer is now in use by the application
  984. //
  985. // PARAMETERS:
  986. //
  987. // pmg - pointer to the glue user attacgment cb
  988. // priority
  989. // channel
  990. // size - size of the buffer just been allocated
  991. //
  992. // RETURNS:
  993. //
  994. // None
  995. //
  996. //
  997. void FLO_AllocReceive(PMG_CLIENT pmgClient,
  998. UINT priority,
  999. NET_CHANNEL_ID channel,
  1000. UINT senderID);
  1001. //
  1002. // API FUNCTION: FLO_FreeReceive
  1003. //
  1004. // DESCRIPTION:
  1005. //
  1006. // Called to indicate that a receive buffer has ben handed back by the
  1007. // application.
  1008. //
  1009. // PARAMETERS:
  1010. //
  1011. // pmg - pointer to the glue user attachment cb
  1012. // priority
  1013. // channel
  1014. // size - size of the buffer just been freed
  1015. //
  1016. // RETURNS:
  1017. //
  1018. // None
  1019. //
  1020. //
  1021. void FLO_FreeReceive(PMG_CLIENT pmgClient,
  1022. NET_PRIORITY priority,
  1023. NET_CHANNEL_ID channel,
  1024. UINT senderID);
  1025. //
  1026. // API FUNCTION: FLO_CheckUsers
  1027. //
  1028. // DESCRIPTION:
  1029. //
  1030. // Called periodically by each client to allow flow control to determine if
  1031. // remote users have left the channel
  1032. //
  1033. // PARAMETERS:
  1034. //
  1035. // pmg - pointer to the user
  1036. //
  1037. // RETURNS:
  1038. //
  1039. // None
  1040. //
  1041. //
  1042. void FLO_CheckUsers(PMG_CLIENT pmgClient);
  1043. //
  1044. // FLOGetStream()
  1045. //
  1046. UINT FLOGetStream(PMG_CLIENT pmgClient, NET_CHANNEL_ID channel, UINT priority,
  1047. PFLO_STREAM_DATA * ppStr);
  1048. void FLOStreamEndControl(PMG_CLIENT pmgClient, UINT stream);
  1049. void FLOPing(PMG_CLIENT pmgClient, UINT stream, UINT curtime);
  1050. void FLOPang(PMG_CLIENT pmgClient, UINT stream, UINT userID);
  1051. void FLOPong(PMG_CLIENT pmgClient, UINT stream, UINT userID, UINT pongID);
  1052. //
  1053. // API FUNCTION: FLOAddUser
  1054. //
  1055. // DESCRIPTION:
  1056. //
  1057. // Add a user to a flow controlled stream
  1058. //
  1059. // PARAMETERS:
  1060. //
  1061. // userID - ID of the new user (single member channel ID)
  1062. // pStr - pointer to the stream to receive the new user
  1063. //
  1064. // RETURNS:
  1065. //
  1066. // None
  1067. //
  1068. //
  1069. PFLO_USER FLOAddUser(UINT userID,
  1070. PFLO_STREAM_DATA pStr);
  1071. //
  1072. // API FUNCTION: FLO_RemoveUser
  1073. //
  1074. // DESCRIPTION:
  1075. //
  1076. // Remove a user from a flow controlled stream
  1077. //
  1078. // PARAMETERS:
  1079. //
  1080. // pmg - pointer to the MCS glue user
  1081. // userID - ID of the bad user (single member channel ID)
  1082. //
  1083. // RETURNS:
  1084. //
  1085. // None
  1086. //
  1087. //
  1088. void FLO_RemoveUser(PMG_CLIENT pmgClient, UINT userID);
  1089. //
  1090. // FUNCTION: MGCallback
  1091. //
  1092. // DESCRIPTION:
  1093. //
  1094. // This function is the callback passed to MCS. The glue layer receives
  1095. // all communication from MCS via this function. It converts MCS messages
  1096. // into DC-Groupware events and posts them to the relevant client(s).
  1097. //
  1098. //
  1099. void CALLBACK MGCallback( unsigned int mcsMessageType,
  1100. unsigned long eventData,
  1101. unsigned long pUser );
  1102. #endif // _H_AST120
  1103.