Session.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (c) 2001-2014
3 **
4 ** This file is part of the QuickFIX FIX Engine
5 **
6 ** This file may be distributed under the terms of the quickfixengine.org
7 ** license as defined by quickfixengine.org and appearing in the file
8 ** LICENSE included in the packaging of this file.
9 **
10 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12 **
13 ** See http://www.quickfixengine.org/LICENSE for licensing information.
14 **
15 ** Contact ask@quickfixengine.org if any conditions of this licensing are
16 ** not clear to you.
17 **
18 ****************************************************************************/
19 
20 #ifdef _MSC_VER
21 #include "stdafx.h"
22 #else
23 #include "config.h"
24 #endif
25 
26 #include "Session.h"
27 #include "Values.h"
28 #include <algorithm>
29 #include <iostream>
30 
31 namespace FIX
32 {
36 Mutex Session::s_mutex;
37 
38 #define LOGEX( method ) try { method; } catch( std::exception& e ) \
39  { m_state.onEvent( e.what() ); }
40 
42  MessageStoreFactory& messageStoreFactory,
43  const SessionID& sessionID,
44  const DataDictionaryProvider& dataDictionaryProvider,
45  const TimeRange& sessionTime,
46  int heartBtInt, LogFactory* pLogFactory )
47 : m_application( application ),
48  m_sessionID( sessionID ),
49  m_sessionTime( sessionTime ),
50  m_logonTime( sessionTime ),
51  m_senderDefaultApplVerID(ApplVerID_FIX50),
52  m_targetDefaultApplVerID(ApplVerID_FIX50),
53  m_sendRedundantResendRequests( false ),
54  m_checkCompId( true ),
55  m_checkLatency( true ),
56  m_maxLatency( 120 ),
57  m_resetOnLogon( false ),
58  m_resetOnLogout( false ),
59  m_resetOnDisconnect( false ),
60  m_refreshOnLogon( false ),
61  m_millisecondsInTimeStamp( true ),
62  m_persistMessages( true ),
63  m_validateLengthAndChecksum( true ),
64  m_dataDictionaryProvider( dataDictionaryProvider ),
65  m_messageStoreFactory( messageStoreFactory ),
66  m_pLogFactory( pLogFactory ),
67  m_pResponder( 0 )
68 {
69  m_state.heartBtInt( heartBtInt );
70  m_state.initiate( heartBtInt != 0 );
72  if ( m_pLogFactory )
74 
76  reset();
77 
78  addSession( *this );
80  m_state.onEvent( "Created session" );
81 }
82 
84 {
85  removeSession( *this );
87  if ( m_pLogFactory && m_state.log() )
89 }
90 
92 {
93  UtcTimeStamp now;
94  bool showMilliseconds = false;
96  showMilliseconds = true;
97  else
98  showMilliseconds = m_sessionID.getBeginString() >= BeginString_FIX42;
99 
100  header.setField( SendingTime(now, showMilliseconds && m_millisecondsInTimeStamp) );
101 }
102 
104 {
105  bool showMilliseconds = false;
107  showMilliseconds = true;
108  else
109  showMilliseconds = m_sessionID.getBeginString() >= BeginString_FIX42;
110 
111  header.setField( OrigSendingTime(when, showMilliseconds && m_millisecondsInTimeStamp) );
112 }
113 
114 void Session::fill( Header& header )
115 {
116  UtcTimeStamp now;
117  m_state.lastSentTime( now );
118  header.setField( m_sessionID.getBeginString() );
121  header.setField( MsgSeqNum( getExpectedSenderNum() ) );
122  insertSendingTime( header );
123 }
124 
126 {
127  next( UtcTimeStamp() );
128 }
129 
130 void Session::next( const UtcTimeStamp& timeStamp )
131 {
132  try
133  {
134  if ( !checkSessionTime(timeStamp) )
135  { reset(); return; }
136 
137  if( !isEnabled() || !isLogonTime(timeStamp) )
138  {
139  if( isLoggedOn() )
140  {
141  if( !m_state.sentLogout() )
142  {
143  m_state.onEvent( "Initiated logout request" );
145  }
146  }
147  else
148  return;
149  }
150 
151  if ( !m_state.receivedLogon() )
152  {
153  if ( m_state.shouldSendLogon() && isLogonTime(timeStamp) )
154  {
155  generateLogon();
156  m_state.onEvent( "Initiated logon request" );
157  }
158  else if ( m_state.alreadySentLogon() && m_state.logonTimedOut() )
159  {
160  m_state.onEvent( "Timed out waiting for logon response" );
161  disconnect();
162  }
163  return ;
164  }
165 
166  if ( m_state.heartBtInt() == 0 ) return ;
167 
168  if ( m_state.logoutTimedOut() )
169  {
170  m_state.onEvent( "Timed out waiting for logout response" );
171  disconnect();
172  }
173 
174  if ( m_state.withinHeartBeat() ) return ;
175 
176  if ( m_state.timedOut() )
177  {
178  m_state.onEvent( "Timed out waiting for heartbeat" );
179  disconnect();
180  }
181  else
182  {
183  if ( m_state.needTestRequest() )
184  {
185  generateTestRequest( "TEST" );
187  m_state.onEvent( "Sent test request TEST" );
188  }
189  else if ( m_state.needHeartbeat() )
190  {
192  }
193  }
194  }
195  catch ( FIX::IOException& e )
196  {
197  m_state.onEvent( e.what() );
198  disconnect();
199  }
200 }
201 
202 void Session::nextLogon( const Message& logon, const UtcTimeStamp& timeStamp )
203 {
204  SenderCompID senderCompID;
205  TargetCompID targetCompID;
206  logon.getHeader().getField( senderCompID );
207  logon.getHeader().getField( targetCompID );
208 
209  if( m_refreshOnLogon )
210  refresh();
211 
212  if( !isEnabled() )
213  {
214  m_state.onEvent( "Session is not enabled for logon" );
215  disconnect();
216  return;
217  }
218 
219  if( !isLogonTime(timeStamp) )
220  {
221  m_state.onEvent( "Received logon outside of valid logon time" );
222  disconnect();
223  return;
224  }
225 
226  ResetSeqNumFlag resetSeqNumFlag(false);
227  logon.getFieldIfSet(resetSeqNumFlag);
228  m_state.receivedReset( resetSeqNumFlag );
229 
230  if( m_state.receivedReset() )
231  {
232  m_state.onEvent( "Logon contains ResetSeqNumFlag=Y, reseting sequence numbers to 1" );
233  if( !m_state.sentReset() ) m_state.reset();
234  }
235 
237  {
238  m_state.onEvent( "Received logon response before sending request" );
239  disconnect();
240  return;
241  }
242 
243  if( !m_state.initiate() && m_resetOnLogon )
244  m_state.reset();
245 
246  if( !verify( logon, false, true ) )
247  return;
248  m_state.receivedLogon( true );
249 
250  if ( !m_state.initiate()
251  || (m_state.receivedReset() && !m_state.sentReset()) )
252  {
254  m_state.onEvent( "Received logon request" );
255  generateLogon( logon );
256  m_state.onEvent( "Responding to logon request" );
257  }
258  else
259  m_state.onEvent( "Received logon response" );
260 
261  m_state.sentReset( false );
262  m_state.receivedReset( false );
263 
264  MsgSeqNum msgSeqNum;
265  logon.getHeader().getField( msgSeqNum );
266  if ( isTargetTooHigh( msgSeqNum ) && !resetSeqNumFlag )
267  {
268  doTargetTooHigh( logon );
269  }
270  else
271  {
273  nextQueued( timeStamp );
274  }
275 
276  if ( isLoggedOn() )
278 }
279 
280 void Session::nextHeartbeat( const Message& heartbeat, const UtcTimeStamp& timeStamp )
281 {
282  if ( !verify( heartbeat ) ) return ;
284  nextQueued( timeStamp );
285 }
286 
287 void Session::nextTestRequest( const Message& testRequest, const UtcTimeStamp& timeStamp )
288 {
289  if ( !verify( testRequest ) ) return ;
290  generateHeartbeat( testRequest );
292  nextQueued( timeStamp );
293 }
294 
295 void Session::nextLogout( const Message& logout, const UtcTimeStamp& timeStamp )
296 {
297  if ( !verify( logout, false, false ) ) return ;
298  if ( !m_state.sentLogout() )
299  {
300  m_state.onEvent( "Received logout request" );
301  generateLogout();
302  m_state.onEvent( "Sending logout response" );
303  }
304  else
305  m_state.onEvent( "Received logout response" );
306 
308  if ( m_resetOnLogout ) m_state.reset();
309  disconnect();
310 }
311 
312 void Session::nextReject( const Message& reject, const UtcTimeStamp& timeStamp )
313 {
314  if ( !verify( reject, false, true ) ) return ;
316  nextQueued( timeStamp );
317 }
318 
319 void Session::nextSequenceReset( const Message& sequenceReset, const UtcTimeStamp& timeStamp )
320 {
321  bool isGapFill = false;
322  GapFillFlag gapFillFlag;
323  if ( sequenceReset.getFieldIfSet( gapFillFlag ) )
324  {
325  isGapFill = gapFillFlag;
326  }
327 
328  if ( !verify( sequenceReset, isGapFill, isGapFill ) ) return ;
329 
330  NewSeqNo newSeqNo;
331  if ( sequenceReset.getFieldIfSet( newSeqNo ) )
332  {
333  m_state.onEvent( "Received SequenceReset FROM: "
335  " TO: " + IntConvertor::convert( newSeqNo ) );
336 
337  if ( newSeqNo > getExpectedTargetNum() )
339  else if ( newSeqNo < getExpectedTargetNum() )
341  }
342 }
343 
344 void Session::nextResendRequest( const Message& resendRequest, const UtcTimeStamp& timeStamp )
345 {
346  if ( !verify( resendRequest, false, false ) ) return ;
347 
348  Locker l( m_mutex );
349 
350  BeginSeqNo beginSeqNo;
351  EndSeqNo endSeqNo;
352  resendRequest.getField( beginSeqNo );
353  resendRequest.getField( endSeqNo );
354 
355  m_state.onEvent( "Received ResendRequest FROM: "
356  + IntConvertor::convert( beginSeqNo ) +
357  " TO: " + IntConvertor::convert( endSeqNo ) );
358 
359  std::string beginString = m_sessionID.getBeginString();
360  if ( (beginString >= FIX::BeginString_FIX42 && endSeqNo == 0) ||
361  (beginString <= FIX::BeginString_FIX42 && endSeqNo == 999999) ||
362  (endSeqNo >= getExpectedSenderNum()) )
363  { endSeqNo = getExpectedSenderNum() - 1; }
364 
365  if ( !m_persistMessages )
366  {
367  endSeqNo = EndSeqNo(endSeqNo + 1);
369  if( endSeqNo > next )
370  endSeqNo = EndSeqNo(next);
371  generateSequenceReset( beginSeqNo, endSeqNo );
372  return;
373  }
374 
375  std::vector < std::string > messages;
376  m_state.get( beginSeqNo, endSeqNo, messages );
377 
378  std::vector < std::string > ::iterator i;
379  MsgSeqNum msgSeqNum(0);
380  MsgType msgType;
381  int begin = 0;
382  int current = beginSeqNo;
383  std::string messageString;
384  Message msg;
385 
386  for ( i = messages.begin(); i != messages.end(); ++i )
387  {
388  const DataDictionary& sessionDD =
390 
391  if( m_sessionID.isFIXT() )
392  {
393  msg.setStringHeader(*i);
394  ApplVerID applVerID;
395  if( !msg.getHeader().getFieldIfSet(applVerID) )
396  applVerID = m_senderDefaultApplVerID;
397 
398  const DataDictionary& applicationDD =
400  msg = Message( *i, sessionDD, applicationDD, m_validateLengthAndChecksum );
401  }
402  else
403  {
404  msg = Message( *i, sessionDD, m_validateLengthAndChecksum );
405  }
406 
407 
408  msg.getHeader().getField( msgSeqNum );
409  msg.getHeader().getField( msgType );
410 
411  if( (current != msgSeqNum) && !begin )
412  begin = current;
413 
414  if ( Message::isAdminMsgType( msgType ) )
415  {
416  if ( !begin ) begin = msgSeqNum;
417  }
418  else
419  {
420  if ( resend( msg ) )
421  {
422  if ( begin ) generateSequenceReset( begin, msgSeqNum );
423  send( msg.toString(messageString) );
424  m_state.onEvent( "Resending Message: "
425  + IntConvertor::convert( msgSeqNum ) );
426  begin = 0;
427  }
428  else
429  { if ( !begin ) begin = msgSeqNum; }
430  }
431  current = msgSeqNum + 1;
432  }
433  if ( begin )
434  {
435  generateSequenceReset( begin, msgSeqNum + 1 );
436  }
437 
438  if ( endSeqNo > msgSeqNum )
439  {
440  endSeqNo = EndSeqNo(endSeqNo + 1);
442  if( endSeqNo > next )
443  endSeqNo = EndSeqNo(next);
444  generateSequenceReset( beginSeqNo, endSeqNo );
445  }
446 
447  resendRequest.getHeader().getField( msgSeqNum );
448  if( !isTargetTooHigh(msgSeqNum) && !isTargetTooLow(msgSeqNum) )
450 }
451 
452 bool Session::send( Message& message )
453 {
456  return sendRaw( message );
457 }
458 
459 bool Session::sendRaw( Message& message, int num )
460 {
461  Locker l( m_mutex );
462 
463  try
464  {
465  Header& header = message.getHeader();
466 
467  MsgType msgType;
468  header.getFieldIfSet(msgType);
469 
470  fill( header );
471  std::string messageString;
472 
473  if ( num )
474  header.setField( MsgSeqNum( num ) );
475 
476  if ( Message::isAdminMsgType( msgType ) )
477  {
478  m_application.toAdmin( message, m_sessionID );
479 
480  if( msgType == "A" && !m_state.receivedReset() )
481  {
482  ResetSeqNumFlag resetSeqNumFlag( false );
483  message.getFieldIfSet(resetSeqNumFlag);
484 
485  if( resetSeqNumFlag )
486  {
487  m_state.reset();
489  }
490  m_state.sentReset( resetSeqNumFlag );
491  }
492 
493  message.toString( messageString );
494 
495  if( !num )
496  persist( message, messageString );
497 
498  if (
499  msgType == "A" || msgType == "5"
500  || msgType == "2" || msgType == "4"
501  || isLoggedOn() )
502  {
503  send( messageString );
504  }
505  }
506  else
507  {
508  // do not send application messages if they will just be cleared
509  if( !isLoggedOn() && shouldSendReset() )
510  return false;
511 
512  try
513  {
514  m_application.toApp( message, m_sessionID );
515  message.toString( messageString );
516 
517  if( !num )
518  persist( message, messageString );
519 
520  if ( isLoggedOn() )
521  send( messageString );
522  }
523  catch ( DoNotSend& ) { return false; }
524  }
525 
526  return true;
527  }
528  catch ( IOException& e )
529  {
530  m_state.onEvent( e.what() );
531  return false;
532  }
533 }
534 
535 bool Session::send( const std::string& string )
536 {
537  if ( !m_pResponder ) return false;
538  m_state.onOutgoing( string );
539  return m_pResponder->send( string );
540 }
541 
543 {
544  Locker l(m_mutex);
545 
546  if ( m_pResponder )
547  {
548  m_state.onEvent( "Disconnecting" );
549 
551  m_pResponder = 0;
552  }
553 
554  if ( m_state.receivedLogon() || m_state.sentLogon() )
555  {
556  m_state.receivedLogon( false );
557  m_state.sentLogon( false );
559  }
560 
561  m_state.sentLogout( false );
562  m_state.receivedReset( false );
563  m_state.sentReset( false );
566  if ( m_resetOnDisconnect )
567  m_state.reset();
568 
569  m_state.resendRange( 0, 0 );
570 }
571 
572 bool Session::resend( Message& message )
573 {
574  SendingTime sendingTime;
575  MsgSeqNum msgSeqNum;
576  Header& header = message.getHeader();
577  header.getField( sendingTime );
578  header.getField( msgSeqNum );
579  insertOrigSendingTime( header, sendingTime );
580  header.setField( PossDupFlag( true ) );
581  insertSendingTime( header );
582 
583  try
584  {
585  m_application.toApp( message, m_sessionID );
586  return true;
587  }
588  catch ( DoNotSend& )
589  { return false; }
590 }
591 
592 void Session::persist( const Message& message, const std::string& messageString )
593 throw ( IOException )
594 {
595  MsgSeqNum msgSeqNum;
596  message.getHeader().getField( msgSeqNum );
597  if( m_persistMessages )
598  m_state.set( msgSeqNum, messageString );
600 }
601 
603 {
604  Message logon;
605  logon.getHeader().setField( MsgType( "A" ) );
606  logon.setField( EncryptMethod( 0 ) );
607  logon.setField( m_state.heartBtInt() );
608  if( m_sessionID.isFIXT() )
610  if( m_refreshOnLogon )
611  refresh();
612  if( m_resetOnLogon )
613  m_state.reset();
614  if( shouldSendReset() )
615  logon.setField( ResetSeqNumFlag(true) );
616 
617  fill( logon.getHeader() );
618  UtcTimeStamp now;
619  m_state.lastReceivedTime( now );
620  m_state.testRequest( 0 );
621  m_state.sentLogon( true );
622  sendRaw( logon );
623 }
624 
625 void Session::generateLogon( const Message& aLogon )
626 {
627  Message logon;
628  EncryptMethod encryptMethod;
629  HeartBtInt heartBtInt;
630  logon.setField( EncryptMethod( 0 ) );
631  if( m_sessionID.isFIXT() )
633  if( m_state.receivedReset() )
634  logon.setField( ResetSeqNumFlag(true) );
635  aLogon.getField( heartBtInt );
636  logon.getHeader().setField( MsgType( "A" ) );
637  logon.setField( heartBtInt );
638  fill( logon.getHeader() );
639  sendRaw( logon );
640  m_state.sentLogon( true );
641 }
642 
643 void Session::generateResendRequest( const BeginString& beginString, const MsgSeqNum& msgSeqNum )
644 {
645  Message resendRequest;
646  BeginSeqNo beginSeqNo( ( int ) getExpectedTargetNum() );
647  EndSeqNo endSeqNo( msgSeqNum - 1 );
648  if ( beginString >= FIX::BeginString_FIX42 )
649  endSeqNo = 0;
650  else if( beginString <= FIX::BeginString_FIX41 )
651  endSeqNo = 999999;
652  resendRequest.getHeader().setField( MsgType( "2" ) );
653  resendRequest.setField( beginSeqNo );
654  resendRequest.setField( endSeqNo );
655  fill( resendRequest.getHeader() );
656  sendRaw( resendRequest );
657 
658  m_state.onEvent( "Sent ResendRequest FROM: "
659  + IntConvertor::convert( beginSeqNo ) +
660  " TO: " + IntConvertor::convert( endSeqNo ) );
661 
662  m_state.resendRange( beginSeqNo, msgSeqNum - 1 );
663 }
664 
666 ( int beginSeqNo, int endSeqNo )
667 {
668  Message sequenceReset;
669  NewSeqNo newSeqNo( endSeqNo );
670  sequenceReset.getHeader().setField( MsgType( "4" ) );
671  sequenceReset.getHeader().setField( PossDupFlag( true ) );
672  sequenceReset.setField( newSeqNo );
673  fill( sequenceReset.getHeader() );
674 
675  SendingTime sendingTime;
676  sequenceReset.getHeader().getField( sendingTime );
677  insertOrigSendingTime( sequenceReset.getHeader(), sendingTime );
678  sequenceReset.getHeader().setField( MsgSeqNum( beginSeqNo ) );
679  sequenceReset.setField( GapFillFlag( true ) );
680  sendRaw( sequenceReset, beginSeqNo );
681  m_state.onEvent( "Sent SequenceReset TO: "
682  + IntConvertor::convert( newSeqNo ) );
683 }
684 
686 {
687  Message heartbeat;
688  heartbeat.getHeader().setField( MsgType( "0" ) );
689  fill( heartbeat.getHeader() );
690  sendRaw( heartbeat );
691 }
692 
693 void Session::generateHeartbeat( const Message& testRequest )
694 {
695  Message heartbeat;
696  heartbeat.getHeader().setField( MsgType( "0" ) );
697  fill( heartbeat.getHeader() );
698  try
699  {
700  TestReqID testReqID;
701  testRequest.getField( testReqID );
702  heartbeat.setField( testReqID );
703  }
704  catch ( FieldNotFound& ) {}
705 
706  sendRaw( heartbeat );
707 }
708 
709 void Session::generateTestRequest( const std::string& id )
710 {
711  Message testRequest;
712  testRequest.getHeader().setField( MsgType( "1" ) );
713  fill( testRequest.getHeader() );
714  TestReqID testReqID( id );
715  testRequest.setField( testReqID );
716 
717  sendRaw( testRequest );
718 }
719 
720 void Session::generateReject( const Message& message, int err, int field )
721 {
722  std::string beginString = m_sessionID.getBeginString();
723 
724  Message reject;
725  reject.getHeader().setField( MsgType( "3" ) );
726  reject.reverseRoute( message.getHeader() );
727  fill( reject.getHeader() );
728 
729  MsgSeqNum msgSeqNum;
730  MsgType msgType;
731 
732  message.getHeader().getField( msgType );
733  if( message.getHeader().getFieldIfSet( msgSeqNum ) )
734  {
735  if( msgSeqNum.getString() != "" )
736  reject.setField( RefSeqNum( msgSeqNum ) );
737  }
738 
739  if ( beginString >= FIX::BeginString_FIX42 )
740  {
741  if( msgType.getString() != "" )
742  reject.setField( RefMsgType( msgType ) );
743  if ( (beginString == FIX::BeginString_FIX42
745  || beginString > FIX::BeginString_FIX42 )
746  {
747  reject.setField( SessionRejectReason( err ) );
748  }
749  }
750  if ( msgType != MsgType_Logon && msgType != MsgType_SequenceReset
751  && msgSeqNum == getExpectedTargetNum() )
753 
754  const char* reason = 0;
755  switch ( err )
756  {
759  break;
762  break;
765  break;
768  break;
771  break;
774  break;
777  break;
780  break;
783  break;
786  break;
789  break;
792  };
793 
794  if ( reason && ( field || err == SessionRejectReason_INVALID_TAG_NUMBER ) )
795  {
796  populateRejectReason( reject, field, reason );
797  m_state.onEvent( "Message " + msgSeqNum.getString() + " Rejected: "
798  + reason + ":" + IntConvertor::convert( field ) );
799  }
800  else if ( reason )
801  {
802  populateRejectReason( reject, reason );
803  m_state.onEvent( "Message " + msgSeqNum.getString()
804  + " Rejected: " + reason );
805  }
806  else
807  m_state.onEvent( "Message " + msgSeqNum.getString() + " Rejected" );
808 
809  if ( !m_state.receivedLogon() )
810  throw std::runtime_error( "Tried to send a reject while not logged on" );
811 
812  sendRaw( reject );
813 }
814 
815 void Session::generateReject( const Message& message, const std::string& str )
816 {
817  std::string beginString = m_sessionID.getBeginString();
818 
819  Message reject;
820  reject.getHeader().setField( MsgType( "3" ) );
821  reject.reverseRoute( message.getHeader() );
822  fill( reject.getHeader() );
823 
824  MsgType msgType;
825  MsgSeqNum msgSeqNum;
826 
827  message.getHeader().getField( msgType );
828  message.getHeader().getField( msgSeqNum );
829  if ( beginString >= FIX::BeginString_FIX42 )
830  reject.setField( RefMsgType( msgType ) );
831  reject.setField( RefSeqNum( msgSeqNum ) );
832 
833  if ( msgType != MsgType_Logon && msgType != MsgType_SequenceReset )
835 
836  reject.setField( Text( str ) );
837  sendRaw( reject );
838  m_state.onEvent( "Message " + msgSeqNum.getString()
839  + " Rejected: " + str );
840 }
841 
842 void Session::generateBusinessReject( const Message& message, int err, int field )
843 {
844  Message reject;
846  if( m_sessionID.isFIXT() )
848  fill( reject.getHeader() );
849  MsgType msgType;
850  MsgSeqNum msgSeqNum;
851  message.getHeader().getField( msgType );
852  message.getHeader().getField( msgSeqNum );
853  reject.setField( RefMsgType( msgType ) );
854  reject.setField( RefSeqNum( msgSeqNum ) );
855  reject.setField( BusinessRejectReason( err ) );
857 
858  const char* reason = 0;
859  switch ( err )
860  {
863  break;
866  break;
869  break;
872  break;
875  break;
878  break;
881  break;
884  break;
885  };
886 
887  if ( reason && field )
888  {
889  populateRejectReason( reject, field, reason );
890  m_state.onEvent( "Message " + msgSeqNum.getString() + " Rejected: "
891  + reason + ":" + IntConvertor::convert( field ) );
892  }
893  else if ( reason )
894  {
895  populateRejectReason( reject, reason );
896  m_state.onEvent( "Message " + msgSeqNum.getString()
897  + " Rejected: " + reason );
898  }
899  else
900  m_state.onEvent( "Message " + msgSeqNum.getString() + " Rejected" );
901 
902  sendRaw( reject );
903 }
904 
905 void Session::generateLogout( const std::string& text )
906 {
907  Message logout;
908  logout.getHeader().setField( MsgType( MsgType_Logout ) );
909  fill( logout.getHeader() );
910  if ( text.length() )
911  logout.setField( Text( text ) );
912  sendRaw( logout );
913  m_state.sentLogout( true );
914 }
915 
916 void Session::populateRejectReason( Message& reject, int field,
917  const std::string& text )
918 {
919  MsgType msgType;
920  reject.getHeader().getField( msgType );
921 
922  if ( msgType == MsgType_Reject
924  {
925  reject.setField( RefTagID( field ) );
926  reject.setField( Text( text ) );
927  }
928  else
929  {
930  std::stringstream stream;
931  stream << text << " (" << field << ")";
932  reject.setField( Text( stream.str() ) );
933  }
934 }
935 
936 void Session::populateRejectReason( Message& reject, const std::string& text )
937 {
938  reject.setField( Text( text ) );
939 }
940 
941 bool Session::verify( const Message& msg, bool checkTooHigh,
942  bool checkTooLow )
943 {
944  const MsgType* pMsgType = 0;
945  const MsgSeqNum* pMsgSeqNum = 0;
946 
947  try
948  {
949  const Header& header = msg.getHeader();
950 
951  pMsgType = FIELD_GET_PTR( header, MsgType );
952  const SenderCompID& senderCompID = FIELD_GET_REF( header, SenderCompID );
953  const TargetCompID& targetCompID = FIELD_GET_REF( header, TargetCompID );
954  const SendingTime& sendingTime = FIELD_GET_REF( header, SendingTime );
955 
956  if( checkTooHigh || checkTooLow )
957  pMsgSeqNum = FIELD_GET_PTR( header, MsgSeqNum );
958 
959  if ( !validLogonState( *pMsgType ) )
960  throw std::logic_error( "Logon state is not valid for message" );
961 
962  if ( !isGoodTime( sendingTime ) )
963  {
964  doBadTime( msg );
965  return false;
966  }
967  if ( !isCorrectCompID( senderCompID, targetCompID ) )
968  {
969  doBadCompID( msg );
970  return false;
971  }
972 
973  if ( checkTooHigh && isTargetTooHigh( *pMsgSeqNum ) )
974  {
975  doTargetTooHigh( msg );
976  return false;
977  }
978  else if ( checkTooLow && isTargetTooLow( *pMsgSeqNum ) )
979  {
980  doTargetTooLow( msg );
981  return false;
982  }
983 
984  if ( (checkTooHigh || checkTooLow) && m_state.resendRequested() )
985  {
987 
988  if ( *pMsgSeqNum >= range.second )
989  {
990  m_state.onEvent ("ResendRequest for messages FROM: " +
991  IntConvertor::convert (range.first) + " TO: " +
992  IntConvertor::convert (range.second) +
993  " has been satisfied.");
994  m_state.resendRange (0, 0);
995  }
996  }
997  }
998  catch ( std::exception& e )
999  {
1000  m_state.onEvent( e.what() );
1001  disconnect();
1002  return false;
1003  }
1004 
1005  UtcTimeStamp now;
1006  m_state.lastReceivedTime( now );
1007  m_state.testRequest( 0 );
1008 
1009  fromCallback( pMsgType ? *pMsgType : MsgType(), msg, m_sessionID );
1010  return true;
1011 }
1012 
1014 {
1015  std::string beginString = m_sessionID.getBeginString();
1016  return beginString >= FIX::BeginString_FIX41
1017  && ( m_resetOnLogon ||
1018  m_resetOnLogout ||
1020  && ( getExpectedSenderNum() == 1 )
1021  && ( getExpectedTargetNum() == 1 );
1022 }
1023 
1024 bool Session::validLogonState( const MsgType& msgType )
1025 {
1026  if ( (msgType == MsgType_Logon && m_state.sentReset())
1027  || (m_state.receivedReset()) )
1028  return true;
1029  if ( (msgType == MsgType_Logon && !m_state.receivedLogon())
1030  || (msgType != MsgType_Logon && m_state.receivedLogon()) )
1031  return true;
1032  if ( msgType == MsgType_Logout && m_state.sentLogon() )
1033  return true;
1034  if ( msgType != MsgType_Logout && m_state.sentLogout() )
1035  return true;
1036  if ( msgType == MsgType_SequenceReset )
1037  return true;
1038  if ( msgType == MsgType_Reject )
1039  return true;
1040 
1041  return false;
1042 }
1043 
1044 void Session::fromCallback( const MsgType& msgType, const Message& msg,
1045  const SessionID& sessionID )
1046 {
1047  if ( Message::isAdminMsgType( msgType ) )
1049  else
1051 }
1052 
1053 void Session::doBadTime( const Message& msg )
1054 {
1056  generateLogout();
1057 }
1058 
1059 void Session::doBadCompID( const Message& msg )
1060 {
1062  generateLogout();
1063 }
1064 
1065 bool Session::doPossDup( const Message& msg )
1066 {
1067  const Header & header = msg.getHeader();
1068  OrigSendingTime origSendingTime;
1069  SendingTime sendingTime;
1070  MsgType msgType;
1071 
1072  header.getField( msgType );
1073  header.getField( sendingTime );
1074 
1075  if ( msgType != MsgType_SequenceReset )
1076  {
1077  if ( !header.getFieldIfSet( origSendingTime ) )
1078  {
1079  generateReject( msg, SessionRejectReason_REQUIRED_TAG_MISSING, origSendingTime.getField() );
1080  return false;
1081  }
1082 
1083  if ( origSendingTime > sendingTime )
1084  {
1086  generateLogout();
1087  return false;
1088  }
1089  }
1090  return true;
1091 }
1092 
1094 {
1095  const Header & header = msg.getHeader();
1096  PossDupFlag possDupFlag(false);
1097  MsgSeqNum msgSeqNum;
1098  header.getFieldIfSet(possDupFlag);
1099  header.getField( msgSeqNum );
1100 
1101  if ( !possDupFlag )
1102  {
1103  std::stringstream stream;
1104  stream << "MsgSeqNum too low, expecting " << getExpectedTargetNum()
1105  << " but received " << msgSeqNum;
1106  generateLogout( stream.str() );
1107  throw std::logic_error( stream.str() );
1108  }
1109 
1110  return doPossDup( msg );
1111 }
1112 
1114 {
1115  const Header & header = msg.getHeader();
1116  BeginString beginString;
1117  MsgSeqNum msgSeqNum;
1118  header.getField( beginString );
1119  header.getField( msgSeqNum );
1120 
1121  m_state.onEvent( "MsgSeqNum too high, expecting "
1123  + " but received "
1124  + IntConvertor::convert( msgSeqNum ) );
1125 
1126  m_state.queue( msgSeqNum, msg );
1127 
1128  if( m_state.resendRequested() )
1129  {
1131 
1132  if( !m_sendRedundantResendRequests && msgSeqNum >= range.first )
1133  {
1134  m_state.onEvent ("Already sent ResendRequest FROM: " +
1135  IntConvertor::convert (range.first) + " TO: " +
1136  IntConvertor::convert (range.second) +
1137  ". Not sending another.");
1138  return;
1139  }
1140  }
1141 
1142  generateResendRequest( beginString, msgSeqNum );
1143 }
1144 
1145 void Session::nextQueued( const UtcTimeStamp& timeStamp )
1146 {
1147  while ( nextQueued( getExpectedTargetNum(), timeStamp ) ) {}
1148 }
1149 
1150 bool Session::nextQueued( int num, const UtcTimeStamp& timeStamp )
1151 {
1152  Message msg;
1153  MsgType msgType;
1154 
1155  if( m_state.retrieve( num, msg ) )
1156  {
1157  m_state.onEvent( "Processing QUEUED message: "
1158  + IntConvertor::convert( num ) );
1159  msg.getHeader().getField( msgType );
1160  if( msgType == MsgType_Logon
1161  || msgType == MsgType_ResendRequest )
1162  {
1164  }
1165  else
1166  {
1167  next( msg, timeStamp, true );
1168  }
1169  return true;
1170  }
1171  return false;
1172 }
1173 
1174 void Session::next( const std::string& msg, const UtcTimeStamp& timeStamp, bool queued )
1175 {
1176  try
1177  {
1178  m_state.onIncoming( msg );
1179  const DataDictionary& sessionDD =
1181  if( m_sessionID.isFIXT() )
1182  {
1183  const DataDictionary& applicationDD =
1185  next( Message( msg, sessionDD, applicationDD, m_validateLengthAndChecksum ), timeStamp, queued );
1186  }
1187  else
1188  {
1189  next( Message( msg, sessionDD, m_validateLengthAndChecksum ), timeStamp, queued );
1190  }
1191  }
1192  catch( InvalidMessage& e )
1193  {
1194  m_state.onEvent( e.what() );
1195 
1196  try
1197  {
1198  if( identifyType(msg) == MsgType_Logon )
1199  {
1200  m_state.onEvent( "Logon message is not valid" );
1201  disconnect();
1202  }
1203  } catch( MessageParseError& ) {}
1204  throw e;
1205  }
1206 }
1207 
1208 void Session::next( const Message& message, const UtcTimeStamp& timeStamp, bool queued )
1209 {
1210  const Header& header = message.getHeader();
1211 
1212  try
1213  {
1214  if ( !checkSessionTime(timeStamp) )
1215  { reset(); return; }
1216 
1217  const MsgType& msgType = FIELD_GET_REF( header, MsgType );
1218  const BeginString& beginString = FIELD_GET_REF( header, BeginString );
1219  // make sure these fields are present
1222 
1223  if ( beginString != m_sessionID.getBeginString() )
1224  throw UnsupportedVersion();
1225 
1226  if( msgType == MsgType_Logon )
1227  {
1228  if( m_sessionID.isFIXT() )
1229  {
1230  const DefaultApplVerID& applVerID = FIELD_GET_REF( message, DefaultApplVerID );
1231  setTargetDefaultApplVerID(applVerID);
1232  }
1233  else
1234  {
1236  }
1237  }
1238 
1239  const DataDictionary& sessionDataDictionary =
1241 
1242  if( m_sessionID.isFIXT() && message.isApp() )
1243  {
1244  ApplVerID applVerID = m_targetDefaultApplVerID;
1245  header.getFieldIfSet(applVerID);
1246  const DataDictionary& applicationDataDictionary =
1248  DataDictionary::validate( message, &sessionDataDictionary, &applicationDataDictionary );
1249  }
1250  else
1251  {
1252  sessionDataDictionary.validate( message );
1253  }
1254 
1255  if ( msgType == MsgType_Logon )
1256  nextLogon( message, timeStamp );
1257  else if ( msgType == MsgType_Heartbeat )
1258  nextHeartbeat( message, timeStamp );
1259  else if ( msgType == MsgType_TestRequest )
1260  nextTestRequest( message, timeStamp );
1261  else if ( msgType == MsgType_SequenceReset )
1262  nextSequenceReset( message, timeStamp );
1263  else if ( msgType == MsgType_Logout )
1264  nextLogout( message, timeStamp );
1265  else if ( msgType == MsgType_ResendRequest )
1266  nextResendRequest( message,timeStamp );
1267  else if ( msgType == MsgType_Reject )
1268  nextReject( message, timeStamp );
1269  else
1270  {
1271  if ( !verify( message ) ) return ;
1273  }
1274  }
1275  catch ( MessageParseError& e )
1276  { m_state.onEvent( e.what() ); }
1277  catch ( RequiredTagMissing & e )
1279  catch ( FieldNotFound & e )
1280  {
1281  if( header.getField(FIELD::BeginString) >= FIX::BeginString_FIX42 && message.isApp() )
1282  {
1284  }
1285  else
1286  {
1288  if ( header.getField(FIELD::MsgType) == MsgType_Logon )
1289  {
1290  m_state.onEvent( "Required field missing from logon" );
1291  disconnect();
1292  }
1293  }
1294  }
1295  catch ( InvalidTagNumber & e )
1297  catch ( NoTagValue & e )
1299  catch ( TagNotDefinedForMessage & e )
1301  catch ( InvalidMessageType& )
1303  catch ( UnsupportedMessageType& )
1304  {
1307  else
1308  { LOGEX( generateReject( message, "Unsupported message type" ) ); }
1309  }
1310  catch ( TagOutOfOrder & e )
1312  catch ( IncorrectDataFormat & e )
1314  catch ( IncorrectTagValue & e )
1316  catch ( RepeatedTag & e )
1318  catch ( RepeatingGroupCountMismatch & e )
1320  catch ( InvalidMessage& e )
1321  { m_state.onEvent( e.what() ); }
1322  catch ( RejectLogon& e )
1323  {
1324  m_state.onEvent( e.what() );
1325  generateLogout( e.what() );
1326  disconnect();
1327  }
1328  catch ( UnsupportedVersion& )
1329  {
1330  if ( header.getField(FIELD::MsgType) == MsgType_Logout )
1331  nextLogout( message, timeStamp );
1332  else
1333  {
1334  generateLogout( "Incorrect BeginString" );
1336  }
1337  }
1338  catch ( IOException& e )
1339  {
1340  m_state.onEvent( e.what() );
1341  disconnect();
1342  }
1343 
1344  if( !queued )
1345  nextQueued( timeStamp );
1346 
1347  if( isLoggedOn() )
1348  next();
1349 }
1350 
1351 bool Session::sendToTarget( Message& message, const std::string& qualifier )
1352 throw( SessionNotFound )
1353 {
1354  try
1355  {
1356  SessionID sessionID = message.getSessionID( qualifier );
1357  return sendToTarget( message, sessionID );
1358  }
1359  catch ( FieldNotFound& ) { throw SessionNotFound(); }
1360 }
1361 
1362 bool Session::sendToTarget( Message& message, const SessionID& sessionID )
1363 throw( SessionNotFound )
1364 {
1365  message.setSessionID( sessionID );
1366  Session* pSession = lookupSession( sessionID );
1367  if ( !pSession ) throw SessionNotFound();
1368  return pSession->send( message );
1369 }
1370 
1372 ( Message& message,
1373  const SenderCompID& senderCompID,
1374  const TargetCompID& targetCompID,
1375  const std::string& qualifier )
1376 throw( SessionNotFound )
1377 {
1378  message.getHeader().setField( senderCompID );
1379  message.getHeader().setField( targetCompID );
1380  return sendToTarget( message, qualifier );
1381 }
1382 
1384 ( Message& message, const std::string& sender, const std::string& target,
1385  const std::string& qualifier )
1386 throw( SessionNotFound )
1387 {
1388  return sendToTarget( message, SenderCompID( sender ),
1389  TargetCompID( target ), qualifier );
1390 }
1391 
1392 std::set<SessionID> Session::getSessions()
1393 {
1394  return s_sessionIDs;
1395 }
1396 
1397 bool Session::doesSessionExist( const SessionID& sessionID )
1398 {
1399  Locker locker( s_mutex );
1400  return s_sessions.end() != s_sessions.find( sessionID );
1401 }
1402 
1404 {
1405  Locker locker( s_mutex );
1406  Sessions::iterator find = s_sessions.find( sessionID );
1407  if ( find != s_sessions.end() )
1408  return find->second;
1409  else
1410  return 0;
1411 }
1412 
1413 Session* Session::lookupSession( const std::string& string, bool reverse )
1414 {
1415  Message message;
1416  if ( !message.setStringHeader( string ) )
1417  return 0;
1418 
1419  try
1420  {
1421  const Header& header = message.getHeader();
1422  const BeginString& beginString = FIELD_GET_REF( header, BeginString );
1423  const SenderCompID& senderCompID = FIELD_GET_REF( header, SenderCompID );
1424  const TargetCompID& targetCompID = FIELD_GET_REF( header, TargetCompID );
1425 
1426  if ( reverse )
1427  {
1428  return lookupSession( SessionID( beginString, SenderCompID( targetCompID ),
1429  TargetCompID( senderCompID ) ) );
1430  }
1431 
1432  return lookupSession( SessionID( beginString, senderCompID,
1433  targetCompID ) );
1434  }
1435  catch ( FieldNotFound& ) { return 0; }
1436 }
1437 
1438 bool Session::isSessionRegistered( const SessionID& sessionID )
1439 {
1440  Locker locker( s_mutex );
1441  return s_registered.end() != s_registered.find( sessionID );
1442 }
1443 
1445 {
1446  Locker locker( s_mutex );
1447  Session* pSession = lookupSession( sessionID );
1448  if ( pSession == 0 ) return 0;
1449  if ( isSessionRegistered( sessionID ) ) return 0;
1450  s_registered[ sessionID ] = pSession;
1451  return pSession;
1452 }
1453 
1454 void Session::unregisterSession( const SessionID& sessionID )
1455 {
1456  Locker locker( s_mutex );
1457  s_registered.erase( sessionID );
1458 }
1459 
1461 {
1462  Locker locker( s_mutex );
1463  return s_sessions.size();
1464 }
1465 
1467 {
1468  Locker locker( s_mutex );
1469  Sessions::iterator it = s_sessions.find( s.m_sessionID );
1470  if ( it == s_sessions.end() )
1471  {
1472  s_sessions[ s.m_sessionID ] = &s;
1473  s_sessionIDs.insert( s.m_sessionID );
1474  return true;
1475  }
1476  else
1477  return false;
1478 }
1479 
1481 {
1482  Locker locker( s_mutex );
1483  s_sessions.erase( s.m_sessionID );
1484  s_sessionIDs.erase( s.m_sessionID );
1485  s_registered.erase( s.m_sessionID );
1486 }
1487 }
const int ApplVerID
int getExpectedTargetNum()
Definition: Session.h:212
bool isEnabled()
Definition: Session.h:59
const char SessionRejectReason_COMPID_PROBLEM_TEXT[]
Definition: Values.h:47
const int OrigSendingTime
const int BusinessRejectReason_UNKNOWN_ID
Definition: FixValues.h:3271
const int BeginSeqNo
void lastReceivedTime(const UtcTimeStamp &value)
Definition: SessionState.h:108
Field has a badly formatted value.
Definition: Exceptions.h:146
static Session * lookupSession(const SessionID &)
Definition: Session.cpp:1403
virtual MessageStore * create(const SessionID &)=0
virtual ~Session()
Definition: Session.cpp:83
void populateRejectReason(Message &, int field, const std::string &)
Definition: Session.cpp:916
void onOutgoing(const std::string &string)
Definition: SessionState.h:202
bool isGoodTime(const SendingTime &sendingTime)
Definition: Session.h:236
bool send(Message &)
Definition: Session.cpp:452
const int RefMsgType
Message type not supported by application.
Definition: Exceptions.h:176
static bool isAdminMsgType(const MsgType &msgType)
Definition: Message.h:250
bool getFieldIfSet(FieldBase &field) const
Get a field if set.
Definition: FieldMap.h:102
bool verify(const Message &msg, bool checkTooHigh=true, bool checkTooLow=true)
Definition: Session.cpp:941
const int BusinessRejectReason_OTHER
Definition: FixValues.h:3272
Keeps track of when session is active.
Definition: TimeRange.h:34
const char BusinessRejectReason_NOT_AUTHORIZED_TEXT[]
Definition: Values.h:59
const int BusinessRejectReason_APPLICATION_NOT_AVAILABLE
Definition: FixValues.h:3267
virtual void onCreate(const SessionID &)=0
Notification of a session begin created.
const int HeartBtInt
#define FIELD_THROW_IF_NOT_FOUND(MAP, FLD)
Definition: FieldMap.h:240
int getExpectedSenderNum()
Definition: Session.h:211
Repeated group count not equal to actual count.
Definition: Exceptions.h:208
DataDictionaryProvider m_dataDictionaryProvider
Definition: Session.h:323
std::pair< int, int > ResendRange
Definition: SessionState.h:83
virtual Log * create()=0
virtual void onLogout(const SessionID &)=0
Notification of a session logging off or disconnecting.
void generateHeartbeat()
Definition: Session.cpp:685
Represents a data dictionary for a version of FIX.
static void unregisterSession(const SessionID &)
Definition: Session.cpp:1454
bool needHeartbeat() const
Definition: SessionState.h:138
int testRequest() const
Definition: SessionState.h:77
const char BeginString_FIX42[]
Definition: Values.h:34
Maintains the state and implements the logic of a FIX session.
Definition: Session.h:45
void doBadTime(const Message &msg)
Definition: Session.cpp:1053
void nextReject(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:312
MessageStoreFactory & m_messageStoreFactory
Definition: Session.h:324
void incrNextTargetMsgSeqNum()
Definition: SessionState.h:187
Unable to parse message.
Definition: Exceptions.h:73
static bool addSession(Session &)
Definition: Session.cpp:1466
const char BeginString_FIXT11[]
Definition: Values.h:30
bool isApp() const
Definition: Message.h:229
void reverseRoute(const Header &)
Add header informations depending on a source message.
Definition: Message.cpp:81
const char SessionRejectReason_INCORRECT_DATA_FORMAT_FOR_VALUE_TEXT[]
Definition: Values.h:44
const char SessionRejectReason_TAG_APPEARS_MORE_THAN_ONCE_TEXT[]
Definition: Values.h:50
const int BusinessRejectReason_NOT_AUTHORIZED
Definition: FixValues.h:3275
Repeated tag not part of repeating group.
Definition: Exceptions.h:199
Session cannot be found for specified action.
Definition: Exceptions.h:231
const char SessionRejectReason_INVALID_TAG_NUMBER_TEXT[]
Definition: Values.h:38
const int EndSeqNo
void next()
Definition: Session.cpp:125
bool set(int s, const std::string &m)
Definition: SessionState.h:172
static size_t numSessions()
Definition: Session.cpp:1460
void setNextTargetMsgSeqNum(int n)
Definition: SessionState.h:183
virtual bool send(const std::string &)=0
Queries for DataDictionary based on appropriate version of FIX.
static ApplVerID toApplVerID(const BeginString &value)
Definition: Message.h:257
bool retrieve(int msgSeqNum, Message &message)
Definition: SessionState.h:157
void reverse(I begin, I end)
Definition: pugixml.cpp:6009
bool setStringHeader(const std::string &string)
Set a messages header from a string This is an optimization that can be used to get useful informatio...
Definition: Message.cpp:380
virtual void onLogon(const SessionID &)=0
Notification of a session successfully logging on.
bool sendRaw(Message &, int msgSeqNum=0)
Definition: Session.cpp:459
const char MsgType_ResendRequest[]
Definition: FixValues.h:666
bool needTestRequest() const
Definition: SessionState.h:143
SessionID m_sessionID
Definition: Session.h:304
const int SessionRejectReason_TAG_APPEARS_MORE_THAN_ONCE
Definition: FixValues.h:1874
void nextTestRequest(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:287
void reset()
Definition: Session.h:66
const int SessionRejectReason_TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER
Definition: FixValues.h:1875
const char BusinessRejectReason_CONDITIONALLY_REQUIRED_FIELD_MISSING_TEXT[]
Definition: Values.h:58
bool shouldSendLogon() const
Definition: SessionState.h:115
bool validLogonState(const MsgType &msgType)
Definition: Session.cpp:1024
virtual void fromApp(const Message &, const SessionID &)=0
Notification of app message being received from target.
void nextResendRequest(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:344
void generateResendRequest(const BeginString &, const MsgSeqNum &)
Definition: Session.cpp:643
const char SessionRejectReason_VALUE_IS_INCORRECT_TEXT[]
Definition: Values.h:43
void queue(int msgSeqNum, const Message &message)
Definition: SessionState.h:155
virtual void destroy(Log *)=0
const TargetCompID & getTargetCompID() const
Definition: SessionID.h:57
void refresh()
Definition: Session.h:68
bool initiate() const
Definition: SessionState.h:68
bool timedOut() const
Definition: SessionState.h:133
static bool isSessionRegistered(const SessionID &)
Definition: Session.cpp:1438
const char MsgType_SequenceReset[]
Definition: FixValues.h:646
void lastSentTime(const UtcTimeStamp &value)
Definition: SessionState.h:101
Tag number does not exist in specification.
Definition: Exceptions.h:101
const int NewSeqNo
static std::string convert(signed_int value)
bool resendRequested() const
Definition: SessionState.h:80
bool isLogonTime(const UtcTimeStamp &time)
Definition: Session.h:110
bool isTargetTooLow(const MsgSeqNum &msgSeqNum)
Definition: Session.h:249
const int SendingTime
bool receivedReset() const
Definition: SessionState.h:62
static Sessions s_sessions
Definition: Session.h:329
const int SessionRejectReason_INVALID_MSGTYPE
Definition: FixValues.h:1880
Definition: Acceptor.cpp:34
const Header & getHeader() const
Getter for the message header.
Definition: Message.h:192
static Session * registerSession(const SessionID &)
Definition: Session.cpp:1444
const char SessionRejectReason_SENDINGTIME_ACCURACY_PROBLEM_TEXT[]
Definition: Values.h:48
const int SessionRejectReason
void doTargetTooHigh(const Message &msg)
Definition: Session.cpp:1113
void generateLogon()
Definition: Session.cpp:602
const char SessionRejectReason_INVALID_MSGTYPE_TEXT[]
Definition: Values.h:49
static void validate(const Message &message, const DataDictionary *const pSessionDD, const DataDictionary *const pAppID)
Validate a message.
Session(Application &, MessageStoreFactory &, const SessionID &, const DataDictionaryProvider &, const TimeRange &, int heartBtInt, LogFactory *pLogFactory)
Definition: Session.cpp:41
void generateSequenceReset(int, int)
Definition: Session.cpp:666
const char SessionRejectReason_REQUIRED_TAG_MISSING_TEXT[]
Definition: Values.h:39
virtual void fromAdmin(const Message &, const SessionID &)=0
Notification of admin message being received from target.
This interface must be implemented to define what your FIX application does.
Definition: Application.h:43
FieldBase & getField(FieldBase &field) const
Get a field without type checking.
Definition: FieldMap.h:112
virtual void toApp(Message &, const SessionID &)=0
Notification of app message being sent to target.
static std::set< SessionID > getSessions()
Definition: Session.cpp:1392
const int GapFillFlag
static bool sendToTarget(Message &message, const std::string &qualifier="")
Definition: Session.cpp:1351
bool sentReset() const
Definition: SessionState.h:65
const int BusinessRejectReason_UNKNOWN_MESSAGE_TYPE
Definition: FixValues.h:3274
Application & m_application
Definition: Session.h:303
const char BusinessRejectReason_UNKNOWN_ID_TEXT[]
Definition: Values.h:54
Not a known message type.
Definition: Exceptions.h:169
const int SessionRejectReason_SENDINGTIME_ACCURACY_PROBLEM
Definition: FixValues.h:1881
bool m_resetOnLogon
Definition: Session.h:314
const int BusinessRejectReason_CONDITIONALLY_REQUIRED_FIELD_MISSING
Definition: FixValues.h:3270
std::string m_senderDefaultApplVerID
Definition: Session.h:308
const char BusinessRejectReason_APPLICATION_NOT_AVAILABLE_TEXT[]
Definition: Values.h:57
Locks/Unlocks a mutex using RAII.
Definition: Mutex.h:95
const char BusinessRejectReason_UNSUPPORTED_MESSAGE_TYPE_TEXT[]
Definition: Values.h:56
const int BusinessRejectReason_UNKNOWN_SECURITY
Definition: FixValues.h:3266
Version of FIX is not supported.
Definition: Exceptions.h:183
const int EncryptMethod
LogFactory * m_pLogFactory
Definition: Session.h:325
void disconnect()
Definition: Session.cpp:542
void persist(const Message &, const std::string &)
Definition: Session.cpp:592
static SessionIDs s_sessionIDs
Definition: Session.h:330
std::string toString(int beginStringField=FIELD::BeginString, int bodyLengthField=FIELD::BodyLength, int checkSumField=FIELD::CheckSum) const
Get a string representation of the message.
Definition: Message.cpp:167
bool isTargetTooHigh(const MsgSeqNum &msgSeqNum)
Definition: Session.h:247
const char SessionRejectReason_TAG_SPECIFIED_WITHOUT_A_VALUE_TEXT[]
Definition: Values.h:42
const DataDictionary & getSessionDataDictionary(const BeginString &beginString) const
const int TargetCompID
bool withinHeartBeat() const
Definition: SessionState.h:127
bool m_millisecondsInTimeStamp
Definition: Session.h:318
static Mutex s_mutex
Definition: Session.h:332
const int SessionRejectReason_INCORRECT_NUMINGROUP_COUNT_FOR_REPEATING_GROUP
Definition: FixValues.h:1873
const char SessionRejectReason_INCORRECT_NUMINGROUP_COUNT_FOR_REPEATING_GROUP_TEXT[]
Definition: Values.h:52
const int BusinessRejectReason_DELIVERTO_FIRM_NOT_AVAILABLE_AT_THIS_TIME
Definition: FixValues.h:3269
void generateReject(const Message &, int err, int field=0)
Definition: Session.cpp:720
void get(int b, int e, std::vector< std::string > &m) const
Definition: SessionState.h:174
SessionState m_state
Definition: Session.h:322
const DataDictionary & getApplicationDataDictionary(const ApplVerID &applVerID) const
Tag is not in the correct order.
Definition: Exceptions.h:190
std::string m_targetDefaultApplVerID
Definition: Session.h:309
This interface must be implemented to create a Log.
Definition: Log.h:42
bool receivedLogon() const
Definition: SessionState.h:53
Base class for all FIX messages.
Definition: Message.h:67
Field not found inside a message.
Definition: Exceptions.h:57
ResendRange resendRange() const
Definition: SessionState.h:85
virtual void toAdmin(Message &, const SessionID &)=0
Notification of admin message being sent to target.
virtual void destroy(MessageStore *)=0
bool m_validateLengthAndChecksum
Definition: Session.h:320
#define LOGEX(method)
Definition: Session.cpp:38
const int SessionRejectReason_INCORRECT_DATA_FORMAT_FOR_VALUE
Definition: FixValues.h:1869
bool checkSessionTime(const UtcTimeStamp &timeStamp)
Definition: Session.h:242
void setField(const FieldBase &field, bool overwrite=true)
Set a field without type checking.
Definition: FieldMap.h:79
const char BusinessRejectReason_OTHER_TEXT[]
Definition: Values.h:53
void incrNextSenderMsgSeqNum()
Definition: SessionState.h:185
void insertSendingTime(Header &)
Definition: Session.cpp:91
std::string logoutReason() const
Definition: SessionState.h:150
void fromCallback(const MsgType &msgType, const Message &msg, const SessionID &sessionID)
Definition: Session.cpp:1044
const bool isFIXT() const
Definition: SessionID.h:61
bool shouldSendReset()
Definition: Session.cpp:1013
const int SessionRejectReason_TAG_NOT_DEFINED_FOR_THIS_MESSAGE_TYPE
Definition: FixValues.h:1866
void nextHeartbeat(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:280
This interface must be implemented to create a MessageStore.
Definition: MessageStore.h:41
Indicates user does not want to send a message.
Definition: Exceptions.h:217
const BeginString & getBeginString() const
Definition: SessionID.h:53
const int Text
const char MsgType_TestRequest[]
Definition: FixValues.h:629
bool logonTimedOut() const
Definition: SessionState.h:117
void removeField(int field)
Remove a field. If field is not present, this is a no-op.
Definition: FieldMap.cpp:117
const char BeginString_FIX41[]
Definition: Values.h:35
bool sentLogon() const
Definition: SessionState.h:59
bool isCorrectCompID(const SenderCompID &senderCompID, const TargetCompID &targetCompID)
Definition: Session.h:251
const int SenderCompID
void onIncoming(const std::string &string)
Definition: SessionState.h:200
void generateTestRequest(const std::string &)
Definition: Session.cpp:709
void onEvent(const std::string &string)
Definition: SessionState.h:204
void nextLogon(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:202
const char MsgType_Logon[]
Definition: FixValues.h:614
const char MsgType_BusinessMessageReject[]
Definition: FixValues.h:626
const int DefaultApplVerID
static void removeSession(Session &)
Definition: Session.cpp:1480
virtual void disconnect()=0
const char SessionRejectReason_TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER_TEXT[]
Definition: Values.h:51
void doBadCompID(const Message &msg)
Definition: Session.cpp:1059
void generateLogout(const std::string &text="")
Definition: Session.cpp:905
void generateBusinessReject(const Message &, int err, int field=0)
Definition: Session.cpp:842
void logout(const std::string &reason="")
Definition: Session.h:57
Mutex m_mutex
Definition: Session.h:327
void fill(Header &)
Definition: Session.cpp:114
Date and Time represented in UTC.
Definition: FieldTypes.h:399
const int SessionRejectReason_COMPID_PROBLEM
Definition: FixValues.h:1864
bool m_resetOnDisconnect
Definition: Session.h:316
const int PossDupFlag
const int ResetSeqNumFlag
bool doTargetTooLow(const Message &msg)
Definition: Session.cpp:1093
const int BeginString
bool m_persistMessages
Definition: Session.h:319
std::set< SessionID > SessionIDs
Definition: Session.h:221
const int MsgSeqNum
#define FIELD_GET_PTR(MAP, FLD)
Definition: FieldMap.h:236
const int RefTagID
const char SessionRejectReason_TAG_NOT_DEFINED_FOR_THIS_MESSAGE_TYPE_TEXT[]
Definition: Values.h:40
Unique session id consists of BeginString, SenderCompID and TargetCompID.
Definition: SessionID.h:30
bool m_sendRedundantResendRequests
Definition: Session.h:310
const int SessionRejectReason_INVALID_TAG_NUMBER
Definition: FixValues.h:1877
Responder * m_pResponder
Definition: Session.h:326
bool logoutTimedOut() const
Definition: SessionState.h:122
const int TestReqID
Required field is not in message.
Definition: Exceptions.h:110
const int RefSeqNum
Field exists in message without a value.
Definition: Exceptions.h:128
Field has a value that is out of range.
Definition: Exceptions.h:137
MsgType identifyType(const std::string &message)
Parse the type of a message from a string.
Definition: Message.h:355
void insertOrigSendingTime(Header &, const UtcTimeStamp &when=UtcTimeStamp())
Definition: Session.cpp:103
const char MsgType_Logout[]
Definition: FixValues.h:622
bool m_resetOnLogout
Definition: Session.h:315
bool resend(Message &message)
Definition: Session.cpp:572
void nextQueued(const UtcTimeStamp &timeStamp)
Definition: Session.cpp:1145
int getNextSenderMsgSeqNum() const
Definition: SessionState.h:177
const char MsgType_Heartbeat[]
Definition: FixValues.h:634
const int SessionRejectReason_REQUIRED_TAG_MISSING
Definition: FixValues.h:1871
Not a recognizable message.
Definition: Exceptions.h:80
const char BusinessRejectReason_UNKNOWN_SECURITY_TEXT[]
Definition: Values.h:55
const SenderCompID & getSenderCompID() const
Definition: SessionID.h:55
MessageStore * store()
Definition: SessionState.h:89
bool m_refreshOnLogon
Definition: Session.h:317
static Sessions s_registered
Definition: Session.h:331
User wants to reject permission to logon.
Definition: Exceptions.h:224
const char BusinessRejectReason_DELIVERTO_FIRM_NOT_AVAILABLE_AT_THIS_TIME_TEXT[]
Definition: Values.h:60
void nextLogout(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:295
bool sentLogout() const
Definition: SessionState.h:56
#define FIELD_GET_REF(MAP, FLD)
Definition: FieldMap.h:238
Field does not belong to message.
Definition: Exceptions.h:119
void setTargetDefaultApplVerID(const std::string &targetDefaultApplVerID)
Definition: Session.h:129
IO Error.
Definition: Exceptions.h:238
const int BusinessRejectReason
const int MsgType
void heartBtInt(const HeartBtInt &value)
Definition: SessionState.h:94
const char ApplVerID_FIX50[]
Definition: FixValues.h:810
const int SessionRejectReason_TAG_SPECIFIED_WITHOUT_A_VALUE
Definition: FixValues.h:1879
void nextSequenceReset(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:319
void logon()
Definition: Session.h:55
bool alreadySentLogon() const
Definition: SessionState.h:116
bool doPossDup(const Message &msg)
Definition: Session.cpp:1065
const char MsgType_Reject[]
Definition: FixValues.h:682
const int SessionRejectReason_VALUE_IS_INCORRECT
Definition: FixValues.h:1878
static bool doesSessionExist(const SessionID &)
Definition: Session.cpp:1397
std::map< SessionID, Session *> Sessions
Definition: Session.h:220
bool isLoggedOn()
Definition: Session.h:65

Generated on Thu Sep 5 2019 11:07:58 for QuickFIX by doxygen 1.8.13 written by Dimitri van Heesch, © 1997-2001