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.

631 lines
25 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: DnProt.h
  6. * Content: This file contains structure definitions for the Direct Net protocol
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 11/06/98 ejs Created
  12. * 07/01/2000 masonb Assumed Ownership
  13. *
  14. ****************************************************************************/
  15. #ifndef _DNPROT_INCLUDED_
  16. #define _DNPROT_INCLUDED_
  17. #define VOL volatile
  18. /*
  19. ** Internal Constants
  20. */
  21. #define DNP_MAX_HEADER_SIZE 36
  22. #define MAX_BUFFERS_IN_FRAME 12 // This is somewhat arbitrary. If someone wants more we can deal
  23. #define MAX_RETRIES 10
  24. #define MAX_RETRY_INTERVAL 5000 // clamp each single retry iteration at 5 seconds
  25. #define SMALL_BUFFER_SIZE (1024 * 2)
  26. #define MEDIUM_BUFFER_SIZE (1024 * 4)
  27. #define LARGE_BUFFER_SIZE (1024 * 16)
  28. /*
  29. ** Signatures for data structures
  30. */
  31. #define PD_SIGN ' SDP' // Protocol Data
  32. #define SPD_SIGN ' DPS' // Service Provider Descriptor
  33. #define EPD_SIGN ' DPE' // End Point Descriptor
  34. #define MSD_SIGN ' DSM' // Message Descriptor
  35. #define FMD_SIGN ' DMF' // Frame Descriptor
  36. #define RCD_SIGN ' DCR' // Receive Descriptor
  37. /*
  38. ** Internal Data Structures
  39. **
  40. */
  41. typedef struct protocoldata ProtocolData, *PProtocolData;
  42. typedef struct spdesc SPD, *PSPD;
  43. typedef struct endpointdesc EPD, *PEPD;
  44. typedef struct checkptdata CHKPT, *PCHKPT;
  45. typedef struct messagedesc MSD, *PMSD;
  46. typedef struct framedesc FMD, *PFMD;
  47. typedef struct recvdesc RCD, *PRCD;
  48. typedef struct _DN_PROTOCOL_INTERFACE_VTBL DN_PROTOCOL_INTERFACE_VTBL, *PDN_PROTOCOL_INTERFACE_VTBL;
  49. /*
  50. ** Protocol Data
  51. **
  52. ** This structure contains all of the global state information for the
  53. ** operating protocol. It is grouped into a structure for (in)convenience
  54. ** against the unlikely possibility that we ever need to run multiple instances
  55. ** out of the same code.
  56. */
  57. #define PFLAGS_PROTOCOL_INITIALIZED 0x00000001
  58. struct protocoldata
  59. {
  60. ULONG ulProtocolFlags; // State info about DN protocol
  61. PVOID Parent; // Direct Play Object
  62. DWORD Sign;
  63. LONG lSPActiveCount; // Number of SPs currently bound to protocol
  64. DWORD dwNextSessID; // ID to assign to next session request
  65. DWORD tIdleThreshhold; // How long will we allow a link to be idle before Checkpointing
  66. DWORD dwConnectTimeout; // These two parameter control new connection commands
  67. DWORD dwConnectRetries;
  68. PDN_PROTOCOL_INTERFACE_VTBL pfVtbl; // Table of indication entry points in CORE
  69. #ifdef DEBUG
  70. // For Debugging we will track the total number of receives outstanding in the higher layers
  71. // at all times.
  72. long ThreadsInReceive;
  73. long BuffersInReceive;
  74. #endif
  75. };
  76. /*
  77. ** Service Provider Descriptor
  78. **
  79. ** This structure describes a Service Provider that we are bound to. It
  80. ** contains at a minimum the vector table to call the SP, and the SPID that
  81. ** is combined with player IDs to make external DPIDs. The SPID should also
  82. ** be the index in the SPTable where this descriptor lives.
  83. **
  84. ** We will have one send thread per service provider, so the thread handle
  85. ** and its wait-event will live in this structure too.
  86. **
  87. ** Lower Edge Protocol Object
  88. **
  89. ** We will also use the SPD as the COM Object given to SP for our lower edge
  90. ** interface. This means that our Lower Vector Table must be the first field in
  91. ** this structure, and ref count must be second.
  92. */
  93. #define SPFLAGS_SEND_THREAD_SCHEDULED 0x0001 // SP has scheduled a thread to service command frames
  94. #define SPFLAGS_TERMINATING 0x4000 // SP is being removed
  95. struct spdesc
  96. {
  97. IDP8SPCallbackVtbl *LowerEdgeVtable; // table used by this SP to call into us, MUST BE FIRST!!!
  98. UINT Sign;
  99. ULONG ulSPFlags; // Flags describing this service provider
  100. IDP8ServiceProvider *IISPIntf; // ptr to SP Object
  101. PProtocolData pPData; // Ptr to owning protocol object
  102. UINT uiFrameLength; // Frame size available to us
  103. UINT uiUserFrameLength; // Frame size available to application
  104. UINT uiLinkSpeed; // Local link speed in BPS
  105. CBilink blSendQueue; // List of wire-ready packets to transmit over this SP
  106. CBilink blPendingQueue; // List of packets owned by SP - Shares Lock w/SendQ
  107. CBilink blEPDActiveList; // List of in use End Point Descriptors for this SP
  108. PVOID SendHandle; // Handle of send thread
  109. UINT SendHandleUnique; // Same
  110. DNCRITICAL_SECTION SPLock; // Guard access to sendQ
  111. #ifdef DEBUG
  112. CBilink blMessageList; // List of in use Message Descriptors
  113. #endif
  114. };
  115. /*
  116. ** End Point Descriptor
  117. **
  118. ** An 'EPD' describes a Direct Network instance that we can communicate with.
  119. ** This structure includes all session related information, statistics, queues, etc.
  120. ** It will manage any of the three types of service simultaneously.
  121. */
  122. #define EPFLAGS_END_POINT_IN_USE 0x0001 // This EndPoint is allocated
  123. // We are always in exactly one of these 4 states
  124. #define EPFLAGS_STATE_DORMANT 0x0002 // Connection protocol has not yet run
  125. #define EPFLAGS_STATE_CONNECTING 0x0004 // Attempting to establish reliable link
  126. #define EPFLAGS_STATE_CONNECTED 0x0008 // Reliable link established
  127. #define EPFLAGS_STATE_TERMINATING 0x0010 // This end point is being closed down
  128. #define EPFLAGS_SP_DISCONNECTED 0x0020 // Set when the SP has called ProcessSPDisconnect
  129. #define EPFLAGS_IN_RECEIVE_COMPLETE 0x0040 // A thread is running in ReceiveComplete routine
  130. #define EPFLAGS_LINKED_TO_LISTEN 0x0080 // During CONNECT this EPD is linked into the Listen MSD's queue
  131. #define EPFLAGS_LINK_STABLE 0x0100 // We think we have found the best current transmit parameters
  132. #define EPFLAGS_STREAM_UNBLOCKED 0x0200 // Reliable traffic is stopped (window or throttle)
  133. #define EPFLAGS_SDATA_READY 0x0400 // Reliable traffic in the pipe
  134. #define EPFLAGS_IN_PIPELINE 0x0800 // Indicates that EPD is in the SPD pipeline queue
  135. #define EPFLAGS_CHECKPOINT_INIT 0x1000 // Need to send a check point packet
  136. #define EPFLAGS_DELAYED_SENDMASK 0x2000 // unacked check point on wire
  137. #define EPFLAGS_DELAYED_NACK 0x4000 // Need to send masks for missing receives
  138. #define EPFLAGS_DELAY_ACKNOWLEDGE 0x8000 // We are waiting for back-traffic before sending ACK frame
  139. #define EPFLAGS_KEEPALIVE_RUNNING 0x00010000 // Checkpoint is running
  140. #define EPFLAGS_SENT_DISCONNECT 0x00020000 // We have sent a DISCONNECT and are waiting for confirm
  141. #define EPFLAGS_RECEIVED_DISCONNECT 0x00040000 // We have received a DISCONNECT and will send confirm when done sending
  142. #define EPFLAGS_DISCONNECT_ACKED 0x00080000 // We sent a DISCONNECT and it has been confirmed
  143. #define EPFLAGS_COMPLETE_SENDS 0x00100000 // There are Reliable MSDs waiting to be called back
  144. #define EPFLAGS_FILLED_WINDOW_BYTE 0x00200000 // Filled Byte-Based send window
  145. #define EPFLAGS_FILLED_WINDOW_FRAME 0x00400000 // We have filled the frame-based SendWindow at least once during last period
  146. #define EPFLAGS_USE_POLL_DELAY 0x00800000 // We have two-way traffic, so wait 5ms before responding to POLL frame
  147. #define EPFLAGS_ACKED_DISCONNECT 0x01000000 // Partner sent a DISCONNECT and we have confirmed it
  148. #define EPFLAGS_RETRIES_QUEUED 0x02000000 // Frames are waiting for retransmission
  149. #define EPFLAGS_THROTTLED_BACK 0x04000000 // temporary throttle is engaged to relieve congestion
  150. #define EPFLAGS_LINK_FROZEN 0x08000000 // DEBUG FLAG -- Do not run dynamic algorithm on this link
  151. #define EPFLAGS_INDICATED_DISCONNECT 0x10000000 // Ensure that we onlly call CORE once to indicate disconnection
  152. #define EPFLAGS_TESTING_GROWTH 0x20000000 // We are currently taking a growth sample
  153. #define EPFLAGS_PROCESSING_DISCONNECT 0x40000000 // Prevents multiple threads from completing a disconnect
  154. #define EPFLAGS_KILLED 0x80000000 // Someone has removed the 'base' reference to make this go away
  155. // We dont want to let this happen twice...
  156. #define MAX_RECEIVE_RANGE 64 // largest # of frames we will retain past a missing frame
  157. #define MAX_FRAME_OFFSET (MAX_RECEIVE_RANGE - 1)
  158. #define INITIAL_STATIC_PERIOD (10 * 1000) // How long does link remain static after finding set-point.
  159. // This value will double every time link finds the same set-point.
  160. struct endpointdesc
  161. {
  162. HANDLE hEndPt; // Together with SP index uniquely defines an End Point we can reach
  163. LONG lRefCnt; // Reference count
  164. UINT Sign; // Signature to validate data structure
  165. PSPD pSPD; // specifies the SP on which this remote instance lives
  166. ULONG VOL ulEPFlags; // End Point Flags
  167. PVOID Context; // Context value returned with all indications
  168. PMSD pCommand; // Connect or Listen command with which this end point was created or Disconnect cmd
  169. CBilink blActiveLinkage; // linkage for SPD list of active EndPoints
  170. CBilink blSPLinkage; // linkage to listen command during connect
  171. CBilink blChkPtQueue; // linkage for active CheckPoints
  172. UINT uiUserFrameLength; // Largest frame we can transmit
  173. UINT uiRTT; // Current RTT -- Integer portion
  174. UINT fpRTT; // Fixed Point 16.16 RTT
  175. UINT uiDropCount; // localized packet drop count (recent drops)
  176. DWORD tThrottleTime; // Timestamp when last Checking occured
  177. UINT uiThrottleEvents; // count of temporary backoffs for all reasons
  178. UINT uiAdaptAlgCount; // Acknowledge count remaining before running adaptive algorithm
  179. DWORD tLastPacket; // Timestamp when last packet arrived
  180. UINT uiWindowFilled; // Count of times we fill the send window
  181. UINT uiPeriodAcksBytes; // frames acked since change in tuning
  182. UINT uiPeriodXmitTime; // time link has been transmitting since change in tuning
  183. UINT uiPeriodRateB;
  184. UINT uiPeakRateB; // Largest sample we ever measure
  185. // While we are in DYNAMIC state we want to remember stats from our previous xmit parameters, at this
  186. // point that means RTT and AvgSendRate. This lets us compare the measurements at our new rate so we can
  187. // ensure that thruput increases with sendrate, and that RTT is not growing out of proportion.
  188. //
  189. // If either thru-put stops improving or RTT grows unreasonably then we can plateau our xmit parameters
  190. // and transition to STABLE state.
  191. UINT uiLastRateB;
  192. UINT uiLastBytesAcked;
  193. DWORD tLastThruPutSample;
  194. // Connection State - State of reliable connection
  195. //
  196. // Send Queuing is getting somewhat complex. Let me spell it out in Anglish.
  197. //
  198. // blXPriSendQ is the list of MSDs awaiting shipment (and being shipped)
  199. // CurrentSend pts to the MSD we are currently pulling frames out of.
  200. // CurrentFrame pts to the next FMD that we will put on the wire.
  201. // blSendWindow is a bilinked list of transmitted but unacknowledged frames. This list may span multi MSDs
  202. //
  203. // WindowF is our current MAX window size expressed in frames
  204. // WindowB is our current MAX window size expressed in bytes
  205. //
  206. // UnAckedFrames is the count of unacknowledged frames on the wire (actual window size)
  207. // UnAckedBytes is the count of unacknowledged bytes on the wire
  208. DWORD uiQueuedMessageCount; // How many MSDs are waiting on all three send queues
  209. CBilink blHighPriSendQ; // These are now mixed Reliable and Datagram traffic
  210. CBilink blNormPriSendQ;
  211. CBilink blLowPriSendQ;
  212. CBilink blCompleteSendList; // Reliable messages completed and awaiting indication to user
  213. DWORD dwSessID; // Session ID so we can detect re-started links
  214. PMSD pCurrentSend; // Head of queue is lead edge of window. window can span multiple frames.
  215. PFMD pCurrentFrame; // frame currently transmitting. this will be trailing edge of window
  216. CBilink blSendWindow;
  217. CBilink blRetryQueue; // Packets waiting for re-transmission
  218. // Lost Packet Lists
  219. //
  220. // When we need to retry a packet and we discover that it is not reliable, then we need to inform partner
  221. // that he can stop waiting for the data. We will piggyback this info on another frame if possible
  222. // Current Transmit Parameters:
  223. UINT uiWindowF; // window size (frames)
  224. UINT uiWindowB; // window size (bytes)
  225. UINT uiWindowBIndex; // index (scaler) for byte-based window
  226. UINT uiUnackedFrames; // outstanding frame count
  227. UINT uiUnackedBytes; // outstanding byte count
  228. UINT uiBurstGap; // number of ms to wait between bursts
  229. INT iBurstCredit; // Either credit or deficit from previous Transmit Burst
  230. // Last Known Good Transmit Parameters -- Values which we believe are safe...
  231. UINT uiGoodWindowF;
  232. UINT uiGoodWindowBI;
  233. UINT uiGoodBurstGap;
  234. UINT uiGoodRTT;
  235. UINT uiRestoreWindowF;
  236. UINT uiRestoreWindowBI;
  237. UINT uiRestoreBurstGap;
  238. DWORD tLastDelta; // Timestamp when we last modified xmit parms
  239. // Reliable Link State
  240. BYTE VOL bNextSend; // Next serial number to assign
  241. BYTE VOL bNextReceive; // Next frame serial we expect to receive
  242. // Group BYTE members for good packing
  243. BYTE VOL bNextMsgID; // Next ID for datagram frames ! NOW USED FOR CFRAMES ONLY
  244. BYTE bLastDataRetry; // Retry count on frame N(R) - 1
  245. // The following fields are all for tracking reliable receives
  246. // The next two fields allow us to return more state with every ACK packet. Since each ack explicitly
  247. // names one frame, the highest in-sequenced packet received so far, we want to remember the arrival time
  248. // and the Retry count of this packet so we can report it in each ACK. It will be the transmitter's
  249. // responsibility to ensure that a single data-point never gets processed more then once, skewing our calcs.
  250. DWORD tLastDataFrame; // Timestamp from the arrival of N(R) - 1
  251. ULONG ulReceiveMask; // mask representing first 32 frames in our rcv window
  252. ULONG ulReceiveMask2; // second 32 frames in our window
  253. DWORD tReceiveMaskDelta; // timestamp when a new bit was last set in ReceiveMask (full 64-bit mask)
  254. ULONG ulSendMask; // mask representing unreliable send frames that have timed out and need
  255. ULONG ulSendMask2; // to be reported to receiver as missing.
  256. PRCD pNewMessage; // singly linked list of message elements
  257. PRCD pNewTail; // tail pointer for singly linked list of msg elements
  258. CBilink blOddFrameList; // Out Of Order frames
  259. CBilink blCompleteList; // List of MESSAGES ready to be indicated
  260. UINT uiCompleteMsgCount; // Count of messages on the CompleteList
  261. PVOID SendTimer; // Timer for next send-burst opportunity
  262. UINT SendTimerUnique;
  263. UINT uiRetryCount; // This count is used during CONNECT processing
  264. UINT uiRetryTimeout; // Current T1 timer value
  265. PVOID ConnectTimer; // We used to share RetryTimer for connecting but we hit some race conditions when timers
  266. UINT ConnectTimerUnique; // would fire as connections completed. This will close these windows at cost of 8 bytes/EPD
  267. PVOID RetryTimer; // window to receive Ack
  268. UINT RetryTimerUnique;
  269. PVOID DelayedAckTimer; // wait for piggyback opportunity before sending Ack
  270. UINT DelayedAckTimerUnique;
  271. PVOID DelayedMaskTimer; // wait for piggyback opportunity before sending
  272. UINT DelayedMaskTimerUnique;
  273. PVOID BGTimer; // Periodic background timer
  274. UINT BGTimerUnique; // serial for background timer
  275. UINT uiBytesAcked;
  276. // Link statistics
  277. //
  278. // All of the following stuff is calculated and stored here for the purpose of reporting in the ConnectionInfo structure
  279. UINT uiMsgSentHigh;
  280. UINT uiMsgSentNorm;
  281. UINT uiMsgSentLow;
  282. UINT uiMsgTOHigh;
  283. UINT uiMsgTONorm;
  284. UINT uiMsgTOLow;
  285. UINT uiMessagesReceived;
  286. UINT uiGuaranteedFramesSent;
  287. UINT uiGuaranteedBytesSent;
  288. UINT uiDatagramFramesSent;
  289. UINT uiDatagramBytesSent;
  290. UINT uiGuaranteedFramesReceived;
  291. UINT uiGuaranteedBytesReceived;
  292. UINT uiDatagramFramesReceived;
  293. UINT uiDatagramBytesReceived;
  294. UINT uiDatagramFramesDropped; // datagram frame we failed to deliver
  295. UINT uiDatagramBytesDropped; // datagram bytes we didnt deliver
  296. UINT uiGuaranteedFramesDropped;
  297. UINT uiGuaranteedBytesDropped;
  298. DNCRITICAL_SECTION EPLock; // Serialize all access to Endpoint
  299. #ifdef DEBUG
  300. UINT uiTotalThrottleEvents;
  301. BYTE bLastDataSeq; // for DEBUG porpoises
  302. CHAR LastPacket[32]; // record last packet received on EPD
  303. #endif
  304. };
  305. /*
  306. ** Check Point Data
  307. **
  308. ** Keeps track of local-end info about a checkpoint in-progress.
  309. */
  310. struct checkptdata
  311. {
  312. CBilink blLinkage; // Linkage for list of CPs on an EndPoint
  313. DWORD tTimestamp; // Local time at start of checkpoint
  314. UCHAR bMsgID; // Msg ID expected in CP response
  315. };
  316. /*
  317. ** Descriptor IDs
  318. **
  319. ** Any Descriptor that may be submitted to an SP as a context must have
  320. ** a field which allows us to determine which structure is returned in a
  321. ** completion call. This field must obviously be in a uniform place in all
  322. ** structures, and could be expanded to be a command specifier as well.
  323. ** Done! Lets call it a command ID.
  324. */
  325. typedef enum CommandID
  326. {
  327. COMMAND_ID_NONE,
  328. COMMAND_ID_SEND_RELIABLE,
  329. COMMAND_ID_SEND_DATAGRAM,
  330. COMMAND_ID_CONNECT,
  331. COMMAND_ID_LISTEN,
  332. COMMAND_ID_ENUM,
  333. COMMAND_ID_ENUMRESP,
  334. COMMAND_ID_DISCONNECT,
  335. COMMAND_ID_DISC_RESPONSE,
  336. COMMAND_ID_CFRAME,
  337. COMMAND_ID_KEEPALIVE,
  338. COMMAND_ID_COPIED_RETRY,
  339. } COMMANDID;
  340. /* Message Descriptor
  341. **
  342. ** An 'MSD' describes a message being sent or received by the protocol. It keeps track
  343. ** of the message elements, tracking which have been sent/received/acknowledged.
  344. */
  345. // Flags ONE field is protected by the MSD->CommandLock
  346. #define MFLAGS_ONE_IN_USE 0x0001
  347. #define MFLAGS_ONE_IN_SERVICE_PROVIDER 0x0002 // This MSD is inside an SP call
  348. #define MFLAGS_ONE_CANCELLED 0x0004 // command was cancelled while owned by SP
  349. #define MFLAGS_ONE_TIMEDOUT 0x0008 // sends only: timed out while event was scheduled
  350. #define MFLAGS_ONE_COMPLETE 0x0010 // connect only: operation is complete and indicated to Core
  351. #ifdef DEBUG
  352. #define MFLAGS_ONE_COMPLETED_TO_CORE 0x4000
  353. #define MFLAGS_ONE_ON_GLOBAL_LIST 0x8000
  354. #endif
  355. // Flags TWO field is protected by the EPD->EPLock
  356. #define MFLAGS_TWO_TRANSMITTING 0x0001
  357. #define MFLAGS_TWO_SEND_COMPLETE 0x0002 // send command completed
  358. #define MFLAGS_TWO_ABORT 0x0004 // Send/Disconnect has been aborted. Do no further processing
  359. #define MFLAGS_TWO_END_OF_STREAM 0x0008 // This MSD is an EOS frame. Could be a user cmd or a response
  360. #define MFLAGS_TWO_KEEPALIVE 0x0010 // This MSD is an empty frame to exercise the reliable engine
  361. #define MFLAGS_TWO_ABORT_WILL_COMPLETE 0x0020 // AbortSendsOnConnection intends to complete this to the core, other functions can clear it
  362. #ifdef DEBUG
  363. #define MFLAGS_TWO_ENQUEUED 0x1000 // This MSD is on one of the EPD SendQs
  364. #endif
  365. struct messagedesc
  366. {
  367. COMMANDID CommandID; // THIS MUST BE FIRST FIELD
  368. LONG lRefCnt; // Reference count
  369. UINT Sign; // Signature
  370. ULONG VOL ulMsgFlags1; // State info serialized by MSD->CommandLock
  371. ULONG VOL ulMsgFlags2; // State info serialized by EPD->EPLock
  372. PEPD pEPD; // Destination End Point
  373. PSPD pSPD; // SP fielding this command
  374. PVOID Context; // User provided context value
  375. ULONG VOL ulSendFlags; // Flags submitted by User in send call
  376. INT iMsgLength; // Total length of user data
  377. UINT VOL uiFrameCount; // Number of frames needed to xmit data, protected by EPLock for reliables
  378. CBilink blFrameList; // List of frames to transport this message, or for a Listen, endpoints that are connecting
  379. CBilink blQLinkage; // linkage for various sendQs
  380. CBilink blSPLinkage; // linkage for SP command list, protected by SP->SPLock
  381. HANDLE hCommand; // handle when submitted to SP (used for connect & listen)
  382. DWORD dwCommandDesc; // Descriptor associated with hCommand
  383. HANDLE hListenEndpoint;
  384. PVOID TimeoutTimer;
  385. UINT TimeoutTimerUnique;
  386. DNCRITICAL_SECTION CommandLock;
  387. #ifdef DEBUG
  388. CCallStack<10> CallStackCoreCompletion;
  389. #endif
  390. };
  391. /*
  392. ** Frame Descriptor
  393. **
  394. ** There are two non-obvious things about the FMD structure. First is that the built-in Buffer Descriptor array
  395. ** has two elements defined in front of it. The first element, Reserved1 and Reserved2 are present to allow the Service
  396. ** Provider to pre-pend a header buffer, and the second element, ImmediateLength and ImmediatePointer are for this
  397. ** protocol to prepend its header. The ImmediatePointer is initialized to point to the ImmediateData field.
  398. **
  399. ** The second thing is that the ulFFlags field is serialized with the ENDPOINTLOCK of the EPD which this frame is linked to.
  400. ** This is good because every time the FFlags fields is modified we have already taken the EPLock already. The exception to this
  401. ** rule is when we are initializing the FMD. In this case the FMD has not been loosed on the world yet so there cannot be any
  402. ** contention for it. We have seperated out the one flag, FRAME_SUBMITTED, into its own BOOL variable because this one is
  403. ** protected by the SP's SPLock, and like the EPLock above, it is already claimed when this flag gets modified.
  404. */
  405. //#define FFLAGS_IN_USE 0x0001
  406. #define FFLAGS_TRANSMITTED 0x0002
  407. #define FFLAGS_END_OF_MESSAGE 0x0004
  408. #define FFLAGS_END_OF_STREAM 0x0008
  409. //#define FFLAGS_FRAME_SUBMITTED 0x0010 // SP Currently owns this frame
  410. #define FFLAGS_RETRY_TIMER_SET 0x0020 // Just what it sounds like
  411. #define FFLAGS_NACK_RETRANSMIT_SENT 0x0040 // We sent a NACK initiated retry.
  412. #define FFLAGS_IN_SEND_WINDOW 0x0080 // This reliable frame has been transmitted and is waiting for Ack
  413. #define FFLAGS_CHECKPOINT 0x0100 // We are asking for a response
  414. //#define FFLAGS_KEEPALIVE 0x0200
  415. //#define FFLAGS_ACKED_BY_MASK 0x0400 // This has been acked out-of-order so its still in the SendWindow
  416. #define FFLAGS_RETRY_QUEUED 0x0800 // Frame currently sitting on the retry queue
  417. //#define FFLAGS_NEW_MESSAGE 0x10000
  418. #define FFLAGS_RELIABLE 0x20000
  419. //#define FFLAGS_SEQUENTIAL 0x40000
  420. #define FFLAGS_FINAL_ACK 0x80000
  421. struct framedesc
  422. {
  423. UINT CommandID; // THIS MUST BE FIRST FIELD to match MSD
  424. LONG lRefCnt; // Reference count
  425. UINT Sign;
  426. UINT uiFrameLength;
  427. ULONG VOL ulFFlags;
  428. BOOL VOL bSubmitted; // Pull out this one flag for protection
  429. PMSD pMSD; // owning message
  430. PEPD pEPD; // owning link; ONLY VALID ON COMMAND FRAMES!
  431. BYTE bPacketFlags;
  432. CBilink blMSDLinkage;
  433. CBilink blQLinkage;
  434. CBilink blWindowLinkage;
  435. UINT uiRetry; // number of times this frame has been transmitted
  436. DWORD tTimestamp[MAX_RETRIES+1]; // timestamp of frame's transmission
  437. SPSENDDATA SendDataBlock; // Block to submit frame to SP
  438. CHAR ImmediateData[DNP_MAX_HEADER_SIZE];
  439. // DO NOT MODIFY LAST FIVE FIELDS IN FRAME STRUCTURE
  440. UINT uiReserved1; // two resv fields are buf..
  441. LPVOID lpReserved2; // ..desc for SP to add header
  442. UINT uiImmediateLength; // These two lines constitute buffer descriptor
  443. LPVOID lpImmediatePointer; // for immediate data (our protocol headers)
  444. BUFFERDESC rgBufferList[MAX_BUFFERS_IN_FRAME]; // KEEP THIS FIELD AT END SO WE CAN ADD BUFFERS DYNAMICALLY
  445. };
  446. /*
  447. ** Receive Descriptor
  448. **
  449. ** This data structure tracks a single buffer received from the network.
  450. ** It may or may not constitute an entire message.
  451. */
  452. typedef enum
  453. {
  454. RBT_SERVICE_PROVIDER_BUFFER,
  455. RBT_PROTOCOL_BUFFER,
  456. RBT_DYNAMIC_BUFFER
  457. } BUFFER_TYPE;
  458. //#define RFLAGS_FRAME_OUT_OF_ORDER 0x0001 // This buffer was received out-of-order
  459. #define RFLAGS_FRAME_INDICATED_NONSEQ 0x0002 // This buffer was indicated out of order, but is still in Out of Order list
  460. //#define RFLAGS_ON_OUT_OF_ORDER_LIST 0x0004 //
  461. //#define RFLAGS_IN_COMPLETE_PROCESS 0x0008
  462. #define RFLAGS_FRAME_LOST 0x0010 // This RCD represents and Unreliable frame that has been lost
  463. struct recvdesc
  464. {
  465. DWORD tTimestamp; // timestamp upon packets arrival
  466. LONG lRefCnt;
  467. UINT Sign; // Signature to identify data structure
  468. UINT uiDataSize; // data in this frame
  469. UINT uiFrameCount; // frames in message
  470. UINT uiMsgSize; // total byte count of message
  471. BYTE bSeq; // Sequence number of this frame
  472. BYTE bFrameFlags; // Flag field from actual frame
  473. BYTE bFrameControl;
  474. PBYTE pbData; // pointer to actual data
  475. UINT ulRFlags; // Receive flags
  476. CBilink blOddFrameLinkage; // BILINKage for queues
  477. CBilink blCompleteLinkage; // 2nd Bilink so RCD can remain in Out Of Order Queue after indication
  478. PRCD pMsgLink; // Single link for frame in message
  479. PSPRECEIVEDBUFFER pRcvBuff; // ptr to SP's receive data structure
  480. };
  481. typedef struct buf BUF, *PBUF;
  482. typedef struct medbuf MEDBUF, *PMEDBUF;
  483. typedef struct bigbuf BIGBUF, *PBIGBUF;
  484. typedef struct dynbuf DYNBUF, *PDYNBUF;
  485. struct buf
  486. {
  487. LPFPOOL Owner; // ptr back to owning pool
  488. BUFFER_TYPE Type; // Identifies this as our buffer or SPs buffer
  489. BYTE data[SMALL_BUFFER_SIZE]; // 2K small buffer for combining multi-frame sends
  490. };
  491. struct medbuf
  492. {
  493. LPFPOOL Owner; // ptr back to owning pool
  494. BUFFER_TYPE Type; // Identifies this as our buffer or SPs buffer
  495. BYTE data[MEDIUM_BUFFER_SIZE]; // 4K mid size buffer
  496. };
  497. struct bigbuf
  498. {
  499. LPFPOOL Owner; // ptr back to owning pool
  500. BUFFER_TYPE Type; // Identifies this as our buffer or SPs buffer
  501. BYTE data[LARGE_BUFFER_SIZE]; // ARBITRARY SIZE OF MAX SEND (16K)
  502. };
  503. struct dynbuf
  504. {
  505. LPFPOOL Owner; // ptr back to owning pool
  506. BUFFER_TYPE Type; // Identifies this as our buffer or SPs buffer
  507. };
  508. #endif