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 
41 Session::Session( Application& application,
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_timestampPrecision( 3 ),
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 );
71  m_state.store( m_messageStoreFactory.create( m_sessionID ) );
72  if ( m_pLogFactory )
73  m_state.log( m_pLogFactory->create( m_sessionID ) );
74 
75  if( !checkSessionTime(UtcTimeStamp()) )
76  reset();
77 
78  addSession( *this );
79  m_application.onCreate( m_sessionID );
80  m_state.onEvent( "Created session" );
81 }
82 
84 {
85  removeSession( *this );
87  if ( m_pLogFactory && m_state.log() )
89 }
90 
91 void Session::insertSendingTime( Header& header )
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_timestampPrecision : 0) );
101 }
102 
103 void Session::insertOrigSendingTime( Header& header, const UtcTimeStamp& when )
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_timestampPrecision : 0) );
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 
125 void Session::next()
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  {
253  logon.getFieldIfSet(m_state.heartBtInt());
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  {
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() )
338  m_state.setNextTargetMsgSeqNum( MsgSeqNum( newSeqNo ) );
339  else if ( newSeqNo < getExpectedTargetNum() )
340  generateReject( sequenceReset, SessionRejectReason_VALUE_IS_INCORRECT );
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 
385  for ( i = messages.begin(); i != messages.end(); ++i )
386  {
387  SmartPtr<FIX::Message> pMsg;
388  std::string strMsgType;
389  const DataDictionary& sessionDD =
391  if (sessionDD.isMessageFieldsOrderPreserved())
392  {
393  std::string::size_type equalSign = (*i).find("\00135=");
394  equalSign += 4;
395  std::string::size_type soh = (*i).find_first_of('\001', equalSign);
396  strMsgType = (*i).substr(equalSign, soh - equalSign);
397 #ifdef HAVE_EMX
398  if (FIX::Message::isAdminMsgType(strMsgType) == false)
399  {
400  equalSign = (*i).find("\0019426=", soh);
401  if (equalSign == std::string::npos)
402  throw FIX::IOException("EMX message type (9426) not found");
403 
404  equalSign += 6;
405  soh = (*i).find_first_of('\001', equalSign);
406  if (soh == std::string::npos)
407  throw FIX::IOException("EMX message type (9426) soh char not found");
408  strMsgType.assign((*i).substr(equalSign, soh - equalSign));
409  }
410 #endif
411  }
412 
413  if( m_sessionID.isFIXT() )
414  {
415  Message msg;
416  msg.setStringHeader(*i);
417  ApplVerID applVerID;
418  if( !msg.getHeader().getFieldIfSet(applVerID) )
419  applVerID = m_senderDefaultApplVerID;
420 
421  const DataDictionary& applicationDD =
423  if (strMsgType.empty())
424  pMsg.reset( new Message( *i, sessionDD, applicationDD, m_validateLengthAndChecksum ));
425  else
426  {
427  const message_order & hdrOrder = sessionDD.getHeaderOrderedFields();
428  const message_order & trlOrder = sessionDD.getTrailerOrderedFields();
429  const message_order & msgOrder = applicationDD.getMessageOrderedFields(strMsgType);
430  pMsg.reset( new Message( hdrOrder, trlOrder, msgOrder, *i, sessionDD, applicationDD, m_validateLengthAndChecksum ));
431  }
432  }
433  else
434  {
435  if (strMsgType.empty())
436  pMsg.reset( new Message( *i, sessionDD, m_validateLengthAndChecksum ));
437  else
438  {
439  const message_order & hdrOrder = sessionDD.getHeaderOrderedFields();
440  const message_order & trlOrder = sessionDD.getTrailerOrderedFields();
441  const message_order & msgOrder = sessionDD.getMessageOrderedFields(strMsgType);
442  pMsg.reset(new Message(hdrOrder, trlOrder, msgOrder, *i, sessionDD, m_validateLengthAndChecksum ));
443  }
444  }
445 
446  Message & msg = *pMsg;
447 
448  msg.getHeader().getField( msgSeqNum );
449  msg.getHeader().getField( msgType );
450 
451  if( (current != msgSeqNum) && !begin )
452  begin = current;
453 
454  if ( Message::isAdminMsgType( msgType ) )
455  {
456  if ( !begin ) begin = msgSeqNum;
457  }
458  else
459  {
460  if ( resend( msg ) )
461  {
462  if ( begin ) generateSequenceReset( begin, msgSeqNum );
463  send( msg.toString(messageString) );
464  m_state.onEvent( "Resending Message: "
465  + IntConvertor::convert( msgSeqNum ) );
466  begin = 0;
467  }
468  else
469  { if ( !begin ) begin = msgSeqNum; }
470  }
471  current = msgSeqNum + 1;
472  }
473  if ( begin )
474  {
475  generateSequenceReset( begin, msgSeqNum + 1 );
476  }
477 
478  if ( endSeqNo > msgSeqNum )
479  {
480  endSeqNo = EndSeqNo(endSeqNo + 1);
482  if( endSeqNo > next )
483  endSeqNo = EndSeqNo(next);
484  generateSequenceReset( beginSeqNo, endSeqNo );
485  }
486 
487  resendRequest.getHeader().getField( msgSeqNum );
488  if( !isTargetTooHigh(msgSeqNum) && !isTargetTooLow(msgSeqNum) )
490 }
491 
492 Message * Session::newMessage(const std::string & msgType) const
493 {
494  Message * msg = 0;
495 
496  const DataDictionary& sessionDD =
498  if (!sessionDD.isMessageFieldsOrderPreserved())
499  {
500  msg = new Message();
501  }
502  else
503  {
504  const message_order & hdrOrder = sessionDD.getHeaderOrderedFields();
505  const message_order & trlOrder = sessionDD.getTrailerOrderedFields();
506  if (!m_sessionID.isFIXT() || Message::isAdminMsgType(msgType) )
507  {
508  const message_order & msgOrder = sessionDD.getMessageOrderedFields(msgType);
509  msg = new Message(hdrOrder, trlOrder, msgOrder);
510  }
511  else
512  {
513  const DataDictionary& applicationDD =
515  const message_order & msgOrder = applicationDD.getMessageOrderedFields(msgType);
516  msg = new Message(hdrOrder, trlOrder, msgOrder);
517  }
518  }
519 
520  return msg;
521 }
522 
523 bool Session::send( Message& message )
524 {
525  message.getHeader().removeField( FIELD::PossDupFlag );
526  message.getHeader().removeField( FIELD::OrigSendingTime );
527  return sendRaw( message );
528 }
529 
530 bool Session::sendRaw( Message& message, int num )
531 {
532  Locker l( m_mutex );
533 
534  try
535  {
536  Header& header = message.getHeader();
537 
538  MsgType msgType;
539  header.getFieldIfSet(msgType);
540 
541  fill( header );
542  std::string messageString;
543 
544  if ( num )
545  header.setField( MsgSeqNum( num ) );
546 
547  if ( Message::isAdminMsgType( msgType ) )
548  {
549  m_application.toAdmin( message, m_sessionID );
550 
551  if( msgType == "A" && !m_state.receivedReset() )
552  {
553  ResetSeqNumFlag resetSeqNumFlag( false );
554  message.getFieldIfSet(resetSeqNumFlag);
555 
556  if( resetSeqNumFlag )
557  {
558  m_state.reset();
559  message.getHeader().setField( MsgSeqNum(getExpectedSenderNum()) );
560  }
561  m_state.sentReset( resetSeqNumFlag );
562  }
563 
564  message.toString( messageString );
565 
566  if( !num )
567  persist( message, messageString );
568 
569  if (
570  msgType == "A" || msgType == "5"
571  || msgType == "2" || msgType == "4"
572  || isLoggedOn() )
573  {
574  send( messageString );
575  }
576  }
577  else
578  {
579  // do not send application messages if they will just be cleared
580  if( !isLoggedOn() && shouldSendReset() )
581  return false;
582 
583  try
584  {
585  m_application.toApp( message, m_sessionID );
586  message.toString( messageString );
587 
588  if( !num )
589  persist( message, messageString );
590 
591  if ( isLoggedOn() )
592  send( messageString );
593  }
594  catch ( DoNotSend& ) { return false; }
595  }
596 
597  return true;
598  }
599  catch ( IOException& e )
600  {
601  m_state.onEvent( e.what() );
602  return false;
603  }
604 }
605 
606 bool Session::send( const std::string& string )
607 {
608  if ( !m_pResponder ) return false;
609  m_state.onOutgoing( string );
610  return m_pResponder->send( string );
611 }
612 
613 void Session::disconnect()
614 {
615  Locker l(m_mutex);
616 
617  if ( m_pResponder )
618  {
619  m_state.onEvent( "Disconnecting" );
620 
622  m_pResponder = 0;
623  }
624 
625  if ( m_state.receivedLogon() || m_state.sentLogon() )
626  {
627  m_state.receivedLogon( false );
628  m_state.sentLogon( false );
630  }
631 
632  m_state.sentLogout( false );
633  m_state.receivedReset( false );
634  m_state.sentReset( false );
637  if ( m_resetOnDisconnect )
638  m_state.reset();
639 
640  m_state.resendRange( 0, 0 );
641 }
642 
643 bool Session::resend( Message& message )
644 {
645  SendingTime sendingTime;
646  MsgSeqNum msgSeqNum;
647  Header& header = message.getHeader();
648  header.getField( sendingTime );
649  header.getField( msgSeqNum );
650  insertOrigSendingTime( header, sendingTime );
651  header.setField( PossDupFlag( true ) );
652  insertSendingTime( header );
653 
654  try
655  {
656  m_application.toApp( message, m_sessionID );
657  return true;
658  }
659  catch ( DoNotSend& )
660  { return false; }
661 }
662 
663 void Session::persist( const Message& message, const std::string& messageString )
664 throw ( IOException )
665 {
666  MsgSeqNum msgSeqNum;
667  message.getHeader().getField( msgSeqNum );
668  if( m_persistMessages )
669  m_state.set( msgSeqNum, messageString );
670  m_state.incrNextSenderMsgSeqNum();
671 }
672 
674 {
675  SmartPtr<Message> pMsg(newMessage("A"));
676  Message & logon = *pMsg;
677 
678  logon.getHeader().setField( MsgType( "A" ) );
679  logon.setField( EncryptMethod( 0 ) );
680  logon.setField( m_state.heartBtInt() );
681  if( m_sessionID.isFIXT() )
682  logon.setField( DefaultApplVerID(m_senderDefaultApplVerID) );
683  if( m_refreshOnLogon )
684  refresh();
685  if( m_resetOnLogon )
686  m_state.reset();
687  if( shouldSendReset() )
688  logon.setField( ResetSeqNumFlag(true) );
689 
690  fill( logon.getHeader() );
691  UtcTimeStamp now;
692  m_state.lastReceivedTime( now );
693  m_state.testRequest( 0 );
694  m_state.sentLogon( true );
695  sendRaw( logon );
696 }
697 
698 void Session::generateLogon( const Message& aLogon )
699 {
700  SmartPtr<Message> pMsg(newMessage("A"));
701  Message & logon = *pMsg;
702 
703  EncryptMethod encryptMethod;
704  HeartBtInt heartBtInt;
705  logon.setField( EncryptMethod( 0 ) );
706  if( m_sessionID.isFIXT() )
707  logon.setField( DefaultApplVerID(m_senderDefaultApplVerID) );
708  if( m_state.receivedReset() )
709  logon.setField( ResetSeqNumFlag(true) );
710  aLogon.getField( heartBtInt );
711  logon.getHeader().setField( MsgType( "A" ) );
712  logon.setField( heartBtInt );
713  fill( logon.getHeader() );
714  sendRaw( logon );
716 }
717 
718 void Session::generateResendRequest( const BeginString& beginString, const MsgSeqNum& msgSeqNum )
719 {
720  SmartPtr<Message> pMsg(newMessage("2"));
721  Message & resendRequest = *pMsg;
722 
723  BeginSeqNo beginSeqNo( ( int ) getExpectedTargetNum() );
724  EndSeqNo endSeqNo( msgSeqNum - 1 );
725  if ( beginString >= FIX::BeginString_FIX42 )
726  endSeqNo = 0;
727  else if( beginString <= FIX::BeginString_FIX41 )
728  endSeqNo = 999999;
729  resendRequest.getHeader().setField( MsgType( "2" ) );
730  resendRequest.setField( beginSeqNo );
731  resendRequest.setField( endSeqNo );
732  fill( resendRequest.getHeader() );
733  sendRaw( resendRequest );
734 
735  m_state.onEvent( "Sent ResendRequest FROM: "
736  + IntConvertor::convert( beginSeqNo ) +
737  " TO: " + IntConvertor::convert( endSeqNo ) );
738 
739  m_state.resendRange( beginSeqNo, msgSeqNum - 1 );
740 }
741 
743 ( int beginSeqNo, int endSeqNo )
744 {
745  SmartPtr<Message> pMsg(newMessage("4"));
746  Message & sequenceReset = *pMsg;
747 
748  NewSeqNo newSeqNo( endSeqNo );
749  sequenceReset.getHeader().setField( MsgType( "4" ) );
750  sequenceReset.getHeader().setField( PossDupFlag( true ) );
751  sequenceReset.setField( newSeqNo );
752  fill( sequenceReset.getHeader() );
753 
754  SendingTime sendingTime;
755  sequenceReset.getHeader().getField( sendingTime );
756  insertOrigSendingTime( sequenceReset.getHeader(), sendingTime );
757  sequenceReset.getHeader().setField( MsgSeqNum( beginSeqNo ) );
758  sequenceReset.setField( GapFillFlag( true ) );
759  sendRaw( sequenceReset, beginSeqNo );
760  m_state.onEvent( "Sent SequenceReset TO: "
761  + IntConvertor::convert( newSeqNo ) );
762 }
763 
765 {
766  SmartPtr<Message> pMsg(newMessage("0"));
767  Message & heartbeat = *pMsg;
768 
769  heartbeat.getHeader().setField( MsgType( "0" ) );
770  fill( heartbeat.getHeader() );
771  sendRaw( heartbeat );
772 }
773 
774 void Session::generateHeartbeat( const Message& testRequest )
775 {
776  SmartPtr<Message> pMsg(newMessage("0"));
777  Message & heartbeat = *pMsg;
778 
779  heartbeat.getHeader().setField( MsgType( "0" ) );
780  fill( heartbeat.getHeader() );
781  try
782  {
783  TestReqID testReqID;
784  testRequest.getField( testReqID );
785  heartbeat.setField( testReqID );
786  }
787  catch ( FieldNotFound& ) {}
788 
789  sendRaw( heartbeat );
790 }
791 
792 void Session::generateTestRequest( const std::string& id )
793 {
794  SmartPtr<Message> pMsg(newMessage("1"));
795  Message & testRequest = *pMsg;
796 
797  testRequest.getHeader().setField( MsgType( "1" ) );
798  fill( testRequest.getHeader() );
799  TestReqID testReqID( id );
800  testRequest.setField( testReqID );
801 
802  sendRaw( testRequest );
803 }
804 
805 void Session::generateReject( const Message& message, int err, int field )
806 {
807  std::string beginString = m_sessionID.getBeginString();
808 
809  SmartPtr<Message> pMsg(newMessage("3"));
810  Message & reject = *pMsg;
811 
812  reject.getHeader().setField( MsgType( "3" ) );
813  reject.reverseRoute( message.getHeader() );
814  fill( reject.getHeader() );
815 
816  MsgSeqNum msgSeqNum;
817  MsgType msgType;
818 
819  message.getHeader().getField( msgType );
820  if( message.getHeader().getFieldIfSet( msgSeqNum ) )
821  {
822  if( msgSeqNum.getString() != "" )
823  reject.setField( RefSeqNum( msgSeqNum ) );
824  }
825 
826  if ( beginString >= FIX::BeginString_FIX42 )
827  {
828  if( msgType.getString() != "" )
829  reject.setField( RefMsgType( msgType ) );
830  if ( (beginString == FIX::BeginString_FIX42
831  && err <= SessionRejectReason_INVALID_MSGTYPE)
832  || beginString > FIX::BeginString_FIX42 )
833  {
834  reject.setField( SessionRejectReason( err ) );
835  }
836  }
837  if ( msgType != MsgType_Logon && msgType != MsgType_SequenceReset
838  && msgSeqNum == getExpectedTargetNum() )
840 
841  const char* reason = 0;
842  switch ( err )
843  {
844  case SessionRejectReason_INVALID_TAG_NUMBER:
846  break;
847  case SessionRejectReason_REQUIRED_TAG_MISSING:
849  break;
850  case SessionRejectReason_TAG_NOT_DEFINED_FOR_THIS_MESSAGE_TYPE:
852  break;
853  case SessionRejectReason_TAG_SPECIFIED_WITHOUT_A_VALUE:
855  break;
856  case SessionRejectReason_VALUE_IS_INCORRECT:
858  break;
859  case SessionRejectReason_INCORRECT_DATA_FORMAT_FOR_VALUE:
861  break;
862  case SessionRejectReason_COMPID_PROBLEM:
864  break;
865  case SessionRejectReason_SENDINGTIME_ACCURACY_PROBLEM:
867  break;
868  case SessionRejectReason_INVALID_MSGTYPE:
870  break;
871  case SessionRejectReason_TAG_APPEARS_MORE_THAN_ONCE:
873  break;
874  case SessionRejectReason_TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER:
876  break;
877  case SessionRejectReason_INCORRECT_NUMINGROUP_COUNT_FOR_REPEATING_GROUP:
879  };
880 
881  if ( reason && ( field || err == SessionRejectReason_INVALID_TAG_NUMBER ) )
882  {
883  populateRejectReason( reject, field, reason );
884  m_state.onEvent( "Message " + msgSeqNum.getString() + " Rejected: "
885  + reason + ":" + IntConvertor::convert( field ) );
886  }
887  else if ( reason )
888  {
889  populateRejectReason( reject, reason );
890  m_state.onEvent( "Message " + msgSeqNum.getString()
891  + " Rejected: " + reason );
892  }
893  else
894  m_state.onEvent( "Message " + msgSeqNum.getString() + " Rejected" );
895 
896  if ( !m_state.receivedLogon() )
897  throw std::runtime_error( "Tried to send a reject while not logged on" );
898 
899  sendRaw( reject );
900 }
901 
902 void Session::generateReject( const Message& message, const std::string& str )
903 {
904  std::string beginString = m_sessionID.getBeginString();
905 
906  SmartPtr<Message> pMsg(newMessage("3"));
907  Message & reject = *pMsg;
908 
909  reject.getHeader().setField( MsgType( "3" ) );
910  reject.reverseRoute( message.getHeader() );
911  fill( reject.getHeader() );
912 
913  MsgType msgType;
914  MsgSeqNum msgSeqNum;
915 
916  message.getHeader().getField( msgType );
917  message.getHeader().getField( msgSeqNum );
918  if ( beginString >= FIX::BeginString_FIX42 )
919  reject.setField( RefMsgType( msgType ) );
920  reject.setField( RefSeqNum( msgSeqNum ) );
921 
922  if ( msgType != MsgType_Logon && msgType != MsgType_SequenceReset )
924 
925  reject.setField( Text( str ) );
926  sendRaw( reject );
927  m_state.onEvent( "Message " + msgSeqNum.getString()
928  + " Rejected: " + str );
929 }
930 
931 void Session::generateBusinessReject( const Message& message, int err, int field )
932 {
933  SmartPtr<Message> pMsg(newMessage("j"));
934  Message & reject = *pMsg;
935 
936  reject.getHeader().setField( MsgType( MsgType_BusinessMessageReject ) );
937  if( m_sessionID.isFIXT() )
938  reject.setField( DefaultApplVerID(m_senderDefaultApplVerID) );
939  fill( reject.getHeader() );
940  MsgType msgType;
941  MsgSeqNum msgSeqNum;
942  message.getHeader().getField( msgType );
943  message.getHeader().getField( msgSeqNum );
944  reject.setField( RefMsgType( msgType ) );
945  reject.setField( RefSeqNum( msgSeqNum ) );
946  reject.setField( BusinessRejectReason( err ) );
948 
949  const char* reason = 0;
950  switch ( err )
951  {
952  case BusinessRejectReason_OTHER:
954  break;
955  case BusinessRejectReason_UNKNOWN_ID:
957  break;
958  case BusinessRejectReason_UNKNOWN_SECURITY:
960  break;
961  case BusinessRejectReason_UNKNOWN_MESSAGE_TYPE:
963  break;
964  case BusinessRejectReason_APPLICATION_NOT_AVAILABLE:
966  break;
967  case BusinessRejectReason_CONDITIONALLY_REQUIRED_FIELD_MISSING:
969  break;
970  case BusinessRejectReason_NOT_AUTHORIZED:
972  break;
973  case BusinessRejectReason_DELIVERTO_FIRM_NOT_AVAILABLE_AT_THIS_TIME:
975  break;
976  };
977 
978  if ( reason && field )
979  {
980  populateRejectReason( reject, field, reason );
981  m_state.onEvent( "Message " + msgSeqNum.getString() + " Rejected: "
982  + reason + ":" + IntConvertor::convert( field ) );
983  }
984  else if ( reason )
985  {
986  populateRejectReason( reject, reason );
987  m_state.onEvent( "Message " + msgSeqNum.getString()
988  + " Rejected: " + reason );
989  }
990  else
991  m_state.onEvent( "Message " + msgSeqNum.getString() + " Rejected" );
992 
993  sendRaw( reject );
994 }
995 
996 void Session::generateLogout( const std::string& text )
997 {
998  SmartPtr<Message> pMsg(newMessage("5"));
999  Message & logout = *pMsg;
1000 
1001  logout.getHeader().setField( MsgType( MsgType_Logout ) );
1002  fill( logout.getHeader() );
1003  if ( text.length() )
1004  logout.setField( Text( text ) );
1005  sendRaw( logout );
1006  m_state.sentLogout( true );
1007 }
1008 
1009 void Session::populateRejectReason( Message& reject, int field,
1010  const std::string& text )
1011 {
1012  MsgType msgType;
1013  reject.getHeader().getField( msgType );
1014 
1015  if ( msgType == MsgType_Reject
1017  {
1018  reject.setField( RefTagID( field ) );
1019  reject.setField( Text( text ) );
1020  }
1021  else
1022  {
1023  std::stringstream stream;
1024  stream << text << " (" << field << ")";
1025  reject.setField( Text( stream.str() ) );
1026  }
1027 }
1028 
1029 void Session::populateRejectReason( Message& reject, const std::string& text )
1030 {
1031  reject.setField( Text( text ) );
1032 }
1033 
1034 bool Session::verify( const Message& msg, bool checkTooHigh,
1035  bool checkTooLow )
1036 {
1037  const MsgType* pMsgType = 0;
1038  const MsgSeqNum* pMsgSeqNum = 0;
1039 
1040  try
1041  {
1042  const Header& header = msg.getHeader();
1043 
1044  pMsgType = FIELD_GET_PTR( header, MsgType );
1045  const SenderCompID& senderCompID = FIELD_GET_REF( header, SenderCompID );
1046  const TargetCompID& targetCompID = FIELD_GET_REF( header, TargetCompID );
1047  const SendingTime& sendingTime = FIELD_GET_REF( header, SendingTime );
1048 
1049  if( checkTooHigh || checkTooLow )
1050  pMsgSeqNum = FIELD_GET_PTR( header, MsgSeqNum );
1052  if ( !validLogonState( *pMsgType ) )
1053  throw std::logic_error( "Logon state is not valid for message" );
1054 
1055  if ( !isGoodTime( sendingTime ) )
1056  {
1057  doBadTime( msg );
1058  return false;
1059  }
1060  if ( !isCorrectCompID( senderCompID, targetCompID ) )
1061  {
1062  doBadCompID( msg );
1063  return false;
1064  }
1065 
1066  if ( checkTooHigh && isTargetTooHigh( *pMsgSeqNum ) )
1067  {
1068  doTargetTooHigh( msg );
1069  return false;
1070  }
1071  else if ( checkTooLow && isTargetTooLow( *pMsgSeqNum ) )
1072  {
1073  doTargetTooLow( msg );
1074  return false;
1075  }
1076 
1077  if ( (checkTooHigh || checkTooLow) && m_state.resendRequested() )
1078  {
1080 
1081  if ( *pMsgSeqNum >= range.second )
1082  {
1083  m_state.onEvent ("ResendRequest for messages FROM: " +
1084  IntConvertor::convert (range.first) + " TO: " +
1085  IntConvertor::convert (range.second) +
1086  " has been satisfied.");
1087  m_state.resendRange (0, 0);
1088  }
1089  }
1090  }
1091  catch ( std::exception& e )
1092  {
1093  m_state.onEvent( e.what() );
1094  disconnect();
1095  return false;
1096  }
1097 
1098  UtcTimeStamp now;
1099  m_state.lastReceivedTime( now );
1100  m_state.testRequest( 0 );
1101 
1102  fromCallback( pMsgType ? *pMsgType : MsgType(), msg, m_sessionID );
1103  return true;
1104 }
1105 
1107 {
1108  std::string beginString = m_sessionID.getBeginString();
1109  return beginString >= FIX::BeginString_FIX41
1110  && ( m_resetOnLogon ||
1111  m_resetOnLogout ||
1113  && ( getExpectedSenderNum() == 1 )
1114  && ( getExpectedTargetNum() == 1 );
1115 }
1116 
1117 bool Session::validLogonState( const MsgType& msgType )
1118 {
1119  if ( (msgType == MsgType_Logon && m_state.sentReset())
1120  || (m_state.receivedReset()) )
1121  return true;
1122  if ( (msgType == MsgType_Logon && !m_state.receivedLogon())
1123  || (msgType != MsgType_Logon && m_state.receivedLogon()) )
1124  return true;
1125  if ( msgType == MsgType_Logout && m_state.sentLogon() )
1126  return true;
1127  if ( msgType != MsgType_Logout && m_state.sentLogout() )
1128  return true;
1129  if ( msgType == MsgType_SequenceReset )
1130  return true;
1131  if ( msgType == MsgType_Reject )
1132  return true;
1133 
1134  return false;
1135 }
1136 
1137 void Session::fromCallback( const MsgType& msgType, const Message& msg,
1138  const SessionID& sessionID )
1139 {
1140  if ( Message::isAdminMsgType( msgType ) )
1142  else
1144 }
1145 
1146 void Session::doBadTime( const Message& msg )
1147 {
1148  generateReject( msg, SessionRejectReason_SENDINGTIME_ACCURACY_PROBLEM );
1149  generateLogout();
1150 }
1151 
1152 void Session::doBadCompID( const Message& msg )
1153 {
1154  generateReject( msg, SessionRejectReason_COMPID_PROBLEM );
1155  generateLogout();
1156 }
1157 
1158 bool Session::doPossDup( const Message& msg )
1159 {
1160  const Header & header = msg.getHeader();
1161  OrigSendingTime origSendingTime;
1162  SendingTime sendingTime;
1163  MsgType msgType;
1164 
1165  header.getField( msgType );
1166  header.getField( sendingTime );
1167 
1168  if ( msgType != MsgType_SequenceReset )
1169  {
1170  if ( !header.getFieldIfSet( origSendingTime ) )
1171  {
1172  generateReject( msg, SessionRejectReason_REQUIRED_TAG_MISSING, origSendingTime.getTag() );
1173  return false;
1174  }
1176  if ( origSendingTime > sendingTime )
1177  {
1178  generateReject( msg, SessionRejectReason_SENDINGTIME_ACCURACY_PROBLEM );
1179  generateLogout();
1180  return false;
1181  }
1182  }
1183  return true;
1184 }
1185 
1186 bool Session::doTargetTooLow( const Message& msg )
1187 {
1188  const Header & header = msg.getHeader();
1189  PossDupFlag possDupFlag(false);
1190  MsgSeqNum msgSeqNum;
1191  header.getFieldIfSet(possDupFlag);
1192  header.getField( msgSeqNum );
1193 
1194  if ( !possDupFlag )
1195  {
1196  std::stringstream stream;
1197  stream << "MsgSeqNum too low, expecting " << getExpectedTargetNum()
1198  << " but received " << msgSeqNum;
1199  generateLogout( stream.str() );
1200  throw std::logic_error( stream.str() );
1201  }
1202 
1203  return doPossDup( msg );
1204 }
1205 
1206 void Session::doTargetTooHigh( const Message& msg )
1207 {
1208  const Header & header = msg.getHeader();
1209  BeginString beginString;
1210  MsgSeqNum msgSeqNum;
1211  header.getField( beginString );
1212  header.getField( msgSeqNum );
1213 
1214  m_state.onEvent( "MsgSeqNum too high, expecting "
1216  + " but received "
1217  + IntConvertor::convert( msgSeqNum ) );
1218 
1219  m_state.queue( msgSeqNum, msg );
1220 
1221  if( m_state.resendRequested() )
1222  {
1224 
1225  if( !m_sendRedundantResendRequests && msgSeqNum >= range.first )
1226  {
1227  m_state.onEvent ("Already sent ResendRequest FROM: " +
1228  IntConvertor::convert (range.first) + " TO: " +
1229  IntConvertor::convert (range.second) +
1230  ". Not sending another.");
1231  return;
1232  }
1233  }
1234 
1235  generateResendRequest( beginString, msgSeqNum );
1236 }
1237 
1238 void Session::nextQueued( const UtcTimeStamp& timeStamp )
1239 {
1240  while ( nextQueued( getExpectedTargetNum(), timeStamp ) ) {}
1241 }
1242 
1243 bool Session::nextQueued( int num, const UtcTimeStamp& timeStamp )
1244 {
1245  Message msg;
1246  MsgType msgType;
1247 
1248  if( m_state.retrieve( num, msg ) )
1249  {
1250  m_state.onEvent( "Processing QUEUED message: "
1251  + IntConvertor::convert( num ) );
1252  msg.getHeader().getField( msgType );
1253  if( msgType == MsgType_Logon
1254  || msgType == MsgType_ResendRequest )
1255  {
1257  }
1258  else
1259  {
1260  next( msg, timeStamp, true );
1261  }
1262  return true;
1263  }
1264  return false;
1265 }
1266 
1267 void Session::next( const std::string& msg, const UtcTimeStamp& timeStamp, bool queued )
1268 {
1269  try
1270  {
1271  m_state.onIncoming( msg );
1272  const DataDictionary& sessionDD =
1274  if( m_sessionID.isFIXT() )
1275  {
1276  const DataDictionary& applicationDD =
1278  next( Message( msg, sessionDD, applicationDD, m_validateLengthAndChecksum ), timeStamp, queued );
1279  }
1280  else
1281  {
1282  next( Message( msg, sessionDD, m_validateLengthAndChecksum ), timeStamp, queued );
1283  }
1284  }
1285  catch( InvalidMessage& e )
1286  {
1287  m_state.onEvent( e.what() );
1288 
1289  try
1290  {
1291  if( identifyType(msg) == MsgType_Logon )
1292  {
1293  m_state.onEvent( "Logon message is not valid" );
1294  disconnect();
1295  }
1296  } catch( MessageParseError& ) {}
1297  throw e;
1298  }
1299 }
1300 
1301 void Session::next( const Message& message, const UtcTimeStamp& timeStamp, bool queued )
1302 {
1303  const Header& header = message.getHeader();
1304 
1305  try
1306  {
1307  if ( !checkSessionTime(timeStamp) )
1308  { reset(); return; }
1309 
1310  const MsgType& msgType = FIELD_GET_REF( header, MsgType );
1311  const BeginString& beginString = FIELD_GET_REF( header, BeginString );
1312  // make sure these fields are present
1313  FIELD_THROW_IF_NOT_FOUND( header, SenderCompID );
1314  FIELD_THROW_IF_NOT_FOUND( header, TargetCompID );
1315 
1316  if ( beginString != m_sessionID.getBeginString() )
1317  throw UnsupportedVersion();
1319  if( msgType == MsgType_Logon )
1320  {
1321  if( m_sessionID.isFIXT() )
1322  {
1323  const DefaultApplVerID& applVerID = FIELD_GET_REF( message, DefaultApplVerID );
1324  setTargetDefaultApplVerID(applVerID);
1325  }
1326  else
1327  {
1329  }
1330  }
1331 
1332  const DataDictionary& sessionDataDictionary =
1334 
1335  if( m_sessionID.isFIXT() && message.isApp() )
1336  {
1337  ApplVerID applVerID = m_targetDefaultApplVerID;
1338  header.getFieldIfSet(applVerID);
1339  const DataDictionary& applicationDataDictionary =
1341  DataDictionary::validate( message, &sessionDataDictionary, &applicationDataDictionary );
1342  }
1343  else
1344  {
1345  sessionDataDictionary.validate( message );
1346  }
1347 
1348  if ( msgType == MsgType_Logon )
1349  nextLogon( message, timeStamp );
1350  else if ( msgType == MsgType_Heartbeat )
1351  nextHeartbeat( message, timeStamp );
1352  else if ( msgType == MsgType_TestRequest )
1353  nextTestRequest( message, timeStamp );
1354  else if ( msgType == MsgType_SequenceReset )
1355  nextSequenceReset( message, timeStamp );
1356  else if ( msgType == MsgType_Logout )
1357  nextLogout( message, timeStamp );
1358  else if ( msgType == MsgType_ResendRequest )
1359  nextResendRequest( message,timeStamp );
1360  else if ( msgType == MsgType_Reject )
1361  nextReject( message, timeStamp );
1362  else
1363  {
1364  if ( !verify( message ) ) return ;
1366  }
1367  }
1368  catch ( MessageParseError& e )
1369  { m_state.onEvent( e.what() ); }
1370  catch ( RequiredTagMissing & e )
1371  { LOGEX( generateReject( message, SessionRejectReason_REQUIRED_TAG_MISSING, e.field ) ); }
1372  catch ( FieldNotFound & e )
1373  {
1374  if( header.getField(FIELD::BeginString) >= FIX::BeginString_FIX42 && message.isApp() )
1375  {
1376  LOGEX( generateBusinessReject( message, BusinessRejectReason_CONDITIONALLY_REQUIRED_FIELD_MISSING, e.field ) );
1377  }
1378  else
1379  {
1380  LOGEX( generateReject( message, SessionRejectReason_REQUIRED_TAG_MISSING, e.field ) );
1381  if ( header.getField(FIELD::MsgType) == MsgType_Logon )
1382  {
1383  m_state.onEvent( "Required field missing from logon" );
1384  disconnect();
1385  }
1386  }
1387  }
1388  catch ( InvalidTagNumber & e )
1389  { LOGEX( generateReject( message, SessionRejectReason_INVALID_TAG_NUMBER, e.field ) ); }
1390  catch ( NoTagValue & e )
1391  { LOGEX( generateReject( message, SessionRejectReason_TAG_SPECIFIED_WITHOUT_A_VALUE, e.field ) ); }
1392  catch ( TagNotDefinedForMessage & e )
1393  { LOGEX( generateReject( message, SessionRejectReason_TAG_NOT_DEFINED_FOR_THIS_MESSAGE_TYPE, e.field ) ); }
1394  catch ( InvalidMessageType& )
1395  { LOGEX( generateReject( message, SessionRejectReason_INVALID_MSGTYPE ) ); }
1396  catch ( UnsupportedMessageType& )
1397  {
1398  if ( header.getField(FIELD::BeginString) >= FIX::BeginString_FIX42 )
1399  { LOGEX( generateBusinessReject( message, BusinessRejectReason_UNKNOWN_MESSAGE_TYPE ) ); }
1400  else
1401  { LOGEX( generateReject( message, "Unsupported message type" ) ); }
1402  }
1403  catch ( TagOutOfOrder & e )
1404  { LOGEX( generateReject( message, SessionRejectReason_TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER, e.field ) ); }
1405  catch ( IncorrectDataFormat & e )
1406  { LOGEX( generateReject( message, SessionRejectReason_INCORRECT_DATA_FORMAT_FOR_VALUE, e.field ) ); }
1407  catch ( IncorrectTagValue & e )
1408  { LOGEX( generateReject( message, SessionRejectReason_VALUE_IS_INCORRECT, e.field ) ); }
1409  catch ( RepeatedTag & e )
1410  { LOGEX( generateReject( message, SessionRejectReason_TAG_APPEARS_MORE_THAN_ONCE, e.field ) ); }
1411  catch ( RepeatingGroupCountMismatch & e )
1412  { LOGEX( generateReject( message, SessionRejectReason_INCORRECT_NUMINGROUP_COUNT_FOR_REPEATING_GROUP, e.field ) ); }
1413  catch ( InvalidMessage& e )
1414  { m_state.onEvent( e.what() ); }
1415  catch ( RejectLogon& e )
1416  {
1417  m_state.onEvent( e.what() );
1418  generateLogout( e.what() );
1419  disconnect();
1420  }
1421  catch ( UnsupportedVersion& )
1422  {
1423  if ( header.getField(FIELD::MsgType) == MsgType_Logout )
1424  nextLogout( message, timeStamp );
1425  else
1426  {
1427  generateLogout( "Incorrect BeginString" );
1429  }
1430  }
1431  catch ( IOException& e )
1432  {
1433  m_state.onEvent( e.what() );
1434  disconnect();
1435  }
1436 
1437  if( !queued )
1438  nextQueued( timeStamp );
1439 
1440  if( isLoggedOn() )
1441  next();
1442 }
1443 
1444 bool Session::sendToTarget( Message& message, const std::string& qualifier )
1445 throw( SessionNotFound )
1446 {
1447  try
1448  {
1449  SessionID sessionID = message.getSessionID( qualifier );
1450  return sendToTarget( message, sessionID );
1451  }
1452  catch ( FieldNotFound& ) { throw SessionNotFound(); }
1453 }
1454 
1455 bool Session::sendToTarget( Message& message, const SessionID& sessionID )
1456 throw( SessionNotFound )
1457 {
1458  message.setSessionID( sessionID );
1459  Session* pSession = lookupSession( sessionID );
1460  if ( !pSession ) throw SessionNotFound();
1461  return pSession->send( message );
1462 }
1463 
1465 ( Message& message,
1466  const SenderCompID& senderCompID,
1467  const TargetCompID& targetCompID,
1468  const std::string& qualifier )
1469 throw( SessionNotFound )
1470 {
1471  message.getHeader().setField( senderCompID );
1472  message.getHeader().setField( targetCompID );
1473  return sendToTarget( message, qualifier );
1474 }
1475 
1477 ( Message& message, const std::string& sender, const std::string& target,
1478  const std::string& qualifier )
1479 throw( SessionNotFound )
1480 {
1481  return sendToTarget( message, SenderCompID( sender ),
1482  TargetCompID( target ), qualifier );
1483 }
1484 
1485 std::set<SessionID> Session::getSessions()
1486 {
1487  return s_sessionIDs;
1488 }
1489 
1490 bool Session::doesSessionExist( const SessionID& sessionID )
1491 {
1492  Locker locker( s_mutex );
1493  return s_sessions.end() != s_sessions.find( sessionID );
1495 
1496 Session* Session::lookupSession( const SessionID& sessionID )
1497 {
1498  Locker locker( s_mutex );
1499  Sessions::iterator find = s_sessions.find( sessionID );
1500  if ( find != s_sessions.end() )
1501  return find->second;
1502  else
1503  return 0;
1504 }
1505 
1506 Session* Session::lookupSession( const std::string& string, bool reverse )
1508  Message message;
1509  if ( !message.setStringHeader( string ) )
1510  return 0;
1511 
1512  try
1513  {
1514  const Header& header = message.getHeader();
1515  const BeginString& beginString = FIELD_GET_REF( header, BeginString );
1516  const SenderCompID& senderCompID = FIELD_GET_REF( header, SenderCompID );
1517  const TargetCompID& targetCompID = FIELD_GET_REF( header, TargetCompID );
1518 
1519  if ( reverse )
1520  {
1521  return lookupSession( SessionID( beginString, SenderCompID( targetCompID ),
1522  TargetCompID( senderCompID ) ) );
1523  }
1524 
1525  return lookupSession( SessionID( beginString, senderCompID,
1526  targetCompID ) );
1527  }
1528  catch ( FieldNotFound& ) { return 0; }
1529 }
1530 
1531 bool Session::isSessionRegistered( const SessionID& sessionID )
1532 {
1533  Locker locker( s_mutex );
1534  return s_registered.end() != s_registered.find( sessionID );
1535 }
1536 
1537 Session* Session::registerSession( const SessionID& sessionID )
1538 {
1539  Locker locker( s_mutex );
1540  Session* pSession = lookupSession( sessionID );
1541  if ( pSession == 0 ) return 0;
1542  if ( isSessionRegistered( sessionID ) ) return 0;
1543  s_registered[ sessionID ] = pSession;
1544  return pSession;
1545 }
1546 
1547 void Session::unregisterSession( const SessionID& sessionID )
1549  Locker locker( s_mutex );
1550  s_registered.erase( sessionID );
1551 }
1552 
1553 size_t Session::numSessions()
1555  Locker locker( s_mutex );
1556  return s_sessions.size();
1557 }
1558 
1559 bool Session::addSession( Session& s )
1560 {
1561  Locker locker( s_mutex );
1562  Sessions::iterator it = s_sessions.find( s.m_sessionID );
1563  if ( it == s_sessions.end() )
1564  {
1565  s_sessions[ s.m_sessionID ] = &s;
1566  s_sessionIDs.insert( s.m_sessionID );
1567  return true;
1568  }
1569  else
1570  return false;
1571 }
1572 
1574 {
1575  Locker locker( s_mutex );
1577  s_sessionIDs.erase( s.m_sessionID );
1578  s_registered.erase( s.m_sessionID );
1579 }
1580 }
FIX::SessionState::reset
void reset()
Definition: SessionState.h:225
FIX::Session::checkSessionTime
bool checkSessionTime(const UtcTimeStamp &timeStamp)
Definition: Session.h:289
FIX::SessionRejectReason_VALUE_IS_INCORRECT_TEXT
const char SessionRejectReason_VALUE_IS_INCORRECT_TEXT[]
Definition: Values.h:60
FIX::Session::generateBusinessReject
void generateBusinessReject(const Message &, int err, int field=0)
Definition: Session.cpp:948
FIX::Session::m_targetDefaultApplVerID
std::string m_targetDefaultApplVerID
Definition: Session.h:358
FIX::Session::doTargetTooLow
bool doTargetTooLow(const Message &msg)
Definition: Session.cpp:1203
FIX::Session::m_resetOnLogout
bool m_resetOnLogout
Definition: Session.h:364
FIX::SessionState::alreadySentLogon
bool alreadySentLogon() const
Definition: SessionState.h:150
FIX::BeginString_FIX41
const char BeginString_FIX41[]
Definition: Values.h:52
FIX::Message::toApplVerID
static ApplVerID toApplVerID(const BeginString &value)
Definition: Message.h:324
FIX::Session::setTargetDefaultApplVerID
void setTargetDefaultApplVerID(const std::string &targetDefaultApplVerID)
Definition: Session.h:163
FIX::SessionState::setNextTargetMsgSeqNum
void setNextTargetMsgSeqNum(int n)
Definition: SessionState.h:217
FIX::SessionID::isFIXT
const bool isFIXT() const
Definition: SessionID.h:95
FIX::SessionRejectReason_COMPID_PROBLEM_TEXT
const char SessionRejectReason_COMPID_PROBLEM_TEXT[]
Definition: Values.h:64
FIX::Session::generateReject
void generateReject(const Message &, int err, int field=0)
Definition: Session.cpp:822
FIX::Session::nextReject
void nextReject(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:329
FIX::SessionState::withinHeartBeat
bool withinHeartBeat() const
Definition: SessionState.h:161
FIX::Application::toAdmin
virtual void toAdmin(Message &, const SessionID &)=0
Notification of admin message being sent to target.
FIX::Session::lookupSession
static Session * lookupSession(const SessionID &)
Definition: Session.cpp:1513
FIX::Session::nextLogon
void nextLogon(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:219
FIX::Session::unregisterSession
static void unregisterSession(const SessionID &)
Definition: Session.cpp:1564
FIX::Session::m_resetOnLogon
bool m_resetOnLogon
Definition: Session.h:363
FIX::SessionState::testRequest
int testRequest() const
Definition: SessionState.h:111
FIX::SessionState::timedOut
bool timedOut() const
Definition: SessionState.h:167
FIX::BeginString_FIX42
const char BeginString_FIX42[]
Definition: Values.h:51
FIX::Session::verify
bool verify(const Message &msg, bool checkTooHigh=true, bool checkTooLow=true)
Definition: Session.cpp:1051
FIX::SessionState::queue
void queue(int msgSeqNum, const Message &message)
Definition: SessionState.h:189
FIX::BusinessRejectReason_NOT_AUTHORIZED_TEXT
const char BusinessRejectReason_NOT_AUTHORIZED_TEXT[]
Definition: Values.h:76
FIX::UtcTimeStamp
Date and Time represented in UTC.
Definition: FieldTypes.h:599
FIX::BusinessRejectReason_UNKNOWN_ID_TEXT
const char BusinessRejectReason_UNKNOWN_ID_TEXT[]
Definition: Values.h:71
FIX::Session::getExpectedTargetNum
int getExpectedTargetNum()
Definition: Session.h:259
FIX::Session::Sessions
std::map< SessionID, Session * > Sessions
Definition: Session.h:267
FIX::Session::s_sessionIDs
static SessionIDs s_sessionIDs
Definition: Session.h:379
LOGEX
#define LOGEX(method)
Definition: Session.cpp:55
FIX::Session::isTargetTooLow
bool isTargetTooLow(const MsgSeqNum &msgSeqNum)
Definition: Session.h:296
FIX::DataDictionary::getMessageOrderedFields
message_order const & getMessageOrderedFields(const std::string &msgType) const
Definition: DataDictionary.cpp:498
FIX::Session::m_timestampPrecision
int m_timestampPrecision
Definition: Session.h:367
FIX::SessionState::needTestRequest
bool needTestRequest() const
Definition: SessionState.h:177
FIX::Session::reset
void reset()
Definition: Session.h:100
FIX::Session::refresh
void refresh()
Definition: Session.h:102
FIX::SessionState::receivedReset
bool receivedReset() const
Definition: SessionState.h:96
FIX::SessionState::getNextSenderMsgSeqNum
int getNextSenderMsgSeqNum() const
Definition: SessionState.h:211
FIX::Session::removeSession
static void removeSession(Session &)
Definition: Session.cpp:1590
FIX::SessionRejectReason_INCORRECT_NUMINGROUP_COUNT_FOR_REPEATING_GROUP_TEXT
const char SessionRejectReason_INCORRECT_NUMINGROUP_COUNT_FOR_REPEATING_GROUP_TEXT[]
Definition: Values.h:69
FIX::SessionRejectReason_REQUIRED_TAG_MISSING_TEXT
const char SessionRejectReason_REQUIRED_TAG_MISSING_TEXT[]
Definition: Values.h:56
FIELD_THROW_IF_NOT_FOUND
#define FIELD_THROW_IF_NOT_FOUND(MAP, FLD)
Definition: FieldMap.h:378
FIX::Session::getSessions
static std::set< SessionID > getSessions()
Definition: Session.cpp:1502
FIX::Session::m_persistMessages
bool m_persistMessages
Definition: Session.h:368
FIX::Session::doBadCompID
void doBadCompID(const Message &msg)
Definition: Session.cpp:1169
FIX::Session::s_sessions
static Sessions s_sessions
Definition: Session.h:378
FIX::Session::SessionIDs
std::set< SessionID > SessionIDs
Definition: Session.h:268
Values.h
FIX::Session::registerSession
static Session * registerSession(const SessionID &)
Definition: Session.cpp:1554
FIX::BusinessRejectReason_UNSUPPORTED_MESSAGE_TYPE_TEXT
const char BusinessRejectReason_UNSUPPORTED_MESSAGE_TYPE_TEXT[]
Definition: Values.h:73
FIX::SessionState::clearQueue
void clearQueue()
Definition: SessionState.h:203
FIX::SessionState::ResendRange
std::pair< int, int > ResendRange
Definition: SessionState.h:117
FIX::Session::m_sessionID
SessionID m_sessionID
Definition: Session.h:353
FIX::SessionState::onOutgoing
void onOutgoing(const std::string &string)
Definition: SessionState.h:236
FIX::MessageStoreFactory::destroy
virtual void destroy(MessageStore *)=0
FIX::Session::numSessions
static size_t numSessions()
Definition: Session.cpp:1570
FIX::SessionState::log
Log * log()
Definition: SessionState.h:125
FIX::Responder::send
virtual bool send(const std::string &)=0
FIX::BusinessRejectReason_CONDITIONALLY_REQUIRED_FIELD_MISSING_TEXT
const char BusinessRejectReason_CONDITIONALLY_REQUIRED_FIELD_MISSING_TEXT[]
Definition: Values.h:75
FIX::SessionState::sentLogout
bool sentLogout() const
Definition: SessionState.h:90
FIX::Session::doBadTime
void doBadTime(const Message &msg)
Definition: Session.cpp:1163
FIX::FieldMap::getFieldIfSet
bool getFieldIfSet(FieldBase &field) const
Get a field if set.
Definition: FieldMap.h:180
FIX::Session::m_sendRedundantResendRequests
bool m_sendRedundantResendRequests
Definition: Session.h:359
FIX::SessionID
Unique session id consists of BeginString, SenderCompID and TargetCompID.
Definition: SessionID.h:47
FIX::Session::generateSequenceReset
void generateSequenceReset(int, int)
Definition: Session.cpp:760
FIX::Session::generateResendRequest
void generateResendRequest(const BeginString &, const MsgSeqNum &)
Definition: Session.cpp:735
FIX::Session::next
void next()
Definition: Session.cpp:142
FIX::SessionState::retrieve
bool retrieve(int msgSeqNum, Message &message)
Definition: SessionState.h:191
FIX::IOException
IO Error.
Definition: Exceptions.h:255
FIX::Session::isGoodTime
bool isGoodTime(const SendingTime &sendingTime)
Definition: Session.h:283
FIX::Session::m_state
SessionState m_state
Definition: Session.h:371
FIX::Session::m_messageStoreFactory
MessageStoreFactory & m_messageStoreFactory
Definition: Session.h:373
FIX::Message::reverseRoute
void reverseRoute(const Header &)
Add header informations depending on a source message.
Definition: Message.cpp:167
FIX::SessionState::get
void get(int b, int e, std::vector< std::string > &m) const
Definition: SessionState.h:208
FIX::SessionID::getSenderCompID
const SenderCompID & getSenderCompID() const
Definition: SessionID.h:89
FIX::Session::m_senderDefaultApplVerID
std::string m_senderDefaultApplVerID
Definition: Session.h:357
FIX::TYPE::UtcTimeStamp
@ UtcTimeStamp
Definition: FieldTypes.h:940
FIX::SessionState::initiate
bool initiate() const
Definition: SessionState.h:102
FIX::Session::validLogonState
bool validLogonState(const MsgType &msgType)
Definition: Session.cpp:1134
FIX::DataDictionaryProvider::getSessionDataDictionary
const DataDictionary & getSessionDataDictionary(const BeginString &beginString) const
Definition: DataDictionaryProvider.cpp:55
FIX::BeginString_FIXT11
const char BeginString_FIXT11[]
Definition: Values.h:47
FIX::Session::s_registered
static Sessions s_registered
Definition: Session.h:380
FIX::IntConvertor::convert
static std::string convert(signed_int value)
Definition: FieldConvertors.h:170
FIX::Message::setStringHeader
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:492
FIX::DataDictionaryProvider::getApplicationDataDictionary
const DataDictionary & getApplicationDataDictionary(const ApplVerID &applVerID) const
Definition: DataDictionaryProvider.cpp:66
FIX::Session::isLogonTime
bool isLogonTime(const UtcTimeStamp &time)
Definition: Session.h:144
FIX::Session::doesSessionExist
static bool doesSessionExist(const SessionID &)
Definition: Session.cpp:1507
FIX::SessionRejectReason_TAG_NOT_DEFINED_FOR_THIS_MESSAGE_TYPE_TEXT
const char SessionRejectReason_TAG_NOT_DEFINED_FOR_THIS_MESSAGE_TYPE_TEXT[]
Definition: Values.h:57
FIX::DataDictionary::getHeaderOrderedFields
message_order const & getHeaderOrderedFields() const
Definition: DataDictionary.cpp:458
FIX::SessionID::getBeginString
const BeginString & getBeginString() const
Definition: SessionID.h:87
FIX::Session::generateLogon
void generateLogon()
Definition: Session.cpp:690
FIX::Session::isSessionRegistered
static bool isSessionRegistered(const SessionID &)
Definition: Session.cpp:1548
FIX::LogFactory::destroy
virtual void destroy(Log *)=0
FIX::Session::generateTestRequest
void generateTestRequest(const std::string &)
Definition: Session.cpp:809
FIX::Session::populateRejectReason
void populateRejectReason(Message &, int field, const std::string &)
Definition: Session.cpp:1026
FIX::Session::fromCallback
void fromCallback(const MsgType &msgType, const Message &msg, const SessionID &sessionID)
Definition: Session.cpp:1154
FIX::SessionRejectReason_TAG_APPEARS_MORE_THAN_ONCE_TEXT
const char SessionRejectReason_TAG_APPEARS_MORE_THAN_ONCE_TEXT[]
Definition: Values.h:67
FIX::Responder::disconnect
virtual void disconnect()=0
FIX::Session::Session
Session(Application &, MessageStoreFactory &, const SessionID &, const DataDictionaryProvider &, const TimeRange &, int heartBtInt, LogFactory *pLogFactory)
Definition: Session.cpp:58
FIX::Session::sendRaw
bool sendRaw(Message &, int msgSeqNum=0)
Definition: Session.cpp:547
FIX::BusinessRejectReason_OTHER_TEXT
const char BusinessRejectReason_OTHER_TEXT[]
Definition: Values.h:70
FIX::SessionState::sentLogon
bool sentLogon() const
Definition: SessionState.h:93
FIX::SessionRejectReason_INVALID_TAG_NUMBER_TEXT
const char SessionRejectReason_INVALID_TAG_NUMBER_TEXT[]
Definition: Values.h:55
FIX::Session::doPossDup
bool doPossDup(const Message &msg)
Definition: Session.cpp:1175
FIX::SessionState::onIncoming
void onIncoming(const std::string &string)
Definition: SessionState.h:234
FIX::BusinessRejectReason_DELIVERTO_FIRM_NOT_AVAILABLE_AT_THIS_TIME_TEXT
const char BusinessRejectReason_DELIVERTO_FIRM_NOT_AVAILABLE_AT_THIS_TIME_TEXT[]
Definition: Values.h:77
FIX::Session::fill
void fill(Header &)
Definition: Session.cpp:131
FIX::Message::isAdminMsgType
static bool isAdminMsgType(const MsgType &msgType)
Definition: Message.h:317
FIX::DataDictionary::validate
static void validate(const Message &message, const DataDictionary *const pSessionDD, const DataDictionary *const pAppID)
Validate a message.
Definition: DataDictionary.cpp:123
FIX::SessionState::logoutReason
std::string logoutReason() const
Definition: SessionState.h:184
FIX::Session::isLoggedOn
bool isLoggedOn()
Definition: Session.h:99
FIX::SessionState::lastReceivedTime
void lastReceivedTime(const UtcTimeStamp &value)
Definition: SessionState.h:142
FIX::Session::addSession
static bool addSession(Session &)
Definition: Session.cpp:1576
FIX::FieldNotFound
Field not found inside a message.
Definition: Exceptions.h:74
FIX::Application::onLogout
virtual void onLogout(const SessionID &)=0
Notification of a session logging off or disconnecting.
FIX::Session::isCorrectCompID
bool isCorrectCompID(const SenderCompID &senderCompID, const TargetCompID &targetCompID)
Definition: Session.h:298
FIX::FieldMap::getField
FieldBase & getField(FieldBase &field) const
Get a field without type checking.
Definition: FieldMap.h:190
FIX::SessionState::receivedLogon
bool receivedLogon() const
Definition: SessionState.h:87
FIX::SessionNotFound
Session cannot be found for specified action.
Definition: Exceptions.h:248
FIX::Message
Base class for all FIX messages.
Definition: Message.h:134
FIX::SessionState::shouldSendLogon
bool shouldSendLogon() const
Definition: SessionState.h:149
FIX::Session::m_application
Application & m_application
Definition: Session.h:352
reverse
void reverse(I begin, I end)
Definition: pugixml.cpp:6009
FIX::Session::getExpectedSenderNum
int getExpectedSenderNum()
Definition: Session.h:258
FIX::SessionState::resendRequested
bool resendRequested() const
Definition: SessionState.h:114
FIX::Session::isEnabled
bool isEnabled()
Definition: Session.h:93
FIX
Definition: Acceptor.cpp:34
FIX::Session::doTargetTooHigh
void doTargetTooHigh(const Message &msg)
Definition: Session.cpp:1223
FIX::SessionState::store
MessageStore * store()
Definition: SessionState.h:123
FIX::Session::nextSequenceReset
void nextSequenceReset(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:336
FIX::Session::isTargetTooHigh
bool isTargetTooHigh(const MsgSeqNum &msgSeqNum)
Definition: Session.h:294
FIX::Session::nextResendRequest
void nextResendRequest(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:361
FIX::DataDictionary
Represents a data dictionary for a version of FIX.
Definition: DataDictionary.h:66
FIX::SessionRejectReason_SENDINGTIME_ACCURACY_PROBLEM_TEXT
const char SessionRejectReason_SENDINGTIME_ACCURACY_PROBLEM_TEXT[]
Definition: Values.h:65
FIX::Session::shouldSendReset
bool shouldSendReset()
Definition: Session.cpp:1123
FIX::SessionState::logoutTimedOut
bool logoutTimedOut() const
Definition: SessionState.h:156
FIX::SessionID::getTargetCompID
const TargetCompID & getTargetCompID() const
Definition: SessionID.h:91
FIX::Session::generateHeartbeat
void generateHeartbeat()
Definition: Session.cpp:781
FIX::Session::disconnect
void disconnect()
Definition: Session.cpp:630
FIX::Session::nextHeartbeat
void nextHeartbeat(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:297
Session.h
FIELD_GET_PTR
#define FIELD_GET_PTR(MAP, FLD)
Definition: FieldMap.h:374
FIX::SessionRejectReason_INVALID_MSGTYPE_TEXT
const char SessionRejectReason_INVALID_MSGTYPE_TEXT[]
Definition: Values.h:66
FIX::Header
Definition: Message.h:58
FIX::SessionState::sentReset
bool sentReset() const
Definition: SessionState.h:99
FIX::Session::~Session
virtual ~Session()
Definition: Session.cpp:100
FIX::Session::logon
void logon()
Definition: Session.h:89
FIX::SessionRejectReason_TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER_TEXT
const char SessionRejectReason_TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER_TEXT[]
Definition: Values.h:68
FIX::Session::sendToTarget
static bool sendToTarget(Message &message, const std::string &qualifier="")
Definition: Session.cpp:1461
FIX::identifyType
MsgType identifyType(const std::string &message)
Parse the type of a message from a string.
Definition: Message.h:434
FIX::Application::onLogon
virtual void onLogon(const SessionID &)=0
Notification of a session successfully logging on.
FIX::FieldMap::setField
void setField(const FieldBase &field, bool overwrite=true)
Set a field without type checking.
Definition: FieldMap.h:150
FIX::Session::m_pResponder
Responder * m_pResponder
Definition: Session.h:375
FIX::SessionRejectReason_TAG_SPECIFIED_WITHOUT_A_VALUE_TEXT
const char SessionRejectReason_TAG_SPECIFIED_WITHOUT_A_VALUE_TEXT[]
Definition: Values.h:59
FIX::SessionState::needHeartbeat
bool needHeartbeat() const
Definition: SessionState.h:172
FIX::Locker
Locks/Unlocks a mutex using RAII.
Definition: Mutex.h:112
FIX::Session::logout
void logout(const std::string &reason="")
Definition: Session.h:91
FIX::Application::fromApp
virtual void fromApp(const Message &, const SessionID &)=0
Notification of app message being received from target.
FIX::Session::persist
void persist(const Message &, const std::string &)
Definition: Session.cpp:680
FIX::Session::nextTestRequest
void nextTestRequest(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:304
FIX::SessionState::onEvent
void onEvent(const std::string &string)
Definition: SessionState.h:238
FIX::Session::m_dataDictionaryProvider
DataDictionaryProvider m_dataDictionaryProvider
Definition: Session.h:372
FIX::Session::m_mutex
Mutex m_mutex
Definition: Session.h:376
FIX::Session::s_mutex
static Mutex s_mutex
Definition: Session.h:381
FIX::Session::m_validateLengthAndChecksum
bool m_validateLengthAndChecksum
Definition: Session.h:369
FIX::BusinessRejectReason_UNKNOWN_SECURITY_TEXT
const char BusinessRejectReason_UNKNOWN_SECURITY_TEXT[]
Definition: Values.h:72
FIX::InvalidMessage
Not a recognizable message.
Definition: Exceptions.h:97
FIX::Session::generateLogout
void generateLogout(const std::string &text="")
Definition: Session.cpp:1013
FIX::message_order
Sorts fields in header, normal, or trailer order.
Definition: MessageSorters.h:130
FIX::Session::insertSendingTime
void insertSendingTime(Header &)
Definition: Session.cpp:108
FIX::BusinessRejectReason_APPLICATION_NOT_AVAILABLE_TEXT
const char BusinessRejectReason_APPLICATION_NOT_AVAILABLE_TEXT[]
Definition: Values.h:74
FIELD_GET_REF
#define FIELD_GET_REF(MAP, FLD)
Definition: FieldMap.h:376
FIX::Session::resend
bool resend(Message &message)
Definition: Session.cpp:660
FIX::SessionRejectReason_INCORRECT_DATA_FORMAT_FOR_VALUE_TEXT
const char SessionRejectReason_INCORRECT_DATA_FORMAT_FOR_VALUE_TEXT[]
Definition: Values.h:61
FIX::Session::nextLogout
void nextLogout(const Message &, const UtcTimeStamp &timeStamp)
Definition: Session.cpp:312
FIX::Session::m_refreshOnLogon
bool m_refreshOnLogon
Definition: Session.h:366
FIX::Application::toApp
virtual void toApp(Message &, const SessionID &)=0
Notification of app message being sent to target.
FIX::SessionState::incrNextTargetMsgSeqNum
void incrNextTargetMsgSeqNum()
Definition: SessionState.h:221
FIX::Session::m_pLogFactory
LogFactory * m_pLogFactory
Definition: Session.h:374
FIX::SessionState::resendRange
ResendRange resendRange() const
Definition: SessionState.h:119
FIX::SessionState::logonTimedOut
bool logonTimedOut() const
Definition: SessionState.h:151
FIX::Message::getHeader
const Header & getHeader() const
Getter for the message header.
Definition: Message.h:262
FIX::Session::m_resetOnDisconnect
bool m_resetOnDisconnect
Definition: Session.h:365
FIX::SessionState::lastSentTime
void lastSentTime(const UtcTimeStamp &value)
Definition: SessionState.h:135
FIX::Session
Maintains the state and implements the logic of a FIX session.
Definition: Session.h:62
FIX::Application::fromAdmin
virtual void fromAdmin(const Message &, const SessionID &)=0
Notification of admin message being received from target.
FIX::Session::send
bool send(Message &)
Definition: Session.cpp:540
FIX::Session::insertOrigSendingTime
void insertOrigSendingTime(Header &, const UtcTimeStamp &when=UtcTimeStamp())
Definition: Session.cpp:120
FIX::SessionState::heartBtInt
void heartBtInt(const HeartBtInt &value)
Definition: SessionState.h:128
FIX::Session::newMessage
Message * newMessage(const std::string &msgType) const
Definition: Session.cpp:509
FIX::Session::nextQueued
void nextQueued(const UtcTimeStamp &timeStamp)
Definition: Session.cpp:1255

Generated on Wed Apr 29 2020 19:41:30 for QuickFIX by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2001