Skip to content

Commit

Permalink
Code refactoring - split into many smaller files
Browse files Browse the repository at this point in the history
  • Loading branch information
lexus2k committed Aug 1, 2024
1 parent 8653d77 commit 4eea18b
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 255 deletions.
13 changes: 9 additions & 4 deletions .hash_db
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@
./src/TinyProtocol.h:c62154a96ab5c19eea3d574b0a4cb3da
./src/proto/crc/tiny_crc.h:ec366c5c7751a822b2c4931e40150a84
./src/proto/crc/tiny_crc.c:904b6700e7edb0c290eafe9fbad7df2e
./src/proto/hdlc/low_level/hdlc.c:20786efe6fba177fd500bafe14f46b00
./src/proto/hdlc/low_level/hdlc.c:ccb4f8dcc65d371f2494730dd3e88176
./src/proto/hdlc/low_level/hdlc.h:363274fa5423ccaaf4c312c9948234c4
./src/proto/hdlc/low_level/hdlc_int.h:5086b2643f08bce859d8e367888df9f3
./src/proto/hdlc/high_level/hdlc.c:49e72944973f5abbe7821ccfc98fcfe2
./src/proto/hdlc/high_level/hdlc.h:8a8ee3205e6a3b646877369fd7dc37ca
./src/proto/fd/tiny_fd_frames.c:ce8b268ac2b5f9c06ea27efaecb2da1c
./src/proto/fd/tiny_fd_int.h:297a74e45acf3fac3032a6d1aa2eaebf
./src/proto/fd/tiny_fd_frames_int.h:883f459f0da1e8c9c9aee6e9cd930597
./src/proto/fd/tiny_fd.c:895afbb17e4737adfac5d2dee827d840
./src/proto/fd/tiny_fd.c:33ae52811c21356633f600eef6f83e56
./src/proto/fd/tiny_fd.h:e4bf3d5757e5a651a3260b2fb8e5f187
./src/proto/light/tiny_light.c:762620e03e620b0b3928078c83c06952
./src/proto/light/tiny_light.h:6d1ac27584d2c414e83d7da46f953632
./src/hal/tiny_debug.h:27d6374dd4deb09b1d98f62e25b0f1a5
./src/hal/tiny_list.c:db940e41cce84752164648cb9e1613df
./src/hal/tiny_types.h:34e617f439dbf7ae0fe7a019005c65db
./src/hal/tiny_types.h:ae8a32b5f0e0fdd300f6e8378532d393
./src/hal/tiny_serial.h:5f53d1f334637e32ccc8a1370f600641
./src/hal/tiny_list.h:69b562367054b805e7e27581e427e5bd
./src/hal/tiny_types.c:c3639fc3c23134af643e8335450cd582
Expand Down Expand Up @@ -107,9 +107,14 @@
./build/CMakeFiles/3.22.1/CompilerIdCXX/CMakeCXXCompilerId.cpp:8f6ee0d17bc4d5795212007f40d90e59
./build/lib.linux-x86_64-3.10/tinyproto/helpers/__init__.py:9df0084a1c0b1cadec43caaf0b21cc20
./build/lib.linux-x86_64-3.10/tinyproto/wrappers/__init__.py:d4882c0a8b1d2cd9b93c0ebb4d00f8c8
./unittest/fd_multidrop_tests.cpp:c92b46501ad2da42ebb0bcec588e6375
./unittest/fd_multidrop_tests.cpp:e3ec7b831de4c358c9d3f0f744fe7b57
./src/hal/tiny_types_cpp.cpp:0153fbfd1f3f42ef78a9ca6deeaec0dc
./src/hal/freertos/freertos_hal.h:64ed002a698414e1e258434ee799e8b9
./src/hal/freertos/freertos_hal.inl:7463e053c8b4a6d68d74614cf936dc1b
./src/hal/cpp/cpp_hal.h:f35701b7333807fc1c3f591b55112c57
./src/hal/cpp/cpp_hal.inl:a214dca4b7ba191f4708163b36bbe4c0
./src/proto/fd/tiny_fd_defines_int.h:d422989b820047e6199bb164464fd044
./src/proto/fd/tiny_fd_peers_int.h:7d4b4629892bc3fa4bdb2479fd22c673
./src/proto/fd/tiny_fd_service_queue_int.h:d6899a160b44566752ad5e069986d456
./src/proto/fd/tiny_fd_on_rx_int.h:9eb94ddc6b12b1cab87916b387ba88e3
./src/proto/fd/tiny_fd_data_queue_int.h:f52317491990ad67e8daf39c504081e0
2 changes: 1 addition & 1 deletion src/hal/tiny_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ extern "C"
#else

/// This macro is used internally for aligning the structures
#define TINY_ALIGN_STRUCT_VALUE (sizeof(uintptr_t))
#define TINY_ALIGN_STRUCT_VALUE (uintptr_t)(sizeof(uintptr_t))

#endif

Expand Down
239 changes: 3 additions & 236 deletions src/proto/fd/tiny_fd.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "tiny_fd_peers_int.h"
#include "tiny_fd_service_queue_int.h"
#include "tiny_fd_data_queue_int.h"
#include "tiny_fd_on_rx_int.h"
#include "hal/tiny_types.h"
#include "hal/tiny_debug.h"

Expand Down Expand Up @@ -88,114 +89,6 @@ static inline uint32_t __time_passed_since_last_marker_seen(tiny_fd_handle_t han

///////////////////////////////////////////////////////////////////////////////

static int __check_received_frame(tiny_fd_handle_t handle, uint8_t peer, uint8_t ns)
{
int result = TINY_SUCCESS;
if ( ns == handle->peers[peer].next_nr )
{
// this is what, we've been waiting for
// LOG("[%p] Confirming received frame <= %d\n", handle, ns);
handle->peers[peer].next_nr = (handle->peers[peer].next_nr + 1) & seq_bits_mask;
handle->peers[peer].sent_reject = 0;
}
else
{
// definitely we need to send reject. We want to see next_nr frame
LOG(TINY_LOG_ERR, "[%p] Out of order I-Frame N(s)=%d\n", handle, ns);
if ( !handle->peers[peer].sent_reject )
{
tiny_frame_header_t frame = {
.address = __peer_to_address_field( handle, peer ) | HDLC_CR_BIT,
.control = HDLC_S_FRAME_BITS | HDLC_S_FRAME_TYPE_REJ | (handle->peers[peer].next_nr << 5),
};
handle->peers[peer].sent_reject = 1;
__put_u_s_frame_to_tx_queue(handle, TINY_FD_QUEUE_S_FRAME, &frame, sizeof(tiny_frame_header_t));
}
result = TINY_ERR_FAILED;
}
return result;
}

///////////////////////////////////////////////////////////////////////////////

static void __confirm_sent_frames(tiny_fd_handle_t handle, uint8_t peer, uint8_t nr)
{
// all frames below nr are received
while ( nr != handle->peers[peer].confirm_ns )
{
if ( handle->peers[peer].confirm_ns == handle->peers[peer].last_ns )
{
// TODO: Out of sync
LOG(TINY_LOG_CRIT, "[%p] Confirmation contains wrong N(r). Remote side is out of sync\n", handle);
break;
}
uint8_t address = __peer_to_address_field( handle, peer );
// LOG("[%p] Confirming sent frames %d\n", handle, handle->peers[peer].confirm_ns);
tiny_fd_frame_info_t *slot = tiny_fd_queue_get_next( &handle->frames.i_queue, TINY_FD_QUEUE_I_FRAME, address, handle->peers[peer].confirm_ns );
if ( slot != NULL )
{
if ( handle->on_send_cb )
{
tiny_mutex_unlock(&handle->frames.mutex);
handle->on_send_cb(handle->user_data,
__is_primary_station( handle ) ? (__peer_to_address_field( handle, peer ) >> 2) : TINY_FD_PRIMARY_ADDR,
&slot->payload[0], slot->len);
tiny_mutex_lock(&handle->frames.mutex);
}
tiny_fd_queue_free( &handle->frames.i_queue, slot );
if ( tiny_fd_queue_has_free_slots( &handle->frames.i_queue ) )
{
// Unblock tx queue to allow application to put new frames for sending
tiny_events_set(&handle->events, FD_EVENT_QUEUE_HAS_FREE_SLOTS);
}
}
else
{
// This should never happen !!!
// TODO: Add error processing
LOG(TINY_LOG_ERR, "[%p] The frame cannot be confirmed: %02X\n", handle, handle->peers[peer].confirm_ns);
}
handle->peers[peer].confirm_ns = (handle->peers[peer].confirm_ns + 1) & seq_bits_mask;
handle->peers[peer].retries = handle->retries;
}
if ( __can_accept_i_frames( handle, peer ) )
{
// Unblock specific peer to accept new frames for sending
tiny_events_set(&handle->peers[peer].events, FD_EVENT_CAN_ACCEPT_I_FRAMES);
}
LOG(TINY_LOG_DEB, "[%p] Last confirmed frame: %02X\n", handle, handle->peers[peer].confirm_ns);
// LOG("[%p] N(S)=%d, N(R)=%d\n", handle, handle->peers[peer].confirm_ns, handle->peers[peer].next_nr);
}

///////////////////////////////////////////////////////////////////////////////

static void __resend_all_unconfirmed_frames(tiny_fd_handle_t handle, uint8_t peer, uint8_t control, uint8_t nr)
{
// First, we need to check if that is possible. Maybe remote side is not in sync
while ( handle->peers[peer].next_ns != nr )
{
if ( handle->peers[peer].confirm_ns == handle->peers[peer].next_ns )
{
// consider here that remote side is not in sync, we cannot perform request
LOG(TINY_LOG_CRIT, "[%p] Remote side not in sync\n", handle);
tiny_fd_u_frame_t frame = {
.header.address = __peer_to_address_field( handle, peer ) | HDLC_CR_BIT,
.header.control = HDLC_U_FRAME_TYPE_FRMR | HDLC_U_FRAME_BITS,
.data1 = control,
.data2 = (handle->peers[peer].next_nr << 5) | (handle->peers[peer].next_ns << 1),
};
// Send 2-byte header + 2 extra bytes
__put_u_s_frame_to_tx_queue(handle, TINY_FD_QUEUE_U_FRAME, &frame, 4);
break;
}
handle->peers[peer].next_ns = (handle->peers[peer].next_ns - 1) & seq_bits_mask;
}
LOG(TINY_LOG_DEB, "[%p] N(s) is set to %02X\n", handle, handle->peers[peer].next_ns);
tiny_events_set(&handle->events, FD_EVENT_TX_DATA_AVAILABLE);
}

///////////////////////////////////////////////////////////////////////////////

static void __switch_to_connected_state(tiny_fd_handle_t handle, uint8_t peer)
{
if ( handle->peers[peer].state != TINY_FD_STATE_CONNECTED )
Expand All @@ -208,6 +101,8 @@ static void __switch_to_connected_state(tiny_fd_handle_t handle, uint8_t peer)
handle->peers[peer].sent_nr = 0;
handle->peers[peer].sent_reject = 0;
tiny_fd_queue_reset_for( &handle->frames.i_queue, __peer_to_address_field( handle, peer ) );
// Reset last arrived frame timestamp on connection.
// This is required to avoid disconnection on keep alive timeout at the beginning of connection
handle->peers[peer].last_ka_ts = tiny_millis();
tiny_events_set(&handle->peers[peer].events, FD_EVENT_CAN_ACCEPT_I_FRAMES);
tiny_events_set(
Expand Down Expand Up @@ -253,134 +148,6 @@ static void __switch_to_disconnected_state(tiny_fd_handle_t handle, uint8_t peer
}
}

///////////////////////////////////////////////////////////////////////////////

static int __on_i_frame_read(tiny_fd_handle_t handle, uint8_t peer, void *data, int len)
{
uint8_t control = ((uint8_t *)data)[1];
uint8_t nr = control >> 5;
uint8_t ns = (control >> 1) & 0x07;
LOG(TINY_LOG_INFO, "[%p] Receiving I-Frame N(R)=%02X,N(S)=%02X with address [%02X]\n", handle, nr, ns, ((uint8_t *)data)[0]);
int result = __check_received_frame(handle, peer, ns);
__confirm_sent_frames(handle, peer, nr);
// Provide data to user only if we expect this frame
if ( result == TINY_SUCCESS )
{
if ( handle->on_read_cb )
{
tiny_mutex_unlock(&handle->frames.mutex);
handle->on_read_cb(handle->user_data,
__is_primary_station( handle ) ? (__peer_to_address_field( handle, peer ) >> 2) : TINY_FD_PRIMARY_ADDR,
(uint8_t *)data + 2, len - 2);
tiny_mutex_lock(&handle->frames.mutex);
}
// Decide whenever we need to send RR after user callback
// Check if we need to send confirmations separately. If we have something to send, just skip RR S-frame.
// Also at this point, since we received expected frame, sent_reject will be cleared to 0.
if ( __all_frames_are_sent(handle, peer) && handle->peers[peer].sent_nr != handle->peers[peer].next_nr )
{
tiny_frame_header_t frame = {
.address = __peer_to_address_field( handle, peer ),
.control = HDLC_S_FRAME_BITS | HDLC_S_FRAME_TYPE_RR | (handle->peers[peer].next_nr << 5),
};
__put_u_s_frame_to_tx_queue(handle, TINY_FD_QUEUE_S_FRAME, &frame, 2);
}
}
return result;
}

///////////////////////////////////////////////////////////////////////////////

static int __on_s_frame_read(tiny_fd_handle_t handle, uint8_t peer, void *data, int len)
{
uint8_t address = ((uint8_t *)data)[0];
uint8_t control = ((uint8_t *)data)[1];
uint8_t nr = control >> 5;
int result = TINY_ERR_FAILED;
LOG(TINY_LOG_INFO, "[%p] Receiving S-Frame N(R)=%02X, type=%s with address [%02X]\n", handle, nr,
((control >> 2) & 0x03) == 0x00 ? "RR" : "REJ", ((uint8_t *)data)[0]);
if ( (control & HDLC_S_FRAME_TYPE_MASK) == HDLC_S_FRAME_TYPE_REJ )
{
__confirm_sent_frames(handle, peer, nr);
__resend_all_unconfirmed_frames(handle, peer, control, nr);
}
else if ( (control & HDLC_S_FRAME_TYPE_MASK) == HDLC_S_FRAME_TYPE_RR )
{
__confirm_sent_frames(handle, peer, nr);
if ( address & HDLC_CR_BIT )
{
// Send answer if we don't have frames to send
if ( handle->peers[peer].next_ns == handle->peers[peer].last_ns )
{
tiny_frame_header_t frame = {
.address = __peer_to_address_field( handle, peer ),
.control = HDLC_S_FRAME_BITS | HDLC_S_FRAME_TYPE_RR | (handle->peers[peer].next_nr << 5),
};
__put_u_s_frame_to_tx_queue(handle, TINY_FD_QUEUE_S_FRAME, &frame, 2);
}
}
}
return result;
}

///////////////////////////////////////////////////////////////////////////////

static int __on_u_frame_read(tiny_fd_handle_t handle, uint8_t peer, void *data, int len)
{
uint8_t control = ((uint8_t *)data)[1];
uint8_t type = control & HDLC_U_FRAME_TYPE_MASK;
int result = TINY_ERR_FAILED;
LOG(TINY_LOG_INFO, "[%p] Receiving U-Frame type=%02X with address [%02X]\n", handle, type, ((uint8_t *)data)[0]);
if ( type == HDLC_U_FRAME_TYPE_SABM || type == HDLC_U_FRAME_TYPE_SNRM )
{
tiny_frame_header_t frame = {
.address = __peer_to_address_field( handle, peer ),
.control = HDLC_U_FRAME_TYPE_UA | HDLC_U_FRAME_BITS,
};
__put_u_s_frame_to_tx_queue(handle, TINY_FD_QUEUE_U_FRAME, &frame, 2);
if ( handle->peers[peer].state == TINY_FD_STATE_CONNECTED )
{
__switch_to_disconnected_state(handle, peer);
}
__switch_to_connected_state(handle, peer);
}
else if ( type == HDLC_U_FRAME_TYPE_DISC )
{
tiny_frame_header_t frame = {
.address = __peer_to_address_field( handle, peer ),
.control = HDLC_U_FRAME_TYPE_UA | HDLC_U_FRAME_BITS,
};
__put_u_s_frame_to_tx_queue(handle, TINY_FD_QUEUE_U_FRAME, &frame, 2);
__switch_to_disconnected_state(handle, peer);
}
else if ( type == HDLC_U_FRAME_TYPE_RSET )
{
// resets N(R) = 0 in secondary, resets N(S) = 0 in primary
// expected answer UA
}
else if ( type == HDLC_U_FRAME_TYPE_FRMR )
{
// response of secondary in case of protocol errors: invalid control field, invalid N(R),
// information field too long or not expected in this frame
}
else if ( type == HDLC_U_FRAME_TYPE_UA )
{
if ( handle->peers[peer].state == TINY_FD_STATE_CONNECTING )
{
// confirmation received
__switch_to_connected_state(handle, peer);
}
else if ( handle->peers[peer].state == TINY_FD_STATE_DISCONNECTING )
{
__switch_to_disconnected_state(handle, peer);
}
}
else
{
LOG(TINY_LOG_WRN, "[%p] Unknown hdlc U-frame received\n", handle);
}
return result;
}

///////////////////////////////////////////////////////////////////////////////

Expand Down
Loading

0 comments on commit 4eea18b

Please sign in to comment.