Repository URL to install this package:
|
Version:
1.15.1 ▾
|
/* -*- C++ -*- */
/****************************************************************************
** Copyright (c) 2001-2014
**
** This file is part of the QuickFIX FIX Engine
**
** This file may be distributed under the terms of the quickfixengine.org
** license as defined by quickfixengine.org and appearing in the file
** LICENSE included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.quickfixengine.org/LICENSE for licensing information.
**
** Contact ask@quickfixengine.org if any conditions of this licensing are
** not clear to you.
**
****************************************************************************/
#ifndef FIX_SESSION_H
#define FIX_SESSION_H
#ifdef _MSC_VER
#pragma warning( disable : 4503 4355 4786 4290 )
#endif
#include "SessionState.h"
#include "TimeRange.h"
#include "SessionID.h"
#include "Responder.h"
#include "Fields.h"
#include "DataDictionaryProvider.h"
#include "Application.h"
#include "Mutex.h"
#include "Log.h"
#include <utility>
#include <map>
#include <queue>
namespace FIX
{
/// Maintains the state and implements the logic of a %FIX %session.
class Session
{
public:
Session( Application&, MessageStoreFactory&,
const SessionID&,
const DataDictionaryProvider&,
const TimeRange&,
int heartBtInt, LogFactory* pLogFactory );
virtual ~Session();
void logon()
{ m_state.enabled( true ); m_state.logoutReason( "" ); }
void logout( const std::string& reason = "" )
{ m_state.enabled( false ); m_state.logoutReason( reason ); }
bool isEnabled()
{ return m_state.enabled(); }
bool sentLogon() { return m_state.sentLogon(); }
bool sentLogout() { return m_state.sentLogout(); }
bool receivedLogon() { return m_state.receivedLogon(); }
bool isLoggedOn() { return receivedLogon() && sentLogon(); }
void reset() throw( IOException )
{ generateLogout(); disconnect(); m_state.reset(); }
void refresh() throw( IOException )
{ m_state.refresh(); }
void setNextSenderMsgSeqNum( int num ) throw( IOException )
{ m_state.setNextSenderMsgSeqNum( num ); }
void setNextTargetMsgSeqNum( int num ) throw( IOException )
{ m_state.setNextTargetMsgSeqNum( num ); }
const SessionID& getSessionID() const
{ return m_sessionID; }
void setDataDictionaryProvider( const DataDictionaryProvider& dataDictionaryProvider )
{ m_dataDictionaryProvider = dataDictionaryProvider; }
const DataDictionaryProvider& getDataDictionaryProvider() const
{ return m_dataDictionaryProvider; }
static bool sendToTarget( Message& message,
const std::string& qualifier = "" )
throw( SessionNotFound );
static bool sendToTarget( Message& message, const SessionID& sessionID )
throw( SessionNotFound );
static bool sendToTarget( Message&,
const SenderCompID& senderCompID,
const TargetCompID& targetCompID,
const std::string& qualifier = "" )
throw( SessionNotFound );
static bool sendToTarget( Message& message,
const std::string& senderCompID,
const std::string& targetCompID,
const std::string& qualifier = "" )
throw( SessionNotFound );
static std::set<SessionID> getSessions();
static bool doesSessionExist( const SessionID& );
static Session* lookupSession( const SessionID& );
static Session* lookupSession( const std::string&, bool reverse = false );
static bool isSessionRegistered( const SessionID& );
static Session* registerSession( const SessionID& );
static void unregisterSession( const SessionID& );
static size_t numSessions();
bool isSessionTime(const UtcTimeStamp& time)
{ return m_sessionTime.isInRange(time); }
bool isLogonTime(const UtcTimeStamp& time)
{ return m_logonTime.isInRange(time); }
bool isInitiator()
{ return m_state.initiate(); }
bool isAcceptor()
{ return !m_state.initiate(); }
const TimeRange& getLogonTime()
{ return m_logonTime; }
void setLogonTime( const TimeRange& value )
{ m_logonTime = value; }
const std::string& getSenderDefaultApplVerID()
{ return m_senderDefaultApplVerID; }
void setSenderDefaultApplVerID( const std::string& senderDefaultApplVerID )
{ m_senderDefaultApplVerID = senderDefaultApplVerID; }
const std::string& getTargetDefaultApplVerID()
{ return m_targetDefaultApplVerID; }
void setTargetDefaultApplVerID( const std::string& targetDefaultApplVerID )
{ m_targetDefaultApplVerID = targetDefaultApplVerID; }
bool getSendRedundantResendRequests()
{ return m_sendRedundantResendRequests; }
void setSendRedundantResendRequests ( bool value )
{ m_sendRedundantResendRequests = value; }
bool getCheckCompId()
{ return m_checkCompId; }
void setCheckCompId ( bool value )
{ m_checkCompId = value; }
bool getCheckLatency()
{ return m_checkLatency; }
void setCheckLatency ( bool value )
{ m_checkLatency = value; }
int getMaxLatency()
{ return m_maxLatency; }
void setMaxLatency ( int value )
{ m_maxLatency = value; }
int getLogonTimeout()
{ return m_state.logonTimeout(); }
void setLogonTimeout ( int value )
{ m_state.logonTimeout( value ); }
int getLogoutTimeout()
{ return m_state.logoutTimeout(); }
void setLogoutTimeout ( int value )
{ m_state.logoutTimeout( value ); }
bool getResetOnLogon()
{ return m_resetOnLogon; }
void setResetOnLogon ( bool value )
{ m_resetOnLogon = value; }
bool getResetOnLogout()
{ return m_resetOnLogout; }
void setResetOnLogout ( bool value )
{ m_resetOnLogout = value; }
bool getResetOnDisconnect()
{ return m_resetOnDisconnect; }
void setResetOnDisconnect( bool value )
{ m_resetOnDisconnect = value; }
bool getRefreshOnLogon()
{ return m_refreshOnLogon; }
void setRefreshOnLogon( bool value )
{ m_refreshOnLogon = value; }
bool getMillisecondsInTimeStamp()
{ return m_millisecondsInTimeStamp; }
void setMillisecondsInTimeStamp ( bool value )
{ m_millisecondsInTimeStamp = value; }
bool getPersistMessages()
{ return m_persistMessages; }
void setPersistMessages ( bool value )
{ m_persistMessages = value; }
bool getValidateLengthAndChecksum()
{ return m_validateLengthAndChecksum; }
void setValidateLengthAndChecksum ( bool value )
{ m_validateLengthAndChecksum = value; }
void setResponder( Responder* pR )
{
if( !checkSessionTime(UtcTimeStamp()) )
reset();
m_pResponder = pR;
}
bool send( Message& );
void next();
void next( const UtcTimeStamp& timeStamp );
void next( const std::string&, const UtcTimeStamp& timeStamp, bool queued = false );
void next( const Message&, const UtcTimeStamp& timeStamp, bool queued = false );
void disconnect();
int getExpectedSenderNum() { return m_state.getNextSenderMsgSeqNum(); }
int getExpectedTargetNum() { return m_state.getNextTargetMsgSeqNum(); }
Log* getLog() { return &m_state; }
const MessageStore* getStore() { return &m_state; }
private:
typedef std::map < SessionID, Session* > Sessions;
typedef std::set < SessionID > SessionIDs;
static bool addSession( Session& );
static void removeSession( Session& );
bool send( const std::string& );
bool sendRaw( Message&, int msgSeqNum = 0 );
bool resend( Message& message );
void persist( const Message&, const std::string& ) throw ( IOException );
void insertSendingTime( Header& );
void insertOrigSendingTime( Header&,
const UtcTimeStamp& when = UtcTimeStamp () );
void fill( Header& );
bool isGoodTime( const SendingTime& sendingTime )
{
if ( !m_checkLatency ) return true;
UtcTimeStamp now;
return labs( now - sendingTime ) <= m_maxLatency;
}
bool checkSessionTime( const UtcTimeStamp& timeStamp )
{
UtcTimeStamp creationTime = m_state.getCreationTime();
return m_sessionTime.isInSameRange( timeStamp, creationTime );
}
bool isTargetTooHigh( const MsgSeqNum& msgSeqNum )
{ return msgSeqNum > ( m_state.getNextTargetMsgSeqNum() ); }
bool isTargetTooLow( const MsgSeqNum& msgSeqNum )
{ return msgSeqNum < ( m_state.getNextTargetMsgSeqNum() ); }
bool isCorrectCompID( const SenderCompID& senderCompID,
const TargetCompID& targetCompID )
{
if( !m_checkCompId ) return true;
return
m_sessionID.getSenderCompID().getValue() == targetCompID.getValue()
&& m_sessionID.getTargetCompID().getValue() == senderCompID.getValue();
}
bool shouldSendReset();
bool validLogonState( const MsgType& msgType );
void fromCallback( const MsgType& msgType, const Message& msg,
const SessionID& sessionID );
void doBadTime( const Message& msg );
void doBadCompID( const Message& msg );
bool doPossDup( const Message& msg );
bool doTargetTooLow( const Message& msg );
void doTargetTooHigh( const Message& msg );
void nextQueued( const UtcTimeStamp& timeStamp );
bool nextQueued( int num, const UtcTimeStamp& timeStamp );
void nextLogon( const Message&, const UtcTimeStamp& timeStamp );
void nextHeartbeat( const Message&, const UtcTimeStamp& timeStamp );
void nextTestRequest( const Message&, const UtcTimeStamp& timeStamp );
void nextLogout( const Message&, const UtcTimeStamp& timeStamp );
void nextReject( const Message&, const UtcTimeStamp& timeStamp );
void nextSequenceReset( const Message&, const UtcTimeStamp& timeStamp );
void nextResendRequest( const Message&, const UtcTimeStamp& timeStamp );
void generateLogon();
void generateLogon( const Message& );
void generateResendRequest( const BeginString&, const MsgSeqNum& );
void generateSequenceReset( int, int );
void generateHeartbeat();
void generateHeartbeat( const Message& );
void generateTestRequest( const std::string& );
void generateReject( const Message&, int err, int field = 0 );
void generateReject( const Message&, const std::string& );
void generateBusinessReject( const Message&, int err, int field = 0 );
void generateLogout( const std::string& text = "" );
void populateRejectReason( Message&, int field, const std::string& );
void populateRejectReason( Message&, const std::string& );
bool verify( const Message& msg,
bool checkTooHigh = true, bool checkTooLow = true );
bool set( int s, const Message& m );
bool get( int s, Message& m ) const;
Application& m_application;
SessionID m_sessionID;
TimeRange m_sessionTime;
TimeRange m_logonTime;
std::string m_senderDefaultApplVerID;
std::string m_targetDefaultApplVerID;
bool m_sendRedundantResendRequests;
bool m_checkCompId;
bool m_checkLatency;
int m_maxLatency;
bool m_resetOnLogon;
bool m_resetOnLogout;
bool m_resetOnDisconnect;
bool m_refreshOnLogon;
bool m_millisecondsInTimeStamp;
bool m_persistMessages;
bool m_validateLengthAndChecksum;
SessionState m_state;
DataDictionaryProvider m_dataDictionaryProvider;
MessageStoreFactory& m_messageStoreFactory;
LogFactory* m_pLogFactory;
Responder* m_pResponder;
Mutex m_mutex;
static Sessions s_sessions;
static SessionIDs s_sessionIDs;
static Sessions s_registered;
static Mutex s_mutex;
};
}
#endif //FIX_SESSION_H