1- use std:: { cell:: RefCell , rc:: Rc } ;
1+ use std:: {
2+ cell:: { Cell , RefCell } ,
3+ rc:: Rc ,
4+ } ;
25
36use easyfix_messages:: {
47 fields:: {
@@ -152,6 +155,8 @@ pub(crate) struct Session<S> {
152155 settings : Settings ,
153156 session_settings : SessionSettings ,
154157 emitter : Emitter ,
158+ // Not in SessionState as I/O layer asks for this value often
159+ heartbeat_interval : Cell < u64 > ,
155160}
156161
157162impl < S : MessagesStorage > Session < S > {
@@ -162,12 +167,16 @@ impl<S: MessagesStorage> Session<S> {
162167 sender : Sender ,
163168 emitter : Emitter ,
164169 ) -> Session < S > {
170+ let heartbeat_interval = settings
171+ . heartbeat_interval
172+ . unwrap_or ( settings. auto_disconnect_after_no_logout . as_secs ( ) ) ;
165173 Session {
166174 state,
167175 settings,
168176 session_settings,
169177 sender,
170178 emitter,
179+ heartbeat_interval : Cell :: new ( heartbeat_interval) ,
171180 }
172181 }
173182
@@ -385,7 +394,7 @@ impl<S: MessagesStorage> Session<S> {
385394 self . send ( Box :: new ( Message :: Logon ( Logon {
386395 // encrypt_method: EncryptMethod::None,
387396 encrypt_method : EncryptMethod :: NoneOther ,
388- heart_bt_int : state . heart_bt_int ( ) ,
397+ heart_bt_int : self . heartbeat_interval . get ( ) . try_into ( ) . unwrap_or ( Int :: MAX ) ,
389398 reset_seq_num_flag : self . should_send_reset ( state) . then_some ( true ) ,
390399 next_expected_msg_seq_num : if self . session_settings . enable_next_expected_msg_seq_num {
391400 let next_expected_msg_seq_num = state. next_sender_msg_seq_num ( ) ;
@@ -406,8 +415,7 @@ impl<S: MessagesStorage> Session<S> {
406415
407416 self . send ( Box :: new ( Message :: Logon ( Logon {
408417 encrypt_method : EncryptMethod :: NoneOther ,
409- // TODO: option to use predefined OR the value from Logon request
410- heart_bt_int : state. heart_bt_int ( ) ,
418+ heart_bt_int : self . heartbeat_interval . get ( ) . try_into ( ) . unwrap_or ( Int :: MAX ) ,
411419 reset_seq_num_flag : self . should_send_reset ( state) . then_some ( true ) ,
412420 next_expected_msg_seq_num,
413421 // TODO: if self.session_settings.session_id().is_fixt()
@@ -965,8 +973,17 @@ impl<S: MessagesStorage> Session<S> {
965973 !Self :: is_target_too_high ( & state, msg_seq_num) || self . session_settings . reset_on_logon ;
966974
967975 if !state. initiate ( ) || ( state. reset_received ( ) && !state. reset_sent ( ) ) {
968- state. set_heart_bt_int ( heart_bt_int) ;
969976 info ! ( "Received logon request" ) ;
977+ if self . settings . heartbeat_interval . is_none ( ) {
978+ if heart_bt_int <= 0 {
979+ return Err ( VerifyError :: Reject {
980+ reason : SessionRejectReason :: ValueIsIncorrect ,
981+ tag : Some ( FieldTag :: HeartBtInt ) ,
982+ disconnect_reason : None ,
983+ } ) ;
984+ }
985+ self . heartbeat_interval . set ( heart_bt_int as u64 ) ;
986+ }
970987
971988 if enable_next_expected_msg_seq_num {
972989 let mut next_expected_target_num = state. next_target_msg_seq_num ( ) ;
@@ -1375,11 +1392,7 @@ impl<S: MessagesStorage> Session<S> {
13751392 }
13761393
13771394 pub fn heartbeat_interval ( & self ) -> Duration {
1378- // TODO: logon.heartbeat_interval, value from settings is for n8 only (implement as Reject
1379- // on Logon)
1395+ Duration :: from_secs ( self . heartbeat_interval . get ( ) )
13801396
1381- //let inbound_test_request_timeout_duration =
1382- // self.settings.heartbeat_interval + NO_INBOUND_TIMEOUT_PADDING;
1383- self . settings . heartbeat_interval
13841397 }
13851398}
0 commit comments