CONNECT.H (14400B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: /CounterStrike/CONNECT.H 1 3/03/97 10:24a Joe_bostic $ */ 17 /*************************************************************************** 18 ** 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 ** 19 *************************************************************************** 20 * * 21 * Project Name : Command & Conquer * 22 * * 23 * File Name : CONNECT.H * 24 * * 25 * Programmer : Bill Randolph * 26 * * 27 * Start Date : December 19, 1994 * 28 * * 29 * Last Update : April 1, 1995 [BR] * 30 * * 31 *-------------------------------------------------------------------------* 32 * * 33 * DESCRIPTION: * 34 * This class represents a single "connection" with another system. It's * 35 * a pure virtual base class that acts as a framework for other classes. * 36 * * 37 * This class contains a CommBufferClass member, which stores received * 38 * & transmitted packets. The ConnectionClass has virtual functions to * 39 * handle adding packets to the queue, reading them from the queue, * 40 * a Send routine for actually sending data, and a Receive_Packet function * 41 * which is used to tell the connection that a new packet has come in. * 42 * * 43 * The virtual Service routines handle all ACK & Retry logic for * 44 * communicating between this system & another. Thus, any class derived * 45 * from this class may overload the basic ACK/Retry logic. * 46 * * 47 * THE PACKET HEADER: * 48 * The Connection Classes prefix every packet sent with a header that's * 49 * local to this class. The header contains a "Magic Number" which should * 50 * be unique for each product, and Packet "Code", which will tell the * 51 * receiving end if this is DATA, or an ACK packet, and a packet ID, which * 52 * is a unique numerical ID for this packet (useful for detecting resends).* 53 * The header is stored with each packet in the send & receive Queues; * 54 * it's removed before it's passed back to the application, via * 55 * Get_Packet() * 56 * * 57 * THE CONNECTION MANAGER: * 58 * It is assumed that there will be a "Connection Manager" class which * 59 * will handle parsing incoming packets; it will then tell the connection * 60 * that new packets have come in, and the connection will process them in * 61 * whatever way it needs to for its protocol (check for resends, handle * 62 * ACK packets, etc). The job of the connection manager is to parse * 63 * incoming packets & distribute them to the connections that need to * 64 * store them (for multi-connection protocols). * 65 * * 66 * NOTES ON ACK/RETRY: * 67 * This class provides a "non-sequenced" ACK/Retry approach to packet * 68 * transmission. It sends out as many packets as are in the queue, whose * 69 * resend delta times have expired; and it ACK's any packets its received * 70 * who haven't been ACK'd yet. Thus, order of delivery is NOT guaranteed; * 71 * but, the performance is better than a "sequenced" approach. Also, the * 72 * Packet ID scheme (see below) ensures that the application will read * 73 * the packets in the proper order. Thus, this class guarantees delivery * 74 * and order of deliver. * 75 * * 76 * Each packet has a unique numerical ID; the ID is set to a count of the * 77 * number of packets sent. Different count values are provided, for both * 78 * DATA_ACK & DATA_NOACK packets. This ensures that the counter can be * 79 * used to detect resends of DATA_ACK packets; the counters for DATA_NOACK * 80 * packets aren't currently used. Other counters keep track of the * 81 * last-sequentially-received packet ID (for DATA_ACK packets), so we * 82 * can check for resends & missed packets, and the last-sequentially-read * 83 * packet ID, so we can ensure the app reads the packets in order. * 84 * * 85 * If the protocol being used already guarantees delivery of packets, * 86 * no ACK is required for the packets. In this case, the connection * 87 * class for this protocol can overload the Service routine to avoid * 88 * sending ACK packets, or the Connection Manager can just mark the * 89 * packet as ACK'd when it adds it to the Receive Queue for the connection.* 90 * * 91 * Derived classes must provide: * 92 * - Init: Initialization of any hardware-specific values. * 93 * - Send: a hardware-dependent send routine. * 94 * * 95 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 96 #ifndef CONNECTION_H 97 #define CONNECTION_H 98 99 /* 100 ********************************* Includes ********************************** 101 */ 102 #include "combuf.h" 103 104 /* 105 ********************************** Defines ********************************** 106 */ 107 #define CONN_DEBUG 0 108 /*--------------------------------------------------------------------------- 109 This structure is the header prefixed to any packet sent by the application. 110 MagicNumber: This is a number unique to the application; it's up to the 111 Receive_Packet routine to check this value, to be sure we're 112 not getting data from some other product. This value should 113 be unique for each application. 114 Code: This will be one of the below-defined codes. 115 PacketID: This is a unique numerical ID for this packet. The Connection 116 sets this ID on all packets sent out. 117 ---------------------------------------------------------------------------*/ 118 typedef struct { 119 unsigned short MagicNumber; 120 unsigned char Code; 121 unsigned long PacketID; 122 } CommHeaderType; 123 124 125 /* 126 ***************************** Class Declaration ***************************** 127 */ 128 class ConnectionClass 129 { 130 /* 131 ---------------------------- Public Interface ---------------------------- 132 */ 133 public: 134 /*..................................................................... 135 These are the possible values for the Code field of the CommHeaderType: 136 .....................................................................*/ 137 enum ConnectionEnum { 138 PACKET_DATA_ACK, // this is a data packet requiring an ACK 139 PACKET_DATA_NOACK, // this is a data packet not requiring an ACK 140 PACKET_ACK, // this is an ACK for a packet 141 PACKET_COUNT // for computational purposes 142 }; 143 144 /*..................................................................... 145 Constructor/destructor. 146 .....................................................................*/ 147 ConnectionClass (int numsend, int numrecieve, int maxlen, 148 unsigned short magicnum, unsigned long retry_delta, 149 unsigned long max_retries, unsigned long timeout, int extralen = 0); 150 virtual ~ConnectionClass (); 151 152 /*..................................................................... 153 Initialization. 154 .....................................................................*/ 155 virtual void Init (void); 156 157 /*..................................................................... 158 Send/Receive routines. 159 .....................................................................*/ 160 virtual int Send_Packet (void * buf, int buflen, int ack_req); 161 virtual int Receive_Packet (void * buf, int buflen); 162 virtual int Get_Packet (void * buf, int * buflen); 163 164 /*..................................................................... 165 The main polling routine for the connection. Should be called as often 166 as possible. 167 .....................................................................*/ 168 virtual int Service (void); 169 170 /*..................................................................... 171 This routine is used by the retry logic; returns the current time in 172 60ths of a second. 173 .....................................................................*/ 174 static unsigned long Time (void); 175 176 /*..................................................................... 177 Utility routines. 178 .....................................................................*/ 179 unsigned short Magic_Num (void) { return (MagicNum); } 180 unsigned long Retry_Delta (void) { return (RetryDelta); } 181 void Set_Retry_Delta (unsigned long delta) { RetryDelta = delta;} 182 unsigned long Max_Retries (void) { return (MaxRetries); } 183 void Set_Max_Retries (unsigned long retries) { MaxRetries = retries;} 184 unsigned long Time_Out (void) { return (Timeout); } 185 void Set_TimeOut (unsigned long t) { Timeout = t;} 186 unsigned long Max_Packet_Len (void) { return (MaxPacketLen); } 187 static char * Command_Name(int command); 188 189 /*..................................................................... 190 The packet "queue"; this non-sequenced version isn't really much of 191 a queue, but more of a repository. 192 .....................................................................*/ 193 CommBufferClass *Queue; 194 195 /* 196 -------------------------- Protected Interface --------------------------- 197 */ 198 protected: 199 /*..................................................................... 200 Routines to service the Send & Receive queues. 201 .....................................................................*/ 202 virtual int Service_Send_Queue(void); 203 virtual int Service_Receive_Queue(void); 204 205 /*..................................................................... 206 This routine actually performs a hardware-dependent data send. It's 207 pure virtual, so it must be defined by a derived class. The routine 208 is protected; it's only called by the ACK/Retry logic, not the 209 application. 210 .....................................................................*/ 211 virtual int Send(char *buf, int buflen, void *extrabuf, 212 int extralen) = 0; 213 214 /*..................................................................... 215 This is the maximum packet length, including our own internal header. 216 .....................................................................*/ 217 int MaxPacketLen; 218 219 /*..................................................................... 220 Packet staging area; this is where the CommHeaderType gets tacked onto 221 the application's packet before it's sent. 222 .....................................................................*/ 223 char *PacketBuf; 224 225 /*..................................................................... 226 This is the magic number assigned to this connection. It is the first 227 few bytes of any transmission. 228 .....................................................................*/ 229 unsigned short MagicNum; 230 231 /*..................................................................... 232 This value determines the time delay before a packet is re-sent. 233 .....................................................................*/ 234 unsigned long RetryDelta; 235 236 /*..................................................................... 237 This is the maximum number of retries allowed for a packet; if this 238 value is exceeded, the connection is probably broken. 239 .....................................................................*/ 240 unsigned long MaxRetries; 241 242 /*..................................................................... 243 This is the total timeout for this connection; if this time is exceeded 244 on a packet, the connection is probably broken. 245 .....................................................................*/ 246 unsigned long Timeout; 247 248 /*..................................................................... 249 Running totals of # of packets we send & receive which require an ACK, 250 and those that don't. 251 .....................................................................*/ 252 unsigned long NumRecNoAck; 253 unsigned long NumRecAck; 254 unsigned long NumSendNoAck; 255 unsigned long NumSendAck; 256 257 /*..................................................................... 258 This is the ID of the last consecutively-received packet; anything older 259 than this, we know is a resend. Anything newer than this MUST be lying 260 around in the Queue for us to detect it as a resend. 261 .....................................................................*/ 262 unsigned long LastSeqID; 263 264 /*..................................................................... 265 This is the ID of the PACKET_DATA_ACK packet we read last; it ensures 266 that the application reads that type of packet in order. 267 .....................................................................*/ 268 unsigned long LastReadID; 269 270 /*..................................................................... 271 Names of all packet commands 272 .....................................................................*/ 273 static char * Commands[PACKET_COUNT]; 274 }; 275 276 #endif 277 278 /**************************** end of connect.h *****************************/