aboutsummaryrefslogtreecommitdiff
path: root/src/libparsec/include/net_stream.h
blob: 3b5bd3ea7fc98ba728c13b3ae0a89a6e5f087ef5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
 * PARSEC HEADER: net_stream.h
 */

#ifndef _NET_STREAM_H_
#define _NET_STREAM_H_

// forward decls --------------------------------------------------------------
//
class E_REList;

// history buffer for received message ids to filter out duplicates -----------
//
#define MSGID_HISTORY_SIZE 64

// packet loss meter ----------------------------------------------------------
//
#define PACKET_LOSS_METER_LENGTH	100						// horizontal size

// flag to indicate that the packet does NOT include a reliable payload -------
//
#define NO_RELIABLE					0

// max. # of reliable RE lists to buffer --------------------------------------
//
#define MAX_NUM_RELIABLE_BACKLOG 256

// sructure of FIFO entries ---------------------------------------------------
//
struct StreamFIFOEntry_s {
	E_REList* m_pREList;
	refframe_t  m_Timeout;
	int			m_nRetransmitCount;

	StreamFIFOEntry_s() :
		m_pREList( NULL )
	{
		Reset();
	}
	
	void Reset();
	void InitEntry( E_REList* pREList );
};

// maintaining of message-ids -------------------------------------------------
//
class NET_Stream {
protected:

	dword		Out_MessageId;				// next out message
	dword		Out_ReliableMessageId;		// next reliable out message

	dword		I_ACK_MessageId;			// message I ACK from YOU
	dword		I_ACK_ReliableMessageId;	// reliable message I ACK from YOU

	dword		YOU_ACK_MessageId;			// message YOU ACK from ME
	dword		YOU_ACK_ReliableMessageId;	// reliable message YOU ACK from ME

	dword		m_MessageId_ReliableWasSent;

	bool_t		m_EnableReliable;
	int			m_nPeerID;
	int			m_nSenderID;

	bool_t		m_bIsConnected;

	// FIXME: STATS
	char		packet_graph_recv[ PACKET_LOSS_METER_LENGTH ];
	char		packet_graph_send[ PACKET_LOSS_METER_LENGTH ];

	int			message_id_history[ MSGID_HISTORY_SIZE ];

	int					m_nFIFO_WritePos;
	int					m_nFIFO_ReadPos;
	StreamFIFOEntry_s	m_FIFOEntries[ MAX_NUM_RELIABLE_BACKLOG ];

	refframe_t  m_ReliableRetransmit_Frames;	// timeout to retransmit reliable packets ( based on RTT ( see Stevens ) )

protected:
	int _FIFO_GetNextWritePos()		{ return ( m_nFIFO_WritePos + 1 ) % MAX_NUM_RELIABLE_BACKLOG; }
	int _FIFO_GetNextReadPos()		{ return ( m_nFIFO_ReadPos  + 1 ) % MAX_NUM_RELIABLE_BACKLOG; }

	// update the timeout for a specific FIFO entry
	void _FIFO_UpdateTimeOut( StreamFIFOEntry_s* pEntry );

public:

	// default ctor
	NET_Stream();

	// set the peer ID this stream is connected to
	void SetPeerID( int nPeerID ) { m_nPeerID = nPeerID; }

	// set the sender ID of this stream
	void SetSenderID( int nSenderID ) { m_nSenderID = nSenderID; }

	// reset the stream to defaults
	void Reset();

	// set the stream to connected mode ( accepts non datagrams )
	void SetConnected();

	// set whether we enable reliable for this stream
	void SetEnableReliable( bool_t enable ) { m_EnableReliable = enable; }

	// check whether a reliable message was already ACK
	bool_t IsReliableACK( dword dwMessage ) { return YOU_ACK_ReliableMessageId >= dwMessage; } 

	// check whether a message was already ACK
	bool_t IsACK( dword dwMessage ) { return YOU_ACK_MessageId >= dwMessage; } 

	// return the last message id we got an ACK for
	dword GetLastACKMessageId() { return YOU_ACK_MessageId; }

	// return the message# of the last packet received
	dword GetLastInPacket() { return I_ACK_MessageId; }

	// check input packet for rejection and maintain ACKs correctly
	int InPacket( NetPacket_GMSV* gamepacket_GMSV );

	// fill in fields in outgoing packet
	void OutPacket( NetPacket_GMSV* gamepacket_GMSV, int reliable = FALSE  );

	// check whether to filter out a duplicate packet
	int FilterPacketDuplicate( int messageid );

	// log packet loss statistics 
	void LogPacketLossStats( int numpackets, int packetok, int incoming );

	// append a RE list to the FIFO 
	int AppendToReliableFIFO( E_REList* pREList );

	// retrieve the next reliable RE list from FIFO to send
	E_REList* GetNextReliableToSend();

	// reset all reliable handling
	void FlushReliableBuffer();

	// return the next outgoing message id
	dword GetNextOutMessageId() { return Out_MessageId; }

	friend class NET_PacketDriver;
};


#endif // _NET_STREAM_H_