Skip to content

Commit 72f5f25

Browse files
committed
Added logger function
1 parent 0b10737 commit 72f5f25

7 files changed

Lines changed: 262 additions & 93 deletions

File tree

Makefile.common

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ OBJ_LIB += \
7979
src/proto/hdlc/high_level/hdlc.o \
8080
src/proto/hdlc/low_level/hdlc.o \
8181
src/proto/fd/tiny_fd.o \
82+
src/proto/fd/tiny_fd_proto_logger.o \
8283
src/proto/fd/tiny_fd_frames.o \
8384
src/hal/tiny_list.o \
8485
src/hal/tiny_debug.o \

README.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,20 @@ Tiny Protocol is NOT an application layer protocol, although, for example, it ca
3939

4040
## Key Features
4141

42-
Main features:
43-
* Hot plug/unplug support for ABM (peer to peer).
44-
* Connection autorecover for Full duplex (both for ABM and NRM modes) and Light protocols (with enabled crc)
45-
* Error detection: Simple 8-bit checksum (sum of bytes), FCS16 (CCITT-16), FCS32 (CCITT-32)
46-
* Platform independent hdlc framing implementation (hdlc low level API: hdlc_ll_xxxx)
47-
* Easy to use Light protcol - analogue of a SLIP protcol (tiny_light_xxxx API, see examples)
48-
* Full-duplex protocol (tiny_fd_xxxx true RFC 1662 implementation, supports confirmation, frames retransmissions: ABM and NRM modes )
49-
* one to one and one to many modes
50-
* Frames of maximum 32K or 2G size (payload limit depends on platfrom).
51-
* Low SRAM consumption (starts at 60 bytes).
52-
* Low Flash consumption (starts at 1.2KiB, features can be disabled and enabled at compilation time)
53-
* No dynamic memory allocation!
54-
* Special serial loopback tool for debug purposes and performance testing (ABM mode only)
42+
**Main Features:**
43+
44+
- **Hot Plug/Unplug Support:** Seamless connection and disconnection handling for ABM (peer-to-peer) mode.
45+
- **Comprehensive Logging:** HDLC full-duplex log function simplifies protocol debugging by capturing all packets sent or received by a peer, including data, service (S), and unnumbered (U) frames.
46+
- **Automatic Connection Recovery:** Robust autorecovery for full-duplex (ABM and NRM modes) and Light protocols (with CRC enabled).
47+
- **Error Detection:** Supports simple 8-bit checksum, FCS16 (CCITT-16), and FCS32 (CCITT-32) for reliable communication.
48+
- **Platform-Independent HDLC Framing:** Low-level HDLC API (`hdlc_ll_xxxx`) ensures portability across platforms.
49+
- **Easy-to-Use Light Protocol:** Lightweight protocol similar to SLIP (`tiny_light_xxxx` API), see examples for usage.
50+
- **Full-Duplex Protocol:** True RFC 1662 implementation (`tiny_fd_xxxx`), supporting acknowledgments, frame retransmissions, and both ABM and NRM modes.
51+
- **Flexible Topologies:** Supports both one-to-one and one-to-many communication modes.
52+
- **Large Frame Support:** Handles frames up to 32K or 2G in size (payload limit depends on platform).
53+
- **Low Resource Consumption:** Minimal SRAM usage (starting at 60 bytes) and flash footprint (starting at 1.3 KiB). Features can be enabled or disabled at compile time.
54+
- **No Dynamic Memory Allocation:** Ensures predictable memory usage.
55+
- **Serial Loopback Tool:** Dedicated tool for debugging and performance testing (ABM mode only).
5556

5657
## Supported platforms
5758

src/proto/fd/tiny_fd.c

Lines changed: 3 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -64,79 +64,6 @@ static uint8_t __switch_to_next_peer(tiny_fd_handle_t handle)
6464
return start_peer != handle->next_peer;
6565
}
6666

67-
#if defined(TINY_FD_DEBUG) && defined(TINY_FILE_LOGGING)
68-
///////////////////////////////////////////////////////////////////////////////
69-
70-
static char __get_frame_type(uint8_t control)
71-
{
72-
if ((control & HDLC_I_FRAME_MASK) == HDLC_I_FRAME_BITS)
73-
{
74-
return 'I';
75-
}
76-
else if ((control & HDLC_S_FRAME_MASK) == HDLC_S_FRAME_BITS)
77-
{
78-
return 'S';
79-
}
80-
return 'U';
81-
}
82-
83-
///////////////////////////////////////////////////////////////////////////////
84-
85-
static const char *__get_frame_type_str(uint8_t control)
86-
{
87-
char type = __get_frame_type(control);
88-
if (type == 'I') {
89-
return " ";
90-
}
91-
else if (type == 'S') {
92-
switch (control & HDLC_S_FRAME_TYPE_MASK)
93-
{
94-
case HDLC_S_FRAME_TYPE_RR: return " RR";
95-
case HDLC_S_FRAME_TYPE_REJ: return " REJ";
96-
default: return " UNK";
97-
}
98-
}
99-
switch (control & HDLC_U_FRAME_TYPE_MASK)
100-
{
101-
case HDLC_U_FRAME_TYPE_UA: return " UA";
102-
case HDLC_U_FRAME_TYPE_FRMR: return "FRMR";
103-
case HDLC_U_FRAME_TYPE_RSET: return "RSET";
104-
case HDLC_U_FRAME_TYPE_SABM: return "SABM";
105-
case HDLC_U_FRAME_TYPE_SNRM: return "SNRM";
106-
case HDLC_U_FRAME_TYPE_DISC: return "DISC";
107-
default: return " UNK";
108-
}
109-
}
110-
111-
///////////////////////////////////////////////////////////////////////////////
112-
113-
static uint8_t __get_frame_sequence(uint8_t control)
114-
{
115-
char type = __get_frame_type(control);
116-
switch (type)
117-
{
118-
case 'I': return (control >> 1) & 0x07;
119-
case 'S':
120-
case 'U':
121-
default: return 0;
122-
}
123-
}
124-
125-
///////////////////////////////////////////////////////////////////////////////
126-
127-
static uint8_t __get_awaiting_sequence(uint8_t control)
128-
{
129-
char type = __get_frame_type(control);
130-
switch (type)
131-
{
132-
case 'I': return control >> 5;
133-
case 'S': return control >> 5;
134-
case 'U':
135-
default: return 0;
136-
}
137-
}
138-
#endif // TINY_FD_DEBUG && TINY_FILE_LOGGING
139-
14067
///////////////////////////////////////////////////////////////////////////////
14168

14269
#if 0
@@ -232,8 +159,7 @@ static void on_frame_read(void *user_data, uint8_t *data, int len)
232159
LOG(TINY_LOG_WRN, "%s: received too small frame\n", "FD");
233160
return;
234161
}
235-
FILE_LOG((uintptr_t)handle, " IN", __get_frame_type(data[1]), __get_frame_type_str(data[1]),
236-
__get_frame_sequence(data[1]), __get_awaiting_sequence(data[1]));
162+
__tiny_fd_log_frame(handle, TINY_FD_FRAME_DIRECTION_IN, data, len);
237163
uint8_t peer = __address_field_to_peer( handle, ((uint8_t *)data)[0] );
238164
if ( peer == 0xFF )
239165
{
@@ -444,6 +370,7 @@ int tiny_fd_init(tiny_fd_handle_t *handle, tiny_fd_init_t *init)
444370
protocol->on_read_cb = init->on_read_cb;
445371
protocol->on_send_cb = init->on_send_cb;
446372
protocol->on_connect_event_cb = init->on_connect_event_cb;
373+
protocol->log_frame_cb = init->log_frame_cb;
447374
protocol->send_timeout = init->send_timeout;
448375
// By default assign primary address
449376
protocol->addr = (init->addr ? (init->addr << 2) : HDLC_PRIMARY_ADDR ) | HDLC_E_BIT;
@@ -594,9 +521,7 @@ static uint8_t *tiny_fd_get_next_frame_to_send(tiny_fd_handle_t handle, int *len
594521
header->control |= HDLC_P_BIT;
595522
handle->last_marker_ts = tiny_millis();
596523
handle->peers[peer].last_ka_ts = tiny_millis();
597-
FILE_LOG((uintptr_t)handle, "OUT", __get_frame_type(header->control),
598-
__get_frame_type_str(header->control),
599-
__get_frame_sequence(header->control), __get_awaiting_sequence(header->control));
524+
__tiny_fd_log_frame(handle, TINY_FD_FRAME_DIRECTION_OUT, data, *len);
600525
}
601526
tiny_mutex_unlock(&handle->frames.mutex);
602527
return data;

src/proto/fd/tiny_fd.h

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2019-2024 (C) Alexey Dynda
2+
Copyright 2019-2025 (C) Alexey Dynda
33
44
This file is part of Tiny Protocol Library.
55
@@ -78,6 +78,9 @@ extern "C"
7878
TINY_FD_MODE_ARM = 0x02,
7979
};
8080

81+
/**
82+
* Forward declaration of tiny_fd_data_t structure.
83+
*/
8184
struct tiny_fd_data_t;
8285

8386
/**
@@ -86,6 +89,71 @@ extern "C"
8689
*/
8790
typedef struct tiny_fd_data_t *tiny_fd_handle_t;
8891

92+
/**
93+
* Enumeration of frame types used in Tiny Full Duplex protocol.
94+
*/
95+
typedef enum
96+
{
97+
TINY_FD_FRAME_TYPE_I = 0x00, ///< I-frame
98+
TINY_FD_FRAME_TYPE_S = 0x01, ///< S-frame
99+
TINY_FD_FRAME_TYPE_U = 0x02, ///< U-frame
100+
} tiny_fd_frame_type_t;
101+
102+
/**
103+
* Enumeration of frame subtypes used in Tiny Full Duplex protocol.
104+
* These subtypes are used for S-frames and U-frames.
105+
* The I-frames do not have subtypes, so this enumeration is not used for I-frames.
106+
*/
107+
typedef enum
108+
{
109+
TINY_FD_FRAME_SUBTYPE_RR = 0x00, ///< S-frame subtype RR
110+
TINY_FD_FRAME_SUBTYPE_REJ = 0x08, ///< S-frame subtype REJ
111+
112+
TINY_FD_FRAME_SUBTYPE_UA = 0x60, ///< U-frame subtype UA
113+
TINY_FD_FRAME_SUBTYPE_FRMR = 0x84, ///< U-frame subtype FRMR
114+
TINY_FD_FRAME_SUBTYPE_RSET = 0x8C, ///< U-frame subtype RSET
115+
TINY_FD_FRAME_SUBTYPE_SABM = 0x2C, ///< U-frame subtype SABM
116+
TINY_FD_FRAME_SUBTYPE_SNRM = 0x80, ///< U-frame subtype SNRM
117+
TINY_FD_FRAME_SUBTYPE_DISC = 0x40, ///< U-frame subtype DISC
118+
} tiny_fd_frame_subtype_t;
119+
120+
/**
121+
* Enumeration of frame directions used in Tiny Full Duplex protocol.
122+
*/
123+
typedef enum
124+
{
125+
TINY_FD_FRAME_DIRECTION_IN = 0x00, ///< Frame is incoming
126+
TINY_FD_FRAME_DIRECTION_OUT = 0x01, ///< Frame is outgoing
127+
} tiny_fd_frame_direction_t;
128+
129+
/**
130+
* tiny_fd_log_frame_cb_t is a callback function, which is called every time frame is sent or received.
131+
* This callback is useful for debugging purposes.
132+
*
133+
* The main difference between this callback and on_frame_read_cb_t / on_frame_send_cb_t is that
134+
* this callback is called for every frame, regardless of whether it is sent or received: I-frames, S-frames or U-frames.
135+
* It provides detailed information about the frame, including its type, subtype, sequence numbers and data.
136+
*
137+
* @param handle handle of Tiny.
138+
* @param direction direction of the frame, can be TINY_FD_FRAME_DIRECTION_IN or TINY_FD_FRAME_DIRECTION_OUT.
139+
* @param frame_type type of the frame, can be TINY_FD_FRAME_TYPE_I, TINY_FD_FRAME_TYPE_S or TINY_FD_FRAME_TYPE_U.
140+
* @param frame_subtype subtype of the frame, can be TINY_FD_FRAME_SUBTYPE_RR, TINY_FD_FRAME_SUBTYPE_REJ,
141+
* TINY_FD_FRAME_SUBTYPE_UA, TINY_FD_FRAME_SUBTYPE_FRMR, TINY_FD_FRAME_SUBTYPE_RSET,
142+
* TINY_FD_FRAME_SUBTYPE_SABM, TINY_FD_FRAME_SUBTYPE_SNRM or TINY_FD_FRAME_SUBTYPE_DISC.
143+
* @param ns N(S) sequence number of the frame.
144+
* @param nr N(R) sequence number of the frame.
145+
* @param data pointer to the frame data.
146+
* @param len length of the frame data.
147+
*/
148+
typedef void (*tiny_fd_log_frame_cb_t)(tiny_fd_handle_t handle,
149+
tiny_fd_frame_direction_t direction,
150+
tiny_fd_frame_type_t frame_type,
151+
tiny_fd_frame_subtype_t frame_subtype,
152+
uint8_t ns,
153+
uint8_t nr,
154+
const uint8_t *data,
155+
int len);
156+
89157
/**
90158
* This structure is used for initialization of Tiny Full Duplex protocol.
91159
*/
@@ -153,6 +221,13 @@ extern "C"
153221
*/
154222
on_connect_event_cb_t on_connect_event_cb;
155223

224+
/**
225+
* Callback to log frames. Can be NULL.
226+
* If this callback is set, it will be called for every frame sent or received.
227+
* This is useful for debugging purposes.
228+
*/
229+
tiny_fd_log_frame_cb_t log_frame_cb;
230+
156231
/**
157232
* Local station address. The field has meaning only for secondary stations.
158233
* For primary stations please, leave this field as 0.

src/proto/fd/tiny_fd_int.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ extern "C"
118118
on_frame_send_cb_t on_send_cb;
119119
/// Callback to get connect/disconnect notification
120120
on_connect_event_cb_t on_connect_event_cb;
121+
/// Callback to log frames
122+
tiny_fd_log_frame_cb_t log_frame_cb;
121123
/// hdlc information
122124
hdlc_ll_handle_t _hdlc;
123125
/// Timeout for operations with acknowledge
@@ -148,6 +150,12 @@ extern "C"
148150
void *user_data;
149151
} tiny_fd_data_t;
150152

153+
extern void __tiny_fd_log_frame(
154+
tiny_fd_handle_t handle,
155+
tiny_fd_frame_direction_t direction,
156+
const uint8_t *data,
157+
int len);
158+
151159
#ifdef __cplusplus
152160
}
153161
#endif

0 commit comments

Comments
 (0)