00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef FIX_SESSION_H
00023 #define FIX_SESSION_H
00024
00025 #ifdef _MSC_VER
00026 #pragma warning( disable : 4503 4355 4786 4290 )
00027 #endif
00028
00029 #include "SessionState.h"
00030 #include "SessionTime.h"
00031 #include "SessionID.h"
00032 #include "Responder.h"
00033 #include "Fields.h"
00034 #include "DataDictionary.h"
00035 #include "Application.h"
00036 #include "Mutex.h"
00037 #include "Log.h"
00038 #include <utility>
00039 #include <map>
00040 #include <queue>
00041
00042 namespace FIX
00043 {
00045 class Session
00046 {
00047 public:
00048 Session( Application&, MessageStoreFactory&,
00049 const SessionID&,
00050 const DataDictionary&,
00051 const SessionTime&,
00052 int heartBtInt, LogFactory* pLogFactory );
00053 ~Session();
00054
00055 void logon()
00056 { m_state.enabled( true ); m_state.logoutReason( "" ); }
00057 void logout( const std::string& reason = "" )
00058 { m_state.enabled( false ); m_state.logoutReason( reason ); }
00059 bool isEnabled()
00060 { return m_state.enabled(); }
00061
00062 bool sentLogon() { return m_state.sentLogon(); }
00063 bool sentLogout() { return m_state.sentLogout(); }
00064 bool receivedLogon() { return m_state.receivedLogon(); }
00065 bool isLoggedOn() { return receivedLogon() && sentLogon(); }
00066 void reset() throw( IOException )
00067 { generateLogout(); disconnect(); m_state.reset(); }
00068 void refresh() throw( IOException )
00069 { m_state.refresh(); }
00070 void setNextSenderMsgSeqNum( int num ) throw( IOException )
00071 { m_state.setNextSenderMsgSeqNum( num ); }
00072 void setNextTargetMsgSeqNum( int num ) throw( IOException )
00073 { m_state.setNextTargetMsgSeqNum( num ); }
00074
00075 const SessionID& getSessionID() const
00076 { return m_sessionID; }
00077 void setDataDictionary( const DataDictionary& dataDictionary )
00078 { m_dataDictionary = dataDictionary; }
00079 const DataDictionary& getDataDictionary() const
00080 { return m_dataDictionary; }
00081
00082 static bool sendToTarget( Message& message,
00083 const std::string& qualifier = "" )
00084 throw( SessionNotFound );
00085 static bool sendToTarget( Message& message, const SessionID& sessionID )
00086 throw( SessionNotFound );
00087 static bool sendToTarget( Message&,
00088 const SenderCompID& senderCompID,
00089 const TargetCompID& targetCompID,
00090 const std::string& qualifier = "" )
00091 throw( SessionNotFound );
00092 static bool sendToTarget( Message& message,
00093 const std::string& senderCompID,
00094 const std::string& targetCompID,
00095 const std::string& qualifier = "" )
00096 throw( SessionNotFound );
00097
00098 static bool doesSessionExist( const SessionID& );
00099 static Session* lookupSession( const SessionID& );
00100 static Session* lookupSession( const std::string&, bool reverse = false );
00101 static bool isSessionRegistered( const SessionID& );
00102 static Session* registerSession( const SessionID& );
00103 static void unregisterSession( const SessionID& );
00104
00105 static int numSessions();
00106
00107 bool isSessionTime()
00108 { return m_sessionTime.isSessionTime(); }
00109 void checkCompId ( bool value )
00110 { m_checkCompId = value; }
00111 void checkLatency ( bool value )
00112 { m_checkLatency = value; }
00113 void setMaxLatency ( int value )
00114 { m_maxLatency = value; }
00115 void setLogonTimeout ( int value )
00116 { m_state.logonTimeout( value ); }
00117 void setLogoutTimeout ( int value )
00118 { m_state.logoutTimeout( value ); }
00119 void setResetOnLogon ( bool value )
00120 { m_resetOnLogon = value; }
00121 void setResetOnLogout ( bool value )
00122 { m_resetOnLogout = value; }
00123 void setResetOnDisconnect( bool value )
00124 { m_resetOnDisconnect = value; }
00125 void setRefreshOnLogon( bool value )
00126 { m_refreshOnLogon = value; }
00127 void setMillisecondsInTimeStamp ( bool value )
00128 { m_millisecondsInTimeStamp = value; }
00129
00130 void setResponder( Responder* pR )
00131 {
00132 if ( !checkSessionTime( UtcTimeStamp() ) )
00133 reset();
00134 m_pResponder = pR;
00135 }
00136
00137 bool send( Message& );
00138 void next();
00139 void next( const std::string&, bool queued = false );
00140 void next( const Message&, bool queued = false );
00141 void disconnect();
00142
00143 long getExpectedSenderNum() { return m_state.getNextSenderMsgSeqNum(); }
00144 long getExpectedTargetNum() { return m_state.getNextTargetMsgSeqNum(); }
00145
00146 Log* getLog() { return &m_state; }
00147 const MessageStore* getStore() { return &m_state; }
00148
00149 private:
00150 typedef std::map < SessionID, Session* > Sessions;
00151 static bool addSession( Session& );
00152 static void removeSession( Session& );
00153
00154 bool send( const std::string& );
00155 bool sendRaw( Message&, int msgSeqNum = 0 );
00156 bool resend( Message& message );
00157
00158 void insertSendingTime( Header& );
00159 void insertOrigSendingTime( Header&,
00160 const UtcTimeStamp& when = UtcTimeStamp () );
00161 void fill( Header& );
00162
00163 bool isGoodTime( const SendingTime& sendingTime )
00164 {
00165 if ( !m_checkLatency ) return true;
00166 UtcTimeStamp now;
00167 return labs( now - sendingTime ) <= m_maxLatency;
00168 }
00169 bool checkSessionTime( const UtcTimeStamp& time )
00170 {
00171 UtcTimeStamp creationTime = m_state.getCreationTime();
00172 return m_sessionTime.isSameSession(time, creationTime);
00173 }
00174 bool isTargetTooHigh( const MsgSeqNum& msgSeqNum )
00175 { return msgSeqNum > ( m_state.getNextTargetMsgSeqNum() ); }
00176 bool isTargetTooLow( const MsgSeqNum& msgSeqNum )
00177 { return msgSeqNum < ( m_state.getNextTargetMsgSeqNum() ); }
00178 bool isCorrectCompID( const SenderCompID& senderCompID,
00179 const TargetCompID& targetCompID )
00180 {
00181 if( !m_checkCompId ) return true;
00182
00183 return
00184 m_sessionID.getSenderCompID().getValue() == targetCompID.getValue()
00185 && m_sessionID.getTargetCompID().getValue() == senderCompID.getValue();
00186 }
00187 bool shouldSendReset();
00188
00189 bool validLogonState( const MsgType& msgType );
00190 void fromCallback( const MsgType& msgType, const Message& msg,
00191 const SessionID& sessionID );
00192
00193 void doBadTime( const Message& msg );
00194 void doBadCompID( const Message& msg );
00195 bool doPossDup( const Message& msg );
00196 bool doTargetTooLow( const Message& msg );
00197 void doTargetTooHigh( const Message& msg );
00198 void nextQueued();
00199 bool nextQueued( int num );
00200
00201 void nextLogon( const Message& );
00202 void nextHeartbeat( const Message& );
00203 void nextTestRequest( const Message& );
00204 void nextLogout( const Message& );
00205 void nextReject( const Message& );
00206 void nextSequenceReset( const Message& );
00207 void nextResendRequest( const Message& );
00208
00209 void generateLogon();
00210 void generateLogon( const Message& );
00211 void generateResendRequest( const BeginString&, const MsgSeqNum& );
00212 void generateSequenceReset( int, int );
00213 void generateHeartbeat();
00214 void generateHeartbeat( const Message& );
00215 void generateTestRequest( const std::string& );
00216 void generateReject( const Message&, int err, int field = 0 );
00217 void generateReject( const Message&, const std::string& );
00218 void generateBusinessReject( const Message&, int err );
00219 void generateLogout( const std::string& text = "" );
00220
00221 void populateRejectReason( Message&, int field, const std::string& );
00222 void populateRejectReason( Message&, const std::string& );
00223
00224 bool verify( const Message& msg,
00225 bool checkTooHigh = true, bool checkTooLow = true );
00226
00227 bool set( int s, const Message& m );
00228 bool get( int s, Message& m ) const;
00229
00230 Application& m_application;
00231 SessionID m_sessionID;
00232 SessionTime m_sessionTime;
00233
00234 bool m_checkCompId;
00235 bool m_checkLatency;
00236 int m_maxLatency;
00237 bool m_resetOnLogon;
00238 bool m_resetOnLogout;
00239 bool m_resetOnDisconnect;
00240 bool m_refreshOnLogon;
00241 bool m_millisecondsInTimeStamp;
00242
00243 SessionState m_state;
00244 DataDictionary m_dataDictionary;
00245 MessageStoreFactory& m_messageStoreFactory;
00246 LogFactory* m_pLogFactory;
00247 Responder* m_pResponder;
00248 Mutex m_mutex;
00249
00250 static Sessions s_sessions;
00251 static Sessions s_registered;
00252 static Mutex s_mutex;
00253
00254 };
00255 }
00256
00257 #endif //FIX_SESSION_H