This repository was archived by the owner on Feb 27, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 511
/
Copy pathCONNECT.H
343 lines (320 loc) · 17.4 KB
/
CONNECT.H
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
/*
** Command & Conquer(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* $Header: F:\projects\c&c\vcs\code\connect.h_v 1.12 16 Oct 1995 16:46:04 JOE_BOSTIC $ */
/***************************************************************************
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
***************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : CONNECT.H *
* *
* Programmer : Bill Randolph *
* *
* Start Date : December 19, 1994 *
* *
* Last Update : April 1, 1995 [BR] *
* *
*-------------------------------------------------------------------------*
* *
* DESCRIPTION: *
* This class represents a single "connection" with another system. It's *
* a pure virtual base class that acts as a framework for other classes. *
* *
* This class contains a CommQueueClass member, which stores received *
* & transmitted packets. The ConnectionClass has virtual functions to *
* handle adding packets to the queue, reading them from the queue, *
* a Send routine for actually sending data, and a Receive_Packet function *
* which is used to tell the connection that a new packet has come in. *
* *
* The virtual Service routine will handle all ACK & Retry logic for *
* communicating between this system & another. Thus, any class derived *
* from this class must provide the basic ACK/Retry logic. *
* *
* THE HEADER: *
* The Connection Classes prefix every packet sent with a header that's *
* local to this class. The header contains a "Magic Number" which should *
* be unique for each product, and Packet "Code", which will tell the *
* receiving end if this is DATA, or an ACK packet, and a packet ID, which *
* is a unique numerical ID for this packet (useful for detecting resends).*
* The header is stored with each packet in the send & receive Queues; *
* it's removed before it's passed back to the application, via *
* Get_Packet() *
* *
* THE CONNECTION MANAGER: *
* It is assumed that there will be a "Connection Manager" class which *
* will handle parsing incoming packets; it will then tell the connection *
* that new packets have come in, and the connection will process them in *
* whatever way it needs to for its protocol (check for resends, handle *
* ACK packets, etc). The job of the connection manager is to parse *
* incoming packets & distribute them to the connections that need to *
* store them (for multi-connection protocols). *
* *
* NOTES ON ACK/RETRY: *
* The packet's ID is used to check for re-sends. The ID is set to the *
* Queue's total Send Count; if the receiving system checks this value, *
* and it's less than that system's Receive Count, this is a resend. *
* (ie packet 0 will be the 1st packet sent, since the Send Queue's count *
* is 0 when it's sent; as soon as it's received, the Receive Count goes *
* up to 1, and an ID of 0 then means a resend.) This scheme keeps the *
* application from seeing the same packet twice. All the Connection *
* Manager has to do is mark the resent packet as non-ACK'd. Of course, *
* the Manager doesn't have to use this value at all. *
* *
* Both DATA_ACK packets and DATA_NOACK packets must go through the Send *
* Queue when "sent", so that the SendTotal value for this system *
* will still match the ReceiveTotal value for the other system; this is *
* why a NOACK packet can't just be sent immediately; it must go through *
* the queue. *
* *
* If the protocol being used already guarantees delivery of packets, *
* no ACK is required for the packets. In this case, the connection *
* class for this protocol can overload the Service routine to avoid *
* sending ACK packets, or the Connection Manager can just mark the *
* packet as ACK'd when it adds it to the Receive Queue for the connection.*
* *
* Derived classes must provide: *
* - Init a version of Init that gives the connection *
* access to any hardware-specific values it needs *
* Must chain to the parent's Init routine. *
* - Send_Packet adds the CommHeaderType header, adds the packet *
* to the out-going queue *
* - Receive_Packet processes incoming ACK packets, detects resends,*
* adds new packets to the in-coming queue *
* - Get_Packet reads the next-available packet from the *
* receive queue *
* - Send the hardware-dependent data-sending routine *
* - Service_Send_Queue services the send queue; handles re-sends, *
* detects when outgoing packets have been ACK'd; *
* cleans out the queue of old packets *
* - Service_Receive_Queue services the receive queue; handles sending *
* ACK's for new or re-sent packets; cleans out *
* the queue of old packets *
* *
* Any other routines can be overloaded as the derived class needs. *
* *
* CLASS HIERARCHY: *
* ConnectionClass *
* | *
* | *
* -------------------------------------- *
* | | *
* | | *
* SequencedConnClass NonSequencedConnClass *
* | | *
* | | *
* IPXConnClass ------------------------ *
* | | | *
* | | | *
* IPXGlobalConnClass NullModemConnClass ModemConnClass *
* *
* *
* ConnectionClass: *
* Abstract base class. *
* Provides: Queue for sent/recv'd packets *
* PacketBuf for preparing packets *
* Timeout variables *
* Service() routine *
* *
* SequencedConnClass: *
* Abstract base class *
* Provides: * "Sequenced" ACK/Retry logic, in Service_Send_Queue() & *
* Service_Receive_Queue() routines *
* * Send_Packet(): adds header to packet, adds it to Queue *
* * Receive_Packet(): adds incoming packet to receive Queue, *
* handles incoming ACK's & resends *
* * Get_Packet(): gets packet from the receive queue *
* *
* NonSequencedConnClass: *
* Abstract base class *
* Provides: * "Non-Sequenced" ACK/Retry logic, in Service_Send_Queue() *
* & Service_Receive_Queue() routines *
* * Send_Packet(): adds header to packet, adds it to Queue *
* * Receive_Packet(): adds incoming packet to receive Queue, *
* handles incoming ACK's & resends *
* * Get_Packet(): gets packet from the receive queue *
* *
* IPXConnClass: *
* Provides: * Hardware-dependent IPX interface routines, which allow *
* Service_Send_Queue() & Service_Receive_Queue() to do *
* their job *
* * Ability to associate an IPX Address, a numerical ID, and *
* a character-string Name with a connection *
* Inherits: * Sequenced ACK/Retry logic, Service routines, Queue & *
* PacketBuf, timeout variables *
* *
* IPXGlobalConnClass: *
* Special type of IPX Connection; supports receiving packets from *
* multiple systems at once, and sending packets via Broadcast or *
* to a specific address. *
* Provides: * Specialized Receive_Packet() routine, which handles *
* receiving packets from multiple systems *
* * Specialized Send_Packet() & Get_Packet() routines, *
* which pass IPX address of destination through to *
* the application, giving the application control over *
* whether the packet will be Broadcast or sent to a *
* specific destination (embeds destination address within *
* the packet itself) *
* * Specialized Send routine, which extracts the destination *
* address from the packet *
* Inherits: * Sequenced ACK/Retry logic, Service routines, Queue & *
* PacketBuf, timeout variables, IPX-specific routines *
* *
* NullModemConnClass: *
* Provides: * Hardware-dependent Serial-communication routines, which *
* allow Service_Send_Queue() & Service_Receive_Queue() to *
* do their job *
* Inherits: * Non-Sequenced ACK/Retry logic, Service routines, Queue & *
* PacketBuf, timeout variables *
* *
* ModemConnClass: *
* Provides: * Hardware-dependent Modem-communication routines, which *
* allow Service_Send_Queue() & Service_Receive_Queue() to *
* do their job *
* Inherits: * Non-Sequenced ACK/Retry logic, Service routines, Queue & *
* PacketBuf, timeout variables *
* *
* So, do ya think this header is long enough, or what? *
* *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CONNECTION_H
#define CONNECTION_H
#define CONN_DEBUG 0
/*
********************************** Defines **********************************
*/
/*---------------------------------------------------------------------------
This structure is the header prefixed to any packet sent by the application.
MagicNumber: This is a number unique to the application; it's up to the
Receive_Packet routine to check this value, to be sure we're
not getting data from some other product. This value should
be unique for each application.
Code: This will be one of the below-defined codes.
PacketID: This is a unique numerical ID for this packet. The Connection
sets this ID on all packets sent out.
---------------------------------------------------------------------------*/
typedef struct {
unsigned short MagicNumber;
unsigned char Code;
unsigned long PacketID;
} CommHeaderType;
/*
***************************** Class Declaration *****************************
*/
class ConnectionClass
{
/*
---------------------------- Public Interface ----------------------------
*/
public:
/*.....................................................................
These are the possible values for the Code field of the CommHeaderType:
.....................................................................*/
enum ConnectionEnum {
PACKET_DATA_ACK, // this is a data packet requiring an ACK
PACKET_DATA_NOACK, // this is a data packet not requiring an ACK
PACKET_ACK, // this is an ACK for a packet
PACKET_COUNT, // for computational purposes
};
/*.....................................................................
Constructor/destructor.
.....................................................................*/
ConnectionClass (int maxlen, unsigned short magicnum,
unsigned long retry_delta, unsigned long max_retries,
unsigned long timeout);
virtual ~ConnectionClass ();
/*.....................................................................
Initialization.
.....................................................................*/
virtual void Init (void) {};
/*.....................................................................
Send/Receive routines.
.....................................................................*/
virtual int Send_Packet (void * buf, int buflen, int ack_req) = 0;
virtual int Receive_Packet (void * buf, int buflen) = 0;
virtual int Get_Packet (void * buf, int * buflen) = 0;
/*.....................................................................
The main polling routine for the connection. Should be called as often
as possible.
.....................................................................*/
virtual int Service (void);
/*.....................................................................
This routine is used by the retry logic; returns the current time in
60ths of a second.
.....................................................................*/
static unsigned long Time (void);
/*.....................................................................
Utility routines.
.....................................................................*/
unsigned short Magic_Num (void) { return (MagicNum); }
unsigned long Retry_Delta (void) { return (RetryDelta); }
void Set_Retry_Delta (unsigned long delta) { RetryDelta = delta;}
unsigned long Max_Retries (void) { return (MaxRetries); }
void Set_Max_Retries (unsigned long retries) { MaxRetries = retries;}
unsigned long Time_Out (void) { return (Timeout); }
void Set_TimeOut (unsigned long t) { Timeout = t;}
unsigned long Max_Packet_Len (void) { return (MaxPacketLen); }
static char * Command_Name(int command);
/*
-------------------------- Protected Interface ---------------------------
*/
protected:
/*.....................................................................
Routines to service the Send & Receive queues.
.....................................................................*/
virtual int Service_Send_Queue(void) = 0;
virtual int Service_Receive_Queue(void) = 0;
/*.....................................................................
This routine actually performs a hardware-dependent data send. It's
pure virtual, so it >must< be defined by a derived class.
.....................................................................*/
virtual int Send(char *buf, int buflen) = 0;
/*.....................................................................
This is the maximum packet length, including our own internal header.
.....................................................................*/
int MaxPacketLen;
/*.....................................................................
Packet staging area; this is where the CommHeaderType gets tacked onto
the application's packet before it's sent.
.....................................................................*/
char *PacketBuf;
/*.....................................................................
This is the magic number assigned to this connection. It is the first
few bytes of any transmission.
.....................................................................*/
unsigned short MagicNum;
/*.....................................................................
This value determines the time delay before a packet is re-sent.
.....................................................................*/
unsigned long RetryDelta;
/*.....................................................................
This is the maximum number of retries allowed for a packet; if this
value is exceeded, the connection is probably broken.
.....................................................................*/
unsigned long MaxRetries;
/*.....................................................................
This is the total timeout for this connection; if this time is exceeded
on a packet, the connection is probably broken.
.....................................................................*/
unsigned long Timeout;
/*.....................................................................
Names of all packet commands
.....................................................................*/
static char *ConnectionClass::Commands[PACKET_COUNT];
};
#endif