windows-nt/Source/XPSP1/NT/multimedia/media/dplayx/dplay/protocol/protocol.h
2020-09-26 16:20:57 +08:00

336 lines
9.6 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
PROTOCOL.H
Abstract:
Another Reliable Protocol - CPP implementation
Author:
Aaron Ogus (aarono)
Environment:
Win32/COM
Revision History:
Date Author Description
====== ====== ============================================================
12/10/96 aarono Original
2/11/97 aarono Removed channel from header, now rides in body of 1st packet.
along with the length field.
3/12/97 aarono channel is gone, not relevant to transport protocol, can be
prepended to messages that want it. Length field is gone,
not required.
6/6/98 aarono Turn on throttling and windowing - fix some definitions
--*/
#ifndef _PROTOCOL_H_
#define _PROTOCOL_H_
#pragma pack(push,1)
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;
//
// ARP - Another Reliable Protocol - Packet Definitions
//
// Terminology
//
// message - an arbitrary sized chunk of data
// to be sent from one computer to a another over
// the available media.
//
// packet - a piece of a message broken down
// for the media, including protocol information
// to allow the message to be reconstructed at
// the other end.
//
// frame - an instance of a packet.
//
// Assumptions:
//
// All values on the wire are little endian.
//
// This protocol allows packets to arrive out of
// order but is optimized for the in-order case.
//
#define EXT 0x80 /* EXTENSION BIT */
#define BIG 0x40 /* BIG HEADERS (FAST MEDIA) */
#define CMD 0x20 /* COMMAND FRAME */
#define STA 0x10
#define EOM 0x08 /* END OF MESSAGE */
#define SAK 0x04 /* SEND ME AN ACK */
#define ACK 0x02 /* ACKNOWLEDGE FRAME */
#define RLY 0x01 /* RELIABLE FRAME */
// Shifts used in small extended fields.
#define nNACK_MSK 0x60
#define nNACK_SHIFT 5
#define CMD_MSK 0x1F
#define IDMSK (pCmdInfo->IDMSK)
#define SEQMSK (pCmdInfo->SEQMSK)
// Note: abort packets contain serial numbers but no sequence numbers.
// the nACK field can be used to abort many messages at the same
// time. (using ABORT2 or ABORT3). Also just the messageid is
// provided in the abort case.
typedef struct _Packet1 { // simple small -I- frame
byte flags;
byte messageid;
byte sequence;
byte serial;
byte data[0];
} Packet1, *pPacket1;
typedef struct _Packet2 { // simple large -I- frame
byte flags;
word messageid;
word sequence;
byte serial;
byte data[0];
} Packet2, *pPacket2;
typedef struct {
byte flag1; // header flags
byte flag2; // extended flags for small hdr/command for lrg
byte flag3; // nNACK for large hdr.
byte pad; // make it a dword.
} FLAGS, *pFLAGS;
// different frame components that may be part of any
// frame. type 1 - small frames, type 2 - large frames
//
// ACKNOWLEDGE information
//
typedef struct _ACK1 {
byte messageid;
byte sequence;
byte serial;
dword bytes; // bytes received from remote
dword time; // time when bytes received was this value
} ACK1, *pACK1;
typedef struct _ACK2 {
word messageid;
word sequence;
byte serial;
dword bytes; // bytes received from remote
dword time; // remote time when bytes receive was this value
} ACK2, *pACK2;
//
// ABORT
//
typedef struct _ABT1 {
byte messageid;
byte sequence;
} ABT1, *pABT1;
typedef struct _ABT2 {
word messageid;
word sequence;
} ABT2, *pABT2;
//
// MISSING packet information
//
typedef struct _NACK1 {
byte messageid;
byte sequence;
dword bytes; // bytes received from remote
dword time; // remote time when bytes received was this value
byte mask[0];
} NACK1, *pNACK1;
typedef struct _NACK2 {
word messageid;
word sequence;
dword bytes; // bytes received from remote
dword time; // remote time when bytes received was this value
byte mask[0];
} NACK2, *pNACK2;
//
// COMMAND information (including -I- frames)
//
typedef struct _CMD1 {
byte messageid;
byte sequence;
byte serial;
byte data[0];
} CMD1, *pCMD1;
typedef struct _CMD2 {
word messageid;
word sequence;
byte serial;
byte data[0];
} CMD2, *pCMD2;
#pragma pack(pop)
#endif
/*==============================================================================
Protocol Operational description
================================
Characteristics:
----------------
The ARP protocol provides for reliable and non-reliable packet delivery
over an existing non-reliable (datagram) protocol. It is assumed that
packet length information and addressing information is carried by the
datagram protocol and these fields are therefore ambiguous and excluded
from ARP.
ARP is optimized to provide a minimum of overhead in the case of low
bandwidth links. The overhead per-packet is 3 bytes.
ARP's default command is the delivery of I frames. This avoids the need
for a command field in the protocol header for the most common frame type.
ARP does segmentation and reassembly on large datagram messages. This
allows for datagram delivery of messages larger than 1 packet.
ARP does a hybrid of windowing with selective NACK of missing packets,
allowing optimal operation on both good and weak links, regardless
of latency.
ARP assigns each frame a serial number that is used in the ACK responses.
This allows the protocol to keep up to date latency information as well
as recognize which packet is being responded to in a retry situation.
The serial number allows the protocol to adjust timeouts reliably.
ARP allows multiple messages to be sent concurrently. Having multiple
messages prevents the system from blocking on retry from a single packet
transmission failure. It also allows better use of available bandwidth
since the protocol does not wait for the ACK from one message before
sending the next.
{FUTURE: What about packet sub-allocation? Bandwidth allocation?}
Header Description:
-------------------
Flags:
+-----+-----+-----+-----+-----+-----+-----+-----+
| EXT | BIG | CMD | STA | EOM | SAK | ACK | RLY |
+-----+-----+-----+-----+-----+-----+-----+-----+
Extended Flags:
Small:
+-----+-----+-----+-----+-----+-----+-----+-----+
| EXT | nNACK | COMMAND |
+-----+-----+-----+-----+-----+-----+-----+-----+
Big:
+-----+-----------------------------------------+
| EXT | COMMAND | (only if CMD & BIG set)
+-----+-----------------------------------------+
| EXT | nNACK |
+-----+-----------------------------------------+
Flags:
STA - start of a message.
EOM - this bit is set when the packet is the last packet of a message
ACK - used to signify that this is an ACK packet, otherwise a COMMAND
- if nACK != 0, the ACK is informative only. i.e - tells client
last ACKed frame that instigated the nACK to update latency
information. An ACK without nACK indicates all frames up
to the ACK frame were successfully received. Any bit set
in the nACK mask indicates a missing frame, any 0 bit indicates
a frame that was successfully received.
SAK - when this bit is set, the receiver must send an ACK packet
for this packet.
RLY - indicates that this message is being delivered reliably.
BIG - when this bit is set, the packets are in large format TYPE 3.
CMD - command frame. When this bit is set, the packet contains a
command. If there is no COMMAND field it is an I frame.
EXT - when the BIG bit is not set, indicates extended flags are present.
Extended Flags:
nNACK - if non-zero indicates presence of nNACK byte masks. The NACK
field consists of a sequence number followed by nNACK byte masks.
Each bit in the mask represents a packet after the packet specified
in the sequence number. The packet in the sequence number is also
being NACKed.
Command:
The command field is used to specify protocol subcommands. The following
are defined. Commands larger than 15 require BIG packets. Commands that
require responses include the response in the ACK packet. All protocol
commands are unreliable. Each command has its own messageid sequence and
serial. This means commands can be of arbitrary length. The Response
to a command is also a command.
0000 0 - Default - I Frame or ACK/NACK (nACK != 0)
0001 1 - ABORT
0010 2 - Ping - send packet back to sender.
0011 3 - Ping Response - a message being returned.
0100 4 - GetTime - Get the tick count.
0101 5 - Get Time Response - Response to the Get Time request.
0110 6 - SetTime - Set the tick count.
0111 7 - Set Time Response - Response to the Set Time request.
Rule for processing EXT bits. If a byte in the flags has the high
bit set, there is one more byte. Ignore any bits beyond what you know
how to process.
Sample Packets:
===============
Time setting algorithm?
Bandwidth Calculations?
Scheduling?
Window Size?
Interpacket wait?
Send Queue Management?
Command for selective NACK.
RLY bit separates 2 streams - reliable/datagram. For piggyback
ACK this means reliable piggyback ACKs are only on reliable streams
and datagram piggyback ACKs are only on non-reliable streams.
==============================================================================*/
#ifdef __DPMESS_INCLUDED__
#define MAX_SEND_HEADER (sizeof(Packet2)+sizeof(MSG_PROTOCOL))
// leave space for a 128 bit NACK message, this is the maximum window we ever allow
#define MAX_SYS_HEADER (sizeof(NACK2)+(128/8)+sizeof(MSG_PROTOCOL))
#endif