Skip to content

Commit 725f5ef

Browse files
committed
Fixing errors in tiny_fd_send_to() and adding more unit tests
1 parent 3ee452d commit 725f5ef

2 files changed

Lines changed: 103 additions & 23 deletions

File tree

src/proto/fd/tiny_fd.c

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,8 @@ static void on_frame_send(void *user_data, const uint8_t *data, int len)
260260

261261
///////////////////////////////////////////////////////////////////////////////
262262

263-
int tiny_fd_init(tiny_fd_handle_t *handle, tiny_fd_init_t *init)
263+
static int __tiny_fd_init_validate(tiny_fd_handle_t *handle, tiny_fd_init_t *init, uint8_t peers_count)
264264
{
265-
const uint8_t peers_count = init->peers_count == 0 ? 1 : init->peers_count;
266265
*handle = NULL;
267266
if ( (0 == init->on_read_cb) || (0 == init->buffer) || (0 == init->buffer_size) )
268267
{
@@ -273,7 +272,7 @@ int tiny_fd_init(tiny_fd_handle_t *handle, tiny_fd_init_t *init)
273272
{
274273
int size = tiny_fd_buffer_size_by_mtu_ex(peers_count, 0, init->window_frames, init->crc_type, 1);
275274
init->mtu = (init->buffer_size - size) / (init->window_frames + 1);
276-
if ( init->mtu < 1 )
275+
if ( init->mtu < 2 )
277276
{
278277
LOG(TINY_LOG_CRIT, "Calculated mtu size is zero, no payload transfer is available%s", "\n");
279278
return TINY_ERR_OUT_OF_MEMORY;
@@ -295,6 +294,21 @@ int tiny_fd_init(tiny_fd_handle_t *handle, tiny_fd_init_t *init)
295294
LOG(TINY_LOG_CRIT, "HDLC uses timeouts for ACK, at least retry_timeout, or send_timeout must be specified%s", "\n");
296295
return TINY_ERR_INVALID_DATA;
297296
}
297+
return TINY_SUCCESS;
298+
}
299+
300+
///////////////////////////////////////////////////////////////////////////////
301+
302+
int tiny_fd_init(tiny_fd_handle_t *handle, tiny_fd_init_t *init)
303+
{
304+
const uint8_t peers_count = init->peers_count == 0 ? 1 : init->peers_count;
305+
{
306+
int result = __tiny_fd_init_validate(handle, init, peers_count);
307+
if (result != TINY_SUCCESS)
308+
{
309+
return result;
310+
}
311+
}
298312
memset(init->buffer, 0, init->buffer_size);
299313

300314
/* Lets locate main FD protocol data at the beginning of specified buffer.
@@ -815,20 +829,27 @@ int tiny_fd_buffer_size_by_mtu(int mtu, int window)
815829

816830
int tiny_fd_buffer_size_by_mtu_ex(uint8_t peers_count, int mtu, int tx_window, hdlc_crc_t crc_type, int rx_window)
817831
{
832+
// If peers_count is not specified, then we assume that there is only one peer
818833
if ( !peers_count )
819834
{
820835
peers_count = 1;
821836
}
822-
// Alignment requirements are already satisfied by hdlc_ll_get_buf_size_ex() subfunction call
823-
return sizeof(tiny_fd_data_t) + TINY_ALIGN_STRUCT_VALUE - 1 +
824-
peers_count * sizeof(tiny_fd_peer_info_t) +
825-
// RX side
826-
hdlc_ll_get_buf_size_ex(mtu + sizeof(tiny_frame_header_t), crc_type, rx_window) +
837+
// Aligned size to keep protocol related state machine information
838+
int header_size = sizeof(tiny_fd_data_t) + TINY_ALIGN_STRUCT_VALUE - 1 +
839+
peers_count * sizeof(tiny_fd_peer_info_t);
840+
// Buffer size to hold HDLC low level protocol RX data
841+
int hdlc_level_rx_size = hdlc_ll_get_buf_size_ex(mtu + sizeof(tiny_frame_header_t), crc_type, rx_window);
842+
// minimum size of i-frame including header and payload
843+
int i_frame_tx_size = (sizeof(tiny_fd_frame_info_t *) + sizeof(tiny_fd_frame_info_t) + mtu -
844+
sizeof(((tiny_fd_frame_info_t *)0)->payload));
845+
// minimum size of s-frame/u-frame including header and 2-bytes payload
846+
// this size includes internal library overhead, introduced by the pointer to the frame info
847+
int u_s_frame_tx_size = (sizeof(tiny_fd_frame_info_t *) + sizeof(tiny_fd_frame_info_t));
848+
return header_size +
849+
hdlc_level_rx_size +
827850
// TX side
828-
(sizeof(tiny_fd_frame_info_t *) + sizeof(tiny_fd_frame_info_t) + mtu -
829-
sizeof(((tiny_fd_frame_info_t *)0)->payload)) *
830-
tx_window +
831-
(sizeof(tiny_fd_frame_info_t *) + sizeof(tiny_fd_frame_info_t)) * TINY_FD_U_QUEUE_MAX_SIZE;
851+
i_frame_tx_size * tx_window +
852+
u_s_frame_tx_size * TINY_FD_U_QUEUE_MAX_SIZE;
832853
}
833854

834855
///////////////////////////////////////////////////////////////////////////////
@@ -850,18 +871,20 @@ int tiny_fd_get_mtu(tiny_fd_handle_t handle)
850871
int tiny_fd_send_to(tiny_fd_handle_t handle, uint8_t address, const void *data, int len, uint32_t timeout)
851872
{
852873
const uint8_t *ptr = (const uint8_t *)data;
853-
int left = len;
854-
while ( left > 0 )
874+
int left_bytes = len;
875+
while ( left_bytes > 0 )
855876
{
856-
int size = left < tiny_fd_queue_get_mtu( &handle->frames.i_queue ) ? left : tiny_fd_queue_get_mtu( &handle->frames.i_queue );
877+
int size = left_bytes < tiny_fd_queue_get_mtu( &handle->frames.i_queue ) ?
878+
left_bytes : tiny_fd_queue_get_mtu( &handle->frames.i_queue );
857879
int result = tiny_fd_send_packet_to(handle, address, ptr, size, timeout);
858880
if ( result != TINY_SUCCESS )
859881
{
860882
break;
861883
}
862-
left -= result;
884+
ptr += size;
885+
left_bytes -= size;
863886
}
864-
return left;
887+
return len - left_bytes;
865888
}
866889

867890
///////////////////////////////////////////////////////////////////////////////

unittest/tiny_fd_tests.cpp

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,30 @@ TEST_GROUP(TINY_FD)
120120
CHECK(connected); // Connection should be established
121121
CHECK_EQUAL(4, len);
122122
}
123+
124+
void reinitializeWithMtu(int mtu)
125+
{
126+
tiny_fd_close(handle); // Close the previous handle
127+
tiny_fd_init_t init{};
128+
init.pdata = this;
129+
init.on_connect_event_cb = __onConnect;
130+
init.on_read_cb = onRead;
131+
init.on_send_cb = onSend;
132+
init.log_frame_cb = logFrame;
133+
init.buffer = inBuffer.data();
134+
init.buffer_size = inBuffer.size();
135+
init.window_frames = 7;
136+
init.send_timeout = 1000;
137+
init.retry_timeout = 100;
138+
init.retries = 2;
139+
init.mode = TINY_FD_MODE_ABM;
140+
init.peers_count = 1; // For ABM mode, only one peer is needed
141+
init.crc_type = HDLC_CRC_OFF;
142+
init.mtu = mtu; // Set MTU
143+
auto result = tiny_fd_init(&handle, &init);
144+
CHECK_EQUAL(TINY_SUCCESS, result);
145+
}
146+
123147
};
124148

125149

@@ -150,11 +174,6 @@ TEST(TINY_FD, ABM_ConnectDisconnectResponse)
150174
CHECK(!connected); // Connection should be disconnected
151175
}
152176

153-
TEST(TINY_FD, ABM_ConnecionTestRequest)
154-
{
155-
// TODO
156-
}
157-
158177
TEST(TINY_FD, ABM_DisconnectResponseWhenNotConnected)
159178
{
160179
connected = true; // this flag should not be changed if not connected
@@ -327,4 +346,42 @@ TEST(TINY_FD, ABM_CheckLoggerFunction)
327346
auto read_result = tiny_fd_on_rx_data(handle, (uint8_t *)"\x7E\x03\x00\x11\x7E", 5); // I-frame in order
328347
CHECK_EQUAL(TINY_SUCCESS, read_result);
329348
CHECK_EQUAL(3, counter); // We should have logged 3 frames now
330-
}
349+
}
350+
351+
TEST(TINY_FD, ABM_CheckMtuAndSendSplit)
352+
{
353+
// Check MTU reinitialization
354+
reinitializeWithMtu(2); // Set new MTU
355+
int mtu = tiny_fd_get_mtu(handle);
356+
CHECK_EQUAL(2, mtu); // MTU should be equal to 2
357+
establishConnection(); // Establish connection with new MTU
358+
// Now we can send I-frames
359+
// Check that 5-byte frame is split into 3 frames of 2 bytes each
360+
int result = tiny_fd_send_to(handle, TINY_FD_PRIMARY_ADDR, (const void *)"\x01\x02\x03\x04\x05", 5, 1000);
361+
CHECK_EQUAL(5, result); // We should have sent 5 bytes
362+
int len = tiny_fd_get_tx_data(handle, outBuffer.data(), outBuffer.size(), 100);
363+
CHECK_EQUAL(17, len); // We should have 3 I-frames of 2 bytes, 2 bytes and 1 byte
364+
// Check first I-frame
365+
CHECK_EQUAL(0x7E, outBuffer[0]); // Flag
366+
CHECK_EQUAL(0x01, outBuffer[1]); // Address field
367+
CHECK_EQUAL(0x10, outBuffer[2]); // Control byte
368+
CHECK_EQUAL(0x01, outBuffer[3]); // Data byte
369+
CHECK_EQUAL(0x02, outBuffer[4]); // Data byte
370+
CHECK_EQUAL(0x7E, outBuffer[5]); // Flag
371+
// Check second I-frame
372+
CHECK_EQUAL(0x7E, outBuffer[6]); // Flag
373+
CHECK_EQUAL(0x01, outBuffer[7]); // Address field
374+
CHECK_EQUAL(0x12, outBuffer[8]); // Control byte
375+
CHECK_EQUAL(0x03, outBuffer[9]); // Data byte
376+
CHECK_EQUAL(0x04, outBuffer[10]); // Data byte
377+
CHECK_EQUAL(0x7E, outBuffer[11]); // Flag
378+
// Check third I-frame
379+
CHECK_EQUAL(0x7E, outBuffer[12]); // Flag
380+
CHECK_EQUAL(0x01, outBuffer[13]); // Address field
381+
CHECK_EQUAL(0x14, outBuffer[14]); // Control byte
382+
CHECK_EQUAL(0x05, outBuffer[15]); // Data byte
383+
CHECK_EQUAL(0x7E, outBuffer[16]); // Flag
384+
// Check that I-frame larger than mtu size cannot be sent
385+
result = tiny_fd_send_packet_to(handle, TINY_FD_PRIMARY_ADDR, (const void *)"\x01\x02\x03", 3, 1000);
386+
CHECK_EQUAL(TINY_ERR_DATA_TOO_LARGE, result); // Should return error for frame larger than MTU
387+
}

0 commit comments

Comments
 (0)