Skip to content

Commit 69ad469

Browse files
committed
Connection breaks down if nothing is sent for >= keep alive timeout #40
1 parent 905cd4d commit 69ad469

5 files changed

Lines changed: 37 additions & 28 deletions

File tree

src/proto/fd/tiny_fd.c

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,14 @@ static inline uint8_t __number_of_awaiting_tx_i_frames(tiny_fd_handle_t handle,
7777

7878
static inline uint32_t __time_passed_since_last_frame_received(tiny_fd_handle_t handle, uint8_t peer)
7979
{
80-
return (uint32_t)(tiny_millis() - handle->peers[peer].last_ka_ts);
80+
return (uint32_t)(tiny_millis() - handle->peers[peer].last_received_frame_ts);
81+
}
82+
83+
///////////////////////////////////////////////////////////////////////////////
84+
85+
static inline uint32_t __time_passed_since_last_frame_sent(tiny_fd_handle_t handle, uint8_t peer)
86+
{
87+
return (uint32_t)(tiny_millis() - handle->peers[peer].last_sent_frame_ts);
8188
}
8289

8390
///////////////////////////////////////////////////////////////////////////////
@@ -103,7 +110,8 @@ static void __switch_to_connected_state(tiny_fd_handle_t handle, uint8_t peer)
103110
tiny_fd_queue_reset_for( &handle->frames.i_queue, __peer_to_address_field( handle, peer ) );
104111
// Reset last arrived frame timestamp on connection.
105112
// This is required to avoid disconnection on keep alive timeout at the beginning of connection
106-
handle->peers[peer].last_ka_ts = tiny_millis();
113+
handle->peers[peer].last_received_frame_ts = tiny_millis();
114+
handle->peers[peer].last_sent_frame_ts = tiny_millis();
107115
tiny_events_set(&handle->peers[peer].events, FD_EVENT_CAN_ACCEPT_I_FRAMES);
108116
tiny_events_set(
109117
&handle->events,
@@ -167,7 +175,7 @@ static void on_frame_read(void *user_data, uint8_t *data, int len)
167175
return;
168176
}
169177
tiny_mutex_lock(&handle->frames.mutex);
170-
handle->peers[peer].last_ka_ts = tiny_millis();
178+
handle->peers[peer].last_received_frame_ts = tiny_millis();
171179
handle->peers[peer].ka_confirmed = 1;
172180
uint8_t control = ((uint8_t *)data)[1];
173181
if ( (control & HDLC_U_FRAME_MASK) == HDLC_U_FRAME_MASK )
@@ -489,7 +497,7 @@ static uint8_t *tiny_fd_get_next_i_frame(tiny_fd_handle_t handle, int *len, uint
489497
handle->peers[peer].next_ns &= seq_bits_mask;
490498
// Move to different place
491499
handle->peers[peer].sent_nr = handle->peers[peer].next_nr;
492-
handle->peers[peer].last_i_ts = tiny_millis();
500+
handle->peers[peer].last_sent_i_ts = tiny_millis();
493501
}
494502
return data;
495503
}
@@ -534,7 +542,7 @@ static uint8_t *tiny_fd_get_next_frame_to_send(tiny_fd_handle_t handle, int *len
534542
tiny_frame_header_t *header = (tiny_frame_header_t *)data;
535543
header->control |= HDLC_P_BIT;
536544
handle->last_marker_ts = tiny_millis();
537-
handle->peers[peer].last_ka_ts = tiny_millis();
545+
handle->peers[peer].last_sent_frame_ts = tiny_millis();
538546
__tiny_fd_log_frame(handle, TINY_FD_FRAME_DIRECTION_OUT, data, *len);
539547
}
540548
tiny_mutex_unlock(&handle->frames.mutex);
@@ -548,15 +556,15 @@ static void tiny_fd_connected_check_idle_timeout(tiny_fd_handle_t handle, uint8_
548556
tiny_mutex_lock(&handle->frames.mutex);
549557
// If all I-frames are sent and no respond from the remote side
550558
if ( __has_unconfirmed_frames(handle, peer) && __all_frames_are_sent(handle, peer) &&
551-
__time_passed_since_last_i_frame(handle, peer) >= handle->retry_timeout )
559+
__time_passed_since_last_sent_i_frame(handle, peer) >= handle->retry_timeout )
552560
{
553561
// if sent frame was not confirmed due to noisy line
554562
if ( handle->peers[peer].retries > 0 )
555563
{
556564
LOG(TINY_LOG_WRN,
557565
"[%p] Timeout, resending unconfirmed frames: last(%" PRIu32 " ms, now(%" PRIu32 " ms), timeout(%" PRIu32
558566
" ms))\n",
559-
handle, handle->peers[peer].last_i_ts, tiny_millis(), handle->retry_timeout);
567+
handle, handle->peers[peer].last_sent_i_ts, tiny_millis(), handle->retry_timeout);
560568
handle->peers[peer].retries--;
561569
// Do not use mutex for confirm_ns value as it is byte-value
562570
__resend_all_unconfirmed_frames(handle, peer, 0, handle->peers[peer].confirm_ns);
@@ -567,24 +575,24 @@ static void tiny_fd_connected_check_idle_timeout(tiny_fd_handle_t handle, uint8_
567575
__switch_to_disconnected_state(handle, peer);
568576
}
569577
}
570-
else if ( __time_passed_since_last_frame_received(handle, peer) > handle->ka_timeout )
578+
else if ( __time_passed_since_last_frame_received(handle, peer) >= handle->ka_timeout * 2 )
571579
{
572580
if ( !handle->peers[peer].ka_confirmed )
573581
{
574582
LOG(TINY_LOG_ERR, "[%p] No keep alive after timeout\n", handle);
575583
__switch_to_disconnected_state(handle, peer);
576584
}
577-
else
578-
{
579-
// Nothing to send, all frames are confirmed, just send keep alive
580-
tiny_frame_header_t frame = {
581-
.address = __peer_to_address_field( handle, peer ),
582-
.control = HDLC_S_FRAME_BITS | HDLC_S_FRAME_TYPE_RR | (handle->peers[peer].next_nr << 5),
583-
};
584-
handle->peers[peer].ka_confirmed = 0;
585-
__put_u_s_frame_to_tx_queue(handle, TINY_FD_QUEUE_S_FRAME, &frame, 2);
586-
}
587-
handle->peers[peer].last_ka_ts = tiny_millis();
585+
}
586+
else if ( __time_passed_since_last_frame_sent(handle, peer) >= handle->ka_timeout )
587+
{
588+
// Nothing to send, all frames are confirmed, just send keep alive
589+
tiny_frame_header_t frame = {
590+
.address = __peer_to_address_field( handle, peer ),
591+
.control = HDLC_S_FRAME_BITS | HDLC_S_FRAME_TYPE_RR | (handle->peers[peer].next_nr << 5),
592+
};
593+
handle->peers[peer].ka_confirmed = 0;
594+
__put_u_s_frame_to_tx_queue(handle, TINY_FD_QUEUE_S_FRAME, &frame, 2);
595+
handle->peers[peer].last_sent_frame_ts = tiny_millis();
588596
}
589597
tiny_mutex_unlock(&handle->frames.mutex);
590598
}
@@ -611,7 +619,7 @@ static void tiny_fd_disconnected_check_idle_timeout(tiny_fd_handle_t handle, uin
611619
handle->next_peer, __peer_to_address_field( handle, peer ));
612620
}
613621
handle->peers[peer].state = TINY_FD_STATE_CONNECTING;
614-
handle->peers[peer].last_ka_ts = tiny_millis();
622+
handle->peers[peer].last_received_frame_ts = tiny_millis();
615623
}
616624
}
617625
tiny_mutex_unlock(&handle->frames.mutex);
@@ -965,7 +973,7 @@ int tiny_fd_register_peer(tiny_fd_handle_t handle, uint8_t address)
965973
if ( handle->peers[peer].addr == 0xFF )
966974
{
967975
handle->peers[peer].addr = address;
968-
handle->peers[peer].last_ka_ts = (uint32_t)(tiny_millis() - handle->retry_timeout);
976+
handle->peers[peer].last_received_frame_ts = (uint32_t)(tiny_millis() - handle->retry_timeout);
969977
tiny_mutex_unlock(&handle->frames.mutex);
970978
return TINY_SUCCESS;
971979
}

src/proto/fd/tiny_fd_data_queue_int.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ static inline bool __all_frames_are_sent(tiny_fd_handle_t handle, uint8_t peer)
4949

5050
///////////////////////////////////////////////////////////////////////////////
5151

52-
static inline uint32_t __time_passed_since_last_i_frame(tiny_fd_handle_t handle, uint8_t peer)
52+
static inline uint32_t __time_passed_since_last_sent_i_frame(tiny_fd_handle_t handle, uint8_t peer)
5353
{
54-
return (uint32_t)(tiny_millis() - handle->peers[peer].last_i_ts);
54+
return (uint32_t)(tiny_millis() - handle->peers[peer].last_sent_i_ts);
5555
}
5656

5757
///////////////////////////////////////////////////////////////////////////////

src/proto/fd/tiny_fd_int.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ extern "C"
9090
uint8_t confirm_ns; // next frame to be confirmed
9191
uint8_t last_ns; // next free frame in cycle buffer
9292

93-
uint32_t last_i_ts; // last sent I-frame timestamp
94-
uint32_t last_ka_ts; // last keep alive timestamp
93+
uint32_t last_sent_i_ts; // last sent I-frame timestamp
94+
uint32_t last_sent_frame_ts; // last sent keep alive timestamp
95+
uint32_t last_received_frame_ts; // last keep alive timestamp
9596
uint8_t ka_confirmed;
9697
uint8_t retries; // Number of retries to perform before timeout takes place
9798

unittest/fd_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,8 @@ TEST(FD, no_ka_switch_to_disconnected)
213213
TinyHelperFd helper2(&conn.endpoint2(), 1024, nullptr, 4, 100);
214214
conn.endpoint1().setTimeout(30);
215215
conn.endpoint2().setTimeout(30);
216-
helper1.set_ka_timeout(100);
217-
helper2.set_ka_timeout(100);
216+
helper1.set_ka_timeout(50);
217+
helper2.set_ka_timeout(50);
218218
helper1.run(true);
219219
helper2.run(true);
220220

unittest/tiny_fd_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ TEST(TINY_FD, ABM_CheckMtuAPI)
289289
// Check MTU API
290290
int mtu = tiny_fd_get_mtu(handle);
291291
CHECK(mtu > 0); // MTU should be greater than 0
292-
CHECK_EQUAL(34, mtu); // Assuming the MTU is 34 bytes according to protocol test configuration
292+
CHECK_EQUAL(33, mtu); // Assuming the MTU is 34 bytes according to protocol test configuration
293293
}
294294

295295
TEST(TINY_FD, ABM_CheckLoggerFunction)

0 commit comments

Comments
 (0)