GizmoDistribution

gzDistRemoteChannel.h

Go to the documentation of this file.
00001 //*****************************************************************************
00002 // File         : gzDistRemoteChannel.h
00003 // Module       : gzRemoteDistribution
00004 // Description  : Definition of gzDistRemoteChannel
00005 // Author       : Anders Sandblad, Christian Andersson
00006 // Product      : GizmoDistribution 2.1.1
00007 //
00008 // Copyright © 2004 - Saab Training Systems AB, Sweden
00009 //
00010 // NOTE:    GizmoDistribution is a toolkit used for implementing distributed 
00011 //          objects and events in C++
00012 //
00013 //
00014 // Revision History...
00015 //
00016 // Who  Date    Description
00017 //
00018 // XAA  031113  Created file 
00019 //
00020 //******************************************************************************
00021 #ifndef __GZ_DIST_REMOTE_CHANNEL_H__
00022 #define __GZ_DIST_REMOTE_CHANNEL_H__
00023 
00029 // Includes
00030 #include "gzDistBase.h"
00031 #include "gzDistRemoteMessage.h"
00032 #include "gzDistEncoder.h"
00033 
00034 // Forward declarations
00035 class gzDistProtocolInterface;
00036 class gzDistTransportInterface;
00037 
00038 
00039 //-----------------------------------------------------------------------------
00040 
00041 // Protocol version
00042 const gzUByte GZ_DIST_PROTOCOL_VERSION      = 0x14; // 1.4
00043 const gzUShort GZ_DIST_PROTOCOL_HEADER_SIZE = 29;   // Bytes
00044 
00045 // Positions in gzDistProtocolMessageHeader data
00046 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_VERSION_POS                  = 0;
00047 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_PRIO_POS                     = 1;
00048 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_CHANNEL_POS                  = 1;
00049 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_MESSAGE_TYPE_POS             = 2;
00050 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_SENDER_PROCESS_ID_POS        = 3;
00051 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_SENDER_MACHINE_ID_POS        = 7;
00052 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_SENDER_INDEX_POS             = 11;
00053 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_FRAGMENT_LENGTH_POS          = 15;
00054 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_DESTINATION_PROCESS_ID_POS   = 17;
00055 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_DESTINATION_MACHINE_ID_POS   = 21;
00056 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_FRAGMENT_INDEX_POS           = 25;
00057 const gzUByte GZ_DIST_PROTOCOL_MESSAGE_FRAGMENTS_POS                = 27;
00058 
00060 enum gzDistTransportType
00061 {
00062     GZ_DIST_MULTICAST,  
00063     GZ_DIST_BROADCAST,  
00064     GZ_DIST_TCP         
00065 };
00066 
00067 //----------------------- gzDistProtocolMessageHeader -------------------------
00068 
00069 // Used internal and by sniffer.
00070 class GZ_REMOTE_EXPORT gzDistProtocolMessageHeader
00071 {
00072     public:
00073         gzDistProtocolMessageHeader();
00074         ~gzDistProtocolMessageHeader();
00075 
00076         gzVoid setVersion(gzUByte version);
00077         gzVoid setChannel(gzUByte channel);
00078         gzVoid setMessageType(gzUByte id);
00079         gzVoid setSenderProcessID(gzULong id);
00080         gzVoid setSenderMachineID(gzULong id);
00081         gzVoid setSenderIndex(gzULong index);
00082         gzVoid setFragmentLength(gzUShort length);
00083         gzVoid setDestinationProcessID(gzULong id);
00084         gzVoid setDestinationMachineID(gzULong id);
00085         gzVoid setFragmentIndex(gzUShort index);
00086         gzVoid setFragments(gzUShort fragments);
00087         gzVoid setPrio(gzBool prio);
00088 
00089         gzUByte getVersion();
00090         gzUByte getChannel();
00091         gzUByte getMessageType();
00092         gzULong getSenderProcessID();
00093         gzULong getSenderMachineID();
00094         gzULong getSenderIndex();
00095         gzUShort getFragmentLength();
00096         gzULong getDestinationProcessID();
00097         gzULong getDestinationMachineID();
00098         gzUShort getFragmentIndex();
00099         gzUShort getFragments();
00100         gzBool getPrio();
00101 
00102         gzVoid setBuffer(gzUByte* buffer);
00103         const gzUByte* getBuffer();
00104     
00105     private:
00106 
00107         inline gzUShort readShortVal(const gzUByte pos);
00108         inline gzULong readLongVal(const gzUByte pos);
00109 
00110         inline gzVoid writeShortVal(const gzUShort val, const gzUByte pos);
00111         inline gzVoid writeLongVal(const gzULong val, const gzUByte pos);
00112 
00113         gzULong m_longVal;
00114         gzUShort m_shortVal;
00115         gzUByte* m_data;
00116         gzUByte* m_bytePtr;
00117         gzBool m_littleEndian;
00118 };
00119 
00120 
00121 //-------------------------- gzDistDisposeMessage -----------------------------
00122 
00123 // Internal
00124 class gzDistDisposeRemoteMessage
00125 {
00126     public:
00127         gzDistDisposeRemoteMessage();
00128 
00129         ~gzDistDisposeRemoteMessage();
00130 
00131         gzDistRemoteMessageSession* remoteMessage;
00132 
00133         gzULong lastMessageIndex;
00134 
00135         gzUInt lastFragmentIndex;
00136 };
00137 
00138 
00139 //---------------------- gzDistInstanceIDCompareClass -------------------------
00140 
00141 // Internal
00142 class gzDistInstanceIDCompareClass
00143 {
00144     public:
00145         gzDistInstanceIDCompareClass(const gzDistInstanceID& instanceID) : m_instanceId(instanceID)
00146         {   
00147         }
00148 
00149         ~gzDistInstanceIDCompareClass()
00150         {}
00151         
00152         gzULong hash() const
00153         {
00154             return m_instanceId.processID;
00155         }
00156 
00157         gzBool operator ==(const gzDistInstanceIDCompareClass& right)
00158         {
00159             return (m_instanceId == right.m_instanceId);                 
00160         }
00161 
00162         const gzDistInstanceID& getInstanceID()
00163         {
00164             return m_instanceId;
00165         }
00166 
00167     
00168     private:
00169 
00170         gzDistInstanceID m_instanceId;
00171 };
00172 
00173 
00174 //------------------------ gzDistDisposeBufferData ------------------------------
00175 
00176 // Internal
00177 class gzDistRemoteInstanceIndex
00178 {
00179     public:
00180         gzDistRemoteInstanceIndex(gzULong index) : m_acceptedIndex(index), m_receivedIndex(index),
00181             m_numberOfResends(0), m_acceptedFragmentIndex(0), m_totalFragments(0),
00182             m_lastAccept(0), m_waitingForAck(FALSE) {}
00183         
00184         ~gzDistRemoteInstanceIndex() {}
00185 
00186         gzDouble m_lastAccept;
00187 
00188         // Last accepted receive index.
00189         gzULong m_acceptedIndex;
00190 
00191         // Last received index.
00192         gzULong m_receivedIndex;
00193 
00194         // Last accepted receive fragment index.
00195         gzUInt m_acceptedFragmentIndex;
00196 
00197         // Total number of fragments in message.
00198         gzUInt m_totalFragments;
00199 
00200         // How many resends that has been done for current index.
00201         gzULong m_numberOfResends;
00202 
00203         // Tells if we are waiting from ack from this instance.
00204         gzBool m_waitingForAck;
00205 };
00206 
00207 //---------------------- gzDistResendRequestItem ----------------------
00208 
00209 class gzDistResendRequestItem
00210 {
00211     public:
00212         gzDistResendRequestItem(const gzDistInstanceID& id) : instanceId(id) {}
00213         ~gzDistResendRequestItem(){}
00214 
00215         const gzDistInstanceID instanceId;
00216         gzULong index;
00217         gzUInt fragment;
00218 };
00219 
00220 //----------------------------- gzDistRemoteChannel ---------------------------
00221 
00223 
00236 class gzDistRemoteChannel : public gzDistRemoteChannelInterface
00237 {
00238     public:
00239         
00241 
00255         GZ_REMOTE_EXPORT gzDistRemoteChannel(gzUInt reliableBufferSize = 0);
00256 
00258         GZ_REMOTE_EXPORT virtual ~gzDistRemoteChannel();
00259 
00260 
00262 
00273         GZ_REMOTE_EXPORT gzBool setTransport(gzDistTransportInterface* transport, gzDistEncoderInterface* encoder = NULL);
00274 
00276         GZ_REMOTE_EXPORT gzBool open();
00277         
00279         GZ_REMOTE_EXPORT gzVoid close();
00280 
00282         GZ_REMOTE_EXPORT gzBool isOpen();
00283         
00285         GZ_REMOTE_EXPORT gzBool send(gzDistRemoteMessage* message);
00286 
00288 
00294         GZ_REMOTE_EXPORT gzBool receive(gzDistRemoteMessagePtr& message);
00295 
00297         GZ_REMOTE_EXPORT gzUInt getProtocolHeaderSize();
00298 
00300         GZ_REMOTE_EXPORT gzVoid onTick();
00301 
00302         GZ_REMOTE_EXPORT gzBool hasPendingData();
00303 
00304     private:
00305         
00306         // Add or update a resend request.
00307         gzVoid setReply(const gzDistInstanceID& sendTo, gzULong messageIndex, gzUInt fragmentIndex);
00308         
00309         gzBool processResend();
00310 
00311         gzVoid sendBufferedMessages(gzUInt maxMessages);
00312         
00313         // Send a ackowledge request.
00314         gzVoid requestAck(const gzDistInstanceID& instanceId);
00315         
00316         // Send a reply on a ackowledge request.
00317         gzVoid replyAckRequest(const gzDistInstanceID& instanceId, gzULong index, gzUShort fragmentIndex);
00318 
00319         gzBool receiveInternal(gzDistRemoteMessagePtr& message);
00320 
00321         // Parse buffer and create message
00322         gzBool parseBuffer(gzDistSerializeMemoryData* buffer, gzDistRemoteMessagePtr& message);
00323 
00324         // Serialize message to buffer
00325         gzBool serializeMessage(gzDistRemoteMessage* message);
00326 
00327         // Write a header in the beginning of the buffer.
00328         gzVoid writeHeaders(gzDistRemoteMessage* message, gzUInt messageIndex);
00329 
00330         gzBool parseServerMessage(gzDistRemoteMessageServer* message, gzSerializeAdapter* adapter);
00331 
00332         gzBool parseSessionMessage(gzDistRemoteMessageSession* sessionMessage);
00333         
00334         gzBool serializeServerMessage(gzSerializeAdapter* adapter, const gzDistRemoteMessageServer* message);
00335 
00336     // --- Fragmented data managing methods ---
00337 
00338         // Add a fragment to a message
00339         gzBool disposeFragment(const gzDistInstanceID& instanceID, gzDistSerializeMemoryData* buffer, gzULong messageIndex, gzUInt fragmentIndex);
00340 
00341         // Gets and remove a message. The fragments param is only to verify the number of fragments.
00342         gzDistRemoteMessageSession* removeMessage(const gzDistInstanceID& instanceID, gzUInt fragments);
00343 
00344     // --- 
00345 
00346         // Send a request on resend on missed data.
00347         gzVoid requestResend(const gzDistInstanceID& sendTo, gzDistRemoteInstanceIndex* instance);
00348 
00349         // Reply requested data.
00350         gzBool replyResendRequest(gzDistResendRequestItem* requestItem);
00351 
00352         // Return true when we have reached end of resend buffer.
00353         gzBool bufferMessage(gzDistRemoteMessage* message);
00354 
00355         // Send message to transtporters.
00356         gzVoid sendMessage(gzDistRemoteMessage* message, gzUInt fromFragment);
00357 
00358         gzInt receiveMessage(gzUByte* receiveBuffer, gzUInt bufferSize);
00359 
00360         // This method is needed for other processes to verify that no messages is missed.
00361         gzVoid distributeIndex();
00362 
00363         gzVoid sendBufferStartIndex(const gzDistInstanceID& sendTo, gzULong beginningOfBuffer);
00364 
00365         // Copy (not allowed)
00366         gzDistRemoteChannel(const gzDistRemoteChannel&);
00367     
00368         // Assignment (not allowed)
00369         gzDistRemoteChannel& operator=(const gzDistRemoteChannel&);
00370 
00371         gzBool isNextExpected(gzULong messageIndex, gzUInt fragmentIndex, gzDistRemoteInstanceIndex* instance);
00372 
00373         gzVoid removeInstance(const gzDistInstanceID& instanceId);
00374 
00375         gzVoid removeAckRequest(const gzDistInstanceID& instanceId);
00376 
00377         gzVoid sendShutdown();
00378 
00379         gzVoid buildAckList();
00380 
00381         gzVoid requestAcks();
00382 
00383         gzVoid manageSpecialCommands(gzUByte command);
00384 
00385     // --- Data ---
00386 
00387         gzDistProtocolMessageHeader m_messageHeader;
00388 
00389         gzDistSerializeAdapterMemory m_memoryAdapter;
00390 
00391         // For fragment managing.
00392         gzDict<gzDistInstanceIDCompareClass, gzDistDisposeRemoteMessage> m_messageStore;
00393 
00394     // --- Reliable management data ---
00395 
00396         // For reliable managing
00397         gzDict<gzDistInstanceIDCompareClass, gzDistRemoteInstanceIndex> m_instanceStore;
00398 
00399         // Used to store received messages temporary during resend processing.
00400         gzRefList<gzDistRemoteMessage> m_tempRecMessages;
00401 
00402         // Next time to reply resend requests.
00403         gzDouble m_nextResendTime;
00404 
00405         gzList<gzDistResendRequestItem> m_resendRequests;
00406 
00407         // The sender index from this instance. Index start at index = 1.
00408         gzULong m_messageIndex;
00409 
00410         // Reliable
00411         gzBool m_reliable;
00412 
00413         // A buffer containing this instance data.
00414         gzArray<gzRefPointer<gzDistRemoteMessage> > m_resendBuffer;
00415 
00416         // Current position in m_resendBuffer
00417         gzUInt m_bufferIndex;
00418 
00419         // The message index where m_resendBuffer begins.
00420         gzUInt m_bufferPosition;
00421 
00422         // Time for last tick!!
00423         gzDouble m_lastTick;
00424 
00425         // Time for last index distribution.
00426         gzDouble m_lastIndexDistribution;
00427 
00428         // The number of instances we are expecting ack from.
00429         gzUInt m_waitingForAckCounter;
00430 
00431         // Messages will temporary be placed here during 'wait for ack'.
00432         gzRefList<gzDistRemoteMessage> m_tempSendMessages;
00433     
00434     // ---
00435 
00436         // Is open?
00437         gzBool m_open;
00438 
00439         // Transport (mandatory)
00440         gzDistTransportInterface* m_transport;
00441 
00442         // Encoder (optional)
00443         gzDistEncoderInterface* m_encoder;
00444 
00445         // A handle to a buffer when data is receiving.
00446         gzDistSerializeMemoryData* m_receiveBuffer;
00447 
00448         // A receive buffer used when any type of encoder is used.
00449         gzUByte* m_codeReceiveBuffer;
00450 };
00451 
00452 
00453 //-------------------------------- Utilities ----------------------------------
00454 
00456 /*  Create a channel with a default transport installed.
00457     The default server transport uses UDP multicast
00458     on group GZ_DIST_DEFAULT_IP_ADDRESS and port GZ_DIST_DEFAULT_SERVER_PORT.
00459     These constants are defined in gzDistBase.h
00460     \param reliable         Set this to TRUE if a reliable connection is desired.
00461                             Zero gives best-effort.
00462     \param transportType    Set this to GZ_DIST_BROADCAST to create a broadcast channel.
00463                             GZ_DIST_MULTICAST (default) will create a multicast channel.
00464                             It is possible to use a TCP copnnection by seting the parameter to GZ_DIST_TCP.
00465                             This will create a TCP client. In this case, the gzDistRouter is needed.
00466                             gzDistRouter is a tool that can be downloaded from the homepage of GizmoSDK.
00467     \param encoder          Use this to add a compressor, crypto etc.
00468     \return                 A pointer to a gzDistRemoteChannel.
00469     \note                   A reliable mode GizmoDistribution process cannot cooperate
00470                             with a best-effort mode GizmoDistribution process.
00471     \sa                     gzDistRemoteChannel::gzDistRemoteChannel() \n
00472                             gzDistCreateDefaultSessionChannel() \n
00473                             gzDistCreateChannel()*/
00474 GZ_REMOTE_EXPORT gzDistRemoteChannel* gzDistCreateDefaultServerChannel(gzBool reliable = FALSE, gzDistTransportType transportType = GZ_DIST_MULTICAST, gzDistEncoderInterface* encoder = NULL);
00475 
00476 
00478 
00496 GZ_REMOTE_EXPORT gzDistRemoteChannel* gzDistCreateDefaultSessionChannel(gzBool reliable = FALSE, gzDistTransportType transportType = GZ_DIST_MULTICAST, gzDistEncoderInterface* encoder = NULL);
00497 
00498 
00500 
00522 GZ_REMOTE_EXPORT gzDistRemoteChannel* gzDistCreateChannel(gzUInt reliableBufferSize, gzDistTransportType transportType, gzDistEncoderInterface* encoder, const gzString& address, gzUInt port, const gzString& iface = "0.0.0.0");
00523 
00524 
00525 #endif
00526 

Documentation for GizmoDistribution generated at Wed Feb 20 11:59:21 2008 by   Saab Training Systems AB, ¸ (c) 2003-and beyond