CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

CONNECT.H (17916B)


      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:   F:\projects\c&c\vcs\code\connect.h_v   1.12   16 Oct 1995 16:46:04   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 CommQueueClass 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 routine will handle all ACK & Retry logic for			*
     44  * communicating between this system & another.  Thus, any class derived	*
     45  * from this class must provide the basic ACK/Retry logic.						*
     46  *                                                                         *
     47  * THE 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  * The packet's ID is used to check for re-sends.  The ID is set to the 	*
     68  * Queue's total Send Count; if the receiving system checks this value, 	*
     69  * and it's less than that system's Receive Count, this is a resend.  		*
     70  * (ie packet 0 will be the 1st packet sent, since the Send Queue's count 	*
     71  * is 0 when it's sent;  as soon as it's received, the Receive Count goes 	*
     72  * up to 1, and an ID of 0 then means a resend.)  This scheme keeps the 	*
     73  * application from seeing the same packet twice.  All the Connection 		*
     74  * Manager has to do is mark the resent packet as non-ACK'd.  Of course, 	*
     75  * the Manager doesn't have to use this value at all.								*
     76  *                                                                         *
     77  * Both DATA_ACK packets and DATA_NOACK packets must go through the Send	*
     78  * Queue when "sent", so that the SendTotal value for this system				*
     79  * will still match the ReceiveTotal value for the other system; this is	*
     80  * why a NOACK packet can't just be sent immediately; it must go through	*
     81  * the queue.																					*
     82  *                                                                         *
     83  * If the protocol being used already guarantees delivery of packets,		*
     84  * no ACK is required for the packets.  In this case, the connection			*
     85  * class for this protocol can overload the Service routine to avoid			*
     86  * sending ACK packets, or the Connection Manager can just mark the			*
     87  * packet as ACK'd when it adds it to the Receive Queue for the connection.*
     88  *                                                                         *
     89  *	Derived classes must provide:															*
     90  * - Init						a version of Init that gives the connection 		*
     91  *									access to any hardware-specific values it needs	*
     92  *									Must chain to the parent's Init routine.			*
     93  * - Send_Packet				adds the CommHeaderType header, adds the packet	*
     94  *									to the out-going queue									*
     95  * - Receive_Packet			processes incoming ACK packets, detects resends,*
     96  *									adds new packets to the in-coming queue			*
     97  * - Get_Packet				reads the next-available packet from the			*
     98  *									receive queue												*
     99  * - Send						the hardware-dependent data-sending routine		*
    100  * - Service_Send_Queue		services the send queue; handles re-sends,		*
    101  *									detects when outgoing packets have been ACK'd;	*
    102  *									cleans out the queue of old packets					*
    103  * - Service_Receive_Queue	services the receive queue; handles sending		*
    104  *									ACK's for new or re-sent packets; cleans out		*
    105  *									the queue of old packets								*
    106  *																									*
    107  *	Any other routines can be overloaded as the derived class needs.			*
    108  *																									*
    109  *	CLASS HIERARCHY:																			*
    110  *										ConnectionClass										*
    111  *												 |													*
    112  *												 |													*
    113  *						--------------------------------------							*
    114  *						| 	   	 		  		    		       |							*
    115  *						|        				  		          |							*
    116  *			SequencedConnClass   		 	       NonSequencedConnClass			*
    117  *						|										       |							*
    118  *						|									          |							*
    119  *			   IPXConnClass     			        ------------------------			*
    120  *						|							     |                      |			*
    121  *						|							     |                      |			*
    122  *		   IPXGlobalConnClass        NullModemConnClass       ModemConnClass	*
    123  *																									*
    124  *																									*
    125  *	ConnectionClass:																			*
    126  *		Abstract base class.																	*
    127  *		Provides: Queue for sent/recv'd packets										*
    128  *		          PacketBuf for preparing packets										*
    129  *					 Timeout variables														*
    130  *					 Service() routine														*
    131  *																									*
    132  *	SequencedConnClass:																		*
    133  *		Abstract base class																	*
    134  *		Provides: * "Sequenced" ACK/Retry logic, in Service_Send_Queue() &	*
    135  *						Service_Receive_Queue() routines									*
    136  *					 * Send_Packet(): adds header to packet, adds it to Queue	*
    137  *					 * Receive_Packet(): adds incoming packet to receive Queue, *
    138  *					   handles incoming ACK's & resends									*
    139  *					 * Get_Packet(): gets packet from the receive queue			*
    140  *																									*
    141  *	NonSequencedConnClass:																	*
    142  *		Abstract base class																	*
    143  *		Provides: * "Non-Sequenced" ACK/Retry logic, in Service_Send_Queue()	*
    144  *						& Service_Receive_Queue() routines								*
    145  *					 * Send_Packet(): adds header to packet, adds it to Queue	*
    146  *					 * Receive_Packet(): adds incoming packet to receive Queue, *
    147  *					   handles incoming ACK's & resends									*
    148  *					 * Get_Packet(): gets packet from the receive queue			*
    149  *																									*
    150  *	IPXConnClass:																				*
    151  *		Provides: * Hardware-dependent IPX interface routines, which allow	*
    152  *					   Service_Send_Queue() & Service_Receive_Queue() to do		*
    153  *						their job																*
    154  *					 * Ability to associate an IPX Address, a numerical ID, and	*
    155  *					   a character-string Name with a connection						*
    156  *		Inherits: * Sequenced ACK/Retry logic, Service routines, Queue &		*
    157  *						PacketBuf, timeout variables										*
    158  *																									*
    159  *	IPXGlobalConnClass:																		*
    160  *		Special type of IPX Connection; supports receiving packets from		*
    161  *		multiple systems at once, and sending packets via Broadcast or			*
    162  *		to a specific address.																*
    163  *		Provides: * Specialized Receive_Packet() routine, which handles		*
    164  *						receiving packets from multiple systems						*
    165  *					 * Specialized Send_Packet() & Get_Packet() routines,			*
    166  *					   which pass IPX address of destination through to			*
    167  *						the application, giving the application control over		*
    168  *						whether the packet will be Broadcast or sent to a 			*
    169  *						specific destination (embeds destination address within	*
    170  *						the packet itself)													*
    171  *					 * Specialized Send routine, which extracts the destination	*
    172  *					   address from the packet												*
    173  *		Inherits: * Sequenced ACK/Retry logic, Service routines, Queue &		*
    174  *						PacketBuf, timeout variables, IPX-specific routines		*
    175  *																									*
    176  *	NullModemConnClass:																		*
    177  *		Provides: * Hardware-dependent Serial-communication routines, which	*
    178  *						allow Service_Send_Queue() & Service_Receive_Queue() to 	*
    179  *						do their job															*
    180  *		Inherits: * Non-Sequenced ACK/Retry logic, Service routines, Queue &	*
    181  *						PacketBuf, timeout variables										*
    182  *																									*
    183  *	ModemConnClass:																			*
    184  *		Provides: * Hardware-dependent Modem-communication routines, which	*
    185  *						allow Service_Send_Queue() & Service_Receive_Queue() to 	*
    186  *						do their job															*
    187  *		Inherits: * Non-Sequenced ACK/Retry logic, Service routines, Queue &	*
    188  *						PacketBuf, timeout variables										*
    189  *																									*
    190  *	So, do ya think this header is long enough, or what?							*
    191  *																									*
    192  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    193 
    194 #ifndef CONNECTION_H
    195 #define CONNECTION_H
    196 
    197 #define CONN_DEBUG	0
    198 
    199 /*
    200 ********************************** Defines **********************************
    201 */
    202 /*---------------------------------------------------------------------------
    203 This structure is the header prefixed to any packet sent by the application.
    204 MagicNumber:	This is a number unique to the application; it's up to the
    205 					Receive_Packet routine to check this value, to be sure we're
    206 					not getting data from some other product.  This value should
    207 					be unique for each application.
    208 Code:				This will be one of the below-defined codes.
    209 PacketID:		This is a unique numerical ID for this packet.  The Connection
    210 					sets this ID on all packets sent out.
    211 ---------------------------------------------------------------------------*/
    212 typedef struct {
    213 	unsigned short MagicNumber;
    214 	unsigned char Code;
    215 	unsigned long PacketID;
    216 } CommHeaderType;
    217 
    218 
    219 /*
    220 ***************************** Class Declaration *****************************
    221 */
    222 class ConnectionClass
    223 {
    224 	/*
    225 	---------------------------- Public Interface ----------------------------
    226 	*/
    227 	public:
    228 		/*.....................................................................
    229 		These are the possible values for the Code field of the CommHeaderType:
    230 		.....................................................................*/
    231 		enum ConnectionEnum {
    232 			PACKET_DATA_ACK,			// this is a data packet requiring an ACK
    233 			PACKET_DATA_NOACK,		// this is a data packet not requiring an ACK
    234 			PACKET_ACK,					// this is an ACK for a packet
    235 			PACKET_COUNT,				// for computational purposes
    236 		};
    237 
    238 		/*.....................................................................
    239 		Constructor/destructor.
    240 		.....................................................................*/
    241 		ConnectionClass (int maxlen, unsigned short magicnum, 
    242 			unsigned long retry_delta, unsigned long max_retries, 
    243 			unsigned long timeout);
    244 		virtual ~ConnectionClass ();
    245 
    246 		/*.....................................................................
    247 		Initialization.
    248 		.....................................................................*/
    249 		virtual void Init (void) {};
    250 
    251 		/*.....................................................................
    252 		Send/Receive routines.
    253 		.....................................................................*/
    254 		virtual int Send_Packet (void * buf, int buflen, int ack_req) = 0;
    255 		virtual int Receive_Packet (void * buf, int buflen) = 0;
    256 		virtual int Get_Packet (void * buf, int * buflen) = 0;
    257 
    258 		/*.....................................................................
    259 		The main polling routine for the connection.  Should be called as often
    260 		as possible.
    261 		.....................................................................*/
    262 		virtual int Service (void);
    263 
    264 		/*.....................................................................
    265 		This routine is used by the retry logic; returns the current time in
    266 		60ths of a second.
    267 		.....................................................................*/
    268 		static unsigned long Time (void);
    269 
    270 		/*.....................................................................
    271 		Utility routines.
    272 		.....................................................................*/
    273 		unsigned short Magic_Num (void) { return (MagicNum); }
    274 		unsigned long Retry_Delta (void) { return (RetryDelta); }
    275 		void Set_Retry_Delta (unsigned long delta) { RetryDelta = delta;}
    276 		unsigned long Max_Retries (void) { return (MaxRetries); }
    277 		void Set_Max_Retries (unsigned long retries) { MaxRetries = retries;}
    278 		unsigned long Time_Out (void) { return (Timeout); }
    279 		void Set_TimeOut (unsigned long t) { Timeout = t;}
    280 		unsigned long Max_Packet_Len (void) { return (MaxPacketLen); }
    281 		static char * Command_Name(int command);
    282 
    283 	/*
    284 	-------------------------- Protected Interface ---------------------------
    285 	*/
    286 	protected:
    287 		/*.....................................................................
    288 		Routines to service the Send & Receive queues.
    289 		.....................................................................*/
    290 		virtual int Service_Send_Queue(void) = 0;
    291 		virtual int Service_Receive_Queue(void) = 0;
    292 
    293 		/*.....................................................................
    294 		This routine actually performs a hardware-dependent data send.  It's
    295 		pure virtual, so it >must< be defined by a derived class.
    296 		.....................................................................*/
    297 		virtual int Send(char *buf, int buflen) = 0;
    298 
    299 		/*.....................................................................
    300 		This is the maximum packet length, including our own internal header.
    301 		.....................................................................*/
    302 		int MaxPacketLen;
    303 
    304 		/*.....................................................................
    305 		Packet staging area; this is where the CommHeaderType gets tacked onto 
    306 		the application's packet before it's sent.
    307 		.....................................................................*/
    308 		char *PacketBuf;
    309 
    310 		/*.....................................................................
    311 		This is the magic number assigned to this connection.  It is the first 
    312 		few bytes of any transmission.
    313 		.....................................................................*/
    314 		unsigned short MagicNum;
    315 
    316 		/*.....................................................................
    317 		This value determines the time delay before a packet is re-sent.
    318 		.....................................................................*/
    319 		unsigned long RetryDelta;
    320 
    321 		/*.....................................................................
    322 		This is the maximum number of retries allowed for a packet; if this
    323 		value is exceeded, the connection is probably broken.
    324 		.....................................................................*/
    325 		unsigned long MaxRetries;
    326 
    327 		/*.....................................................................
    328 		This is the total timeout for this connection; if this time is exceeded
    329 		on a packet, the connection is probably broken.
    330 		.....................................................................*/
    331 		unsigned long Timeout;
    332 
    333 		/*.....................................................................
    334 		Names of all packet commands
    335 		.....................................................................*/
    336 		static char *ConnectionClass::Commands[PACKET_COUNT];
    337 };
    338 
    339 #endif
    340