Session.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /* -*- C++ -*- */
  2. /****************************************************************************
  3. ** Copyright (c) 2001-2014
  4. **
  5. ** This file is part of the QuickFIX FIX Engine
  6. **
  7. ** This file may be distributed under the terms of the quickfixengine.org
  8. ** license as defined by quickfixengine.org and appearing in the file
  9. ** LICENSE included in the packaging of this file.
  10. **
  11. ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  12. ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  13. **
  14. ** See http://www.quickfixengine.org/LICENSE for licensing information.
  15. **
  16. ** Contact ask@quickfixengine.org if any conditions of this licensing are
  17. ** not clear to you.
  18. **
  19. ****************************************************************************/
  20. #ifndef FIX_SESSION_H
  21. #define FIX_SESSION_H
  22. #ifdef _MSC_VER
  23. #pragma warning( disable : 4503 4355 4786 4290 )
  24. #endif
  25. #include "SessionState.h"
  26. #include "TimeRange.h"
  27. #include "SessionID.h"
  28. #include "Responder.h"
  29. #include "Fields.h"
  30. #include "DataDictionaryProvider.h"
  31. #include "Application.h"
  32. #include "Mutex.h"
  33. #include "Log.h"
  34. #include <utility>
  35. #include <map>
  36. #include <queue>
  37. namespace FIX
  38. {
  39. /// Maintains the state and implements the logic of a %FIX %session.
  40. class Session
  41. {
  42. public:
  43. Session( Application&, MessageStoreFactory&,
  44. const SessionID&,
  45. const DataDictionaryProvider&,
  46. const TimeRange&,
  47. int heartBtInt, LogFactory* pLogFactory );
  48. virtual ~Session();
  49. void logon()
  50. { m_state.enabled( true ); m_state.logoutReason( "" ); }
  51. void logout( const std::string& reason = "" )
  52. { m_state.enabled( false ); m_state.logoutReason( reason ); }
  53. bool isEnabled()
  54. { return m_state.enabled(); }
  55. bool sentLogon() { return m_state.sentLogon(); }
  56. bool sentLogout() { return m_state.sentLogout(); }
  57. bool receivedLogon() { return m_state.receivedLogon(); }
  58. bool isLoggedOn() { return receivedLogon() && sentLogon(); }
  59. void reset() throw( IOException )
  60. { generateLogout(); disconnect(); m_state.reset(); }
  61. void refresh() throw( IOException )
  62. { m_state.refresh(); }
  63. void setNextSenderMsgSeqNum( int num ) throw( IOException )
  64. { m_state.setNextSenderMsgSeqNum( num ); }
  65. void setNextTargetMsgSeqNum( int num ) throw( IOException )
  66. { m_state.setNextTargetMsgSeqNum( num ); }
  67. const SessionID& getSessionID() const
  68. { return m_sessionID; }
  69. void setDataDictionaryProvider( const DataDictionaryProvider& dataDictionaryProvider )
  70. { m_dataDictionaryProvider = dataDictionaryProvider; }
  71. const DataDictionaryProvider& getDataDictionaryProvider() const
  72. { return m_dataDictionaryProvider; }
  73. static bool sendToTarget( Message& message,
  74. const std::string& qualifier = "" )
  75. throw( SessionNotFound );
  76. static bool sendToTarget( Message& message, const SessionID& sessionID )
  77. throw( SessionNotFound );
  78. static bool sendToTarget( Message&,
  79. const SenderCompID& senderCompID,
  80. const TargetCompID& targetCompID,
  81. const std::string& qualifier = "" )
  82. throw( SessionNotFound );
  83. static bool sendToTarget( Message& message,
  84. const std::string& senderCompID,
  85. const std::string& targetCompID,
  86. const std::string& qualifier = "" )
  87. throw( SessionNotFound );
  88. static std::set<SessionID> getSessions();
  89. static bool doesSessionExist( const SessionID& );
  90. static Session* lookupSession( const SessionID& );
  91. static Session* lookupSession( const std::string&, bool reverse = false );
  92. static bool isSessionRegistered( const SessionID& );
  93. static Session* registerSession( const SessionID& );
  94. static void unregisterSession( const SessionID& );
  95. static int numSessions();
  96. bool isSessionTime(const UtcTimeStamp& time)
  97. { return m_sessionTime.isInRange(time); }
  98. bool isLogonTime(const UtcTimeStamp& time)
  99. { return m_logonTime.isInRange(time); }
  100. bool isInitiator()
  101. { return m_state.initiate(); }
  102. bool isAcceptor()
  103. { return !m_state.initiate(); }
  104. const TimeRange& getLogonTime()
  105. { return m_logonTime; }
  106. void setLogonTime( const TimeRange& value )
  107. { m_logonTime = value; }
  108. const std::string& getSenderDefaultApplVerID()
  109. { return m_senderDefaultApplVerID; }
  110. void setSenderDefaultApplVerID( const std::string& senderDefaultApplVerID )
  111. { m_senderDefaultApplVerID = senderDefaultApplVerID; }
  112. const std::string& getTargetDefaultApplVerID()
  113. { return m_targetDefaultApplVerID; }
  114. void setTargetDefaultApplVerID( const std::string& targetDefaultApplVerID )
  115. { m_targetDefaultApplVerID = targetDefaultApplVerID; }
  116. bool getSendRedundantResendRequests()
  117. { return m_sendRedundantResendRequests; }
  118. void setSendRedundantResendRequests ( bool value )
  119. { m_sendRedundantResendRequests = value; }
  120. bool getCheckCompId()
  121. { return m_checkCompId; }
  122. void setCheckCompId ( bool value )
  123. { m_checkCompId = value; }
  124. bool getCheckLatency()
  125. { return m_checkLatency; }
  126. void setCheckLatency ( bool value )
  127. { m_checkLatency = value; }
  128. int getMaxLatency()
  129. { return m_maxLatency; }
  130. void setMaxLatency ( int value )
  131. { m_maxLatency = value; }
  132. int getLogonTimeout()
  133. { return m_state.logonTimeout(); }
  134. void setLogonTimeout ( int value )
  135. { m_state.logonTimeout( value ); }
  136. int getLogoutTimeout()
  137. { return m_state.logoutTimeout(); }
  138. void setLogoutTimeout ( int value )
  139. { m_state.logoutTimeout( value ); }
  140. bool getResetOnLogon()
  141. { return m_resetOnLogon; }
  142. void setResetOnLogon ( bool value )
  143. { m_resetOnLogon = value; }
  144. bool getResetOnLogout()
  145. { return m_resetOnLogout; }
  146. void setResetOnLogout ( bool value )
  147. { m_resetOnLogout = value; }
  148. bool getResetOnDisconnect()
  149. { return m_resetOnDisconnect; }
  150. void setResetOnDisconnect( bool value )
  151. { m_resetOnDisconnect = value; }
  152. bool getRefreshOnLogon()
  153. { return m_refreshOnLogon; }
  154. void setRefreshOnLogon( bool value )
  155. { m_refreshOnLogon = value; }
  156. bool getMillisecondsInTimeStamp()
  157. { return m_millisecondsInTimeStamp; }
  158. void setMillisecondsInTimeStamp ( bool value )
  159. { m_millisecondsInTimeStamp = value; }
  160. bool getPersistMessages()
  161. { return m_persistMessages; }
  162. void setPersistMessages ( bool value )
  163. { m_persistMessages = value; }
  164. bool getValidateLengthAndChecksum()
  165. { return m_validateLengthAndChecksum; }
  166. void setValidateLengthAndChecksum ( bool value )
  167. { m_validateLengthAndChecksum = value; }
  168. void setResponder( Responder* pR )
  169. {
  170. if( !checkSessionTime(UtcTimeStamp()) )
  171. reset();
  172. m_pResponder = pR;
  173. }
  174. bool send( Message& );
  175. void next();
  176. void next( const UtcTimeStamp& timeStamp );
  177. void next( const std::string&, const UtcTimeStamp& timeStamp, bool queued = false );
  178. void next( const Message&, const UtcTimeStamp& timeStamp, bool queued = false );
  179. void disconnect();
  180. int getExpectedSenderNum() { return m_state.getNextSenderMsgSeqNum(); }
  181. int getExpectedTargetNum() { return m_state.getNextTargetMsgSeqNum(); }
  182. Log* getLog() { return &m_state; }
  183. const MessageStore* getStore() { return &m_state; }
  184. private:
  185. typedef std::map < SessionID, Session* > Sessions;
  186. typedef std::set < SessionID > SessionIDs;
  187. static bool addSession( Session& );
  188. static void removeSession( Session& );
  189. bool send( const std::string& );
  190. bool sendRaw( Message&, int msgSeqNum = 0 );
  191. bool resend( Message& message );
  192. void persist( const Message&, const std::string& ) throw ( IOException );
  193. void insertSendingTime( Header& );
  194. void insertOrigSendingTime( Header&,
  195. const UtcTimeStamp& when = UtcTimeStamp () );
  196. void fill( Header& );
  197. bool isGoodTime( const SendingTime& sendingTime )
  198. {
  199. if ( !m_checkLatency ) return true;
  200. UtcTimeStamp now;
  201. return labs( now - sendingTime ) <= m_maxLatency;
  202. }
  203. bool checkSessionTime( const UtcTimeStamp& timeStamp )
  204. {
  205. UtcTimeStamp creationTime = m_state.getCreationTime();
  206. return m_sessionTime.isInSameRange( timeStamp, creationTime );
  207. }
  208. bool isTargetTooHigh( const MsgSeqNum& msgSeqNum )
  209. { return msgSeqNum > ( m_state.getNextTargetMsgSeqNum() ); }
  210. bool isTargetTooLow( const MsgSeqNum& msgSeqNum )
  211. { return msgSeqNum < ( m_state.getNextTargetMsgSeqNum() ); }
  212. bool isCorrectCompID( const SenderCompID& senderCompID,
  213. const TargetCompID& targetCompID )
  214. {
  215. if( !m_checkCompId ) return true;
  216. return
  217. m_sessionID.getSenderCompID().getValue() == targetCompID.getValue()
  218. && m_sessionID.getTargetCompID().getValue() == senderCompID.getValue();
  219. }
  220. bool shouldSendReset();
  221. bool validLogonState( const MsgType& msgType );
  222. void fromCallback( const MsgType& msgType, const Message& msg,
  223. const SessionID& sessionID );
  224. void doBadTime( const Message& msg );
  225. void doBadCompID( const Message& msg );
  226. bool doPossDup( const Message& msg );
  227. bool doTargetTooLow( const Message& msg );
  228. void doTargetTooHigh( const Message& msg );
  229. void nextQueued( const UtcTimeStamp& timeStamp );
  230. bool nextQueued( int num, const UtcTimeStamp& timeStamp );
  231. void nextLogon( const Message&, const UtcTimeStamp& timeStamp );
  232. void nextHeartbeat( const Message&, const UtcTimeStamp& timeStamp );
  233. void nextTestRequest( const Message&, const UtcTimeStamp& timeStamp );
  234. void nextLogout( const Message&, const UtcTimeStamp& timeStamp );
  235. void nextReject( const Message&, const UtcTimeStamp& timeStamp );
  236. void nextSequenceReset( const Message&, const UtcTimeStamp& timeStamp );
  237. void nextResendRequest( const Message&, const UtcTimeStamp& timeStamp );
  238. void generateLogon();
  239. void generateLogon( const Message& );
  240. void generateResendRequest( const BeginString&, const MsgSeqNum& );
  241. void generateSequenceReset( int, int );
  242. void generateHeartbeat();
  243. void generateHeartbeat( const Message& );
  244. void generateTestRequest( const std::string& );
  245. void generateReject( const Message&, int err, int field = 0 );
  246. void generateReject( const Message&, const std::string& );
  247. void generateBusinessReject( const Message&, int err, int field = 0 );
  248. void generateLogout( const std::string& text = "" );
  249. void populateRejectReason( Message&, int field, const std::string& );
  250. void populateRejectReason( Message&, const std::string& );
  251. bool verify( const Message& msg,
  252. bool checkTooHigh = true, bool checkTooLow = true );
  253. bool set( int s, const Message& m );
  254. bool get( int s, Message& m ) const;
  255. Application& m_application;
  256. SessionID m_sessionID;
  257. TimeRange m_sessionTime;
  258. TimeRange m_logonTime;
  259. std::string m_senderDefaultApplVerID;
  260. std::string m_targetDefaultApplVerID;
  261. bool m_sendRedundantResendRequests;
  262. bool m_checkCompId;
  263. bool m_checkLatency;
  264. int m_maxLatency;
  265. bool m_resetOnLogon;
  266. bool m_resetOnLogout;
  267. bool m_resetOnDisconnect;
  268. bool m_refreshOnLogon;
  269. bool m_millisecondsInTimeStamp;
  270. bool m_persistMessages;
  271. bool m_validateLengthAndChecksum;
  272. SessionState m_state;
  273. DataDictionaryProvider m_dataDictionaryProvider;
  274. MessageStoreFactory& m_messageStoreFactory;
  275. LogFactory* m_pLogFactory;
  276. Responder* m_pResponder;
  277. Mutex m_mutex;
  278. static Sessions s_sessions;
  279. static SessionIDs s_sessionIDs;
  280. static Sessions s_registered;
  281. static Mutex s_mutex;
  282. };
  283. }
  284. #endif //FIX_SESSION_H