Skip to content

Commit 819289a

Browse files
committed
Added couple NRM tests
1 parent d2fea28 commit 819289a

8 files changed

Lines changed: 535 additions & 59 deletions

File tree

Makefile.cpputest

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ OBJ_UNIT_TEST = \
1818
unittest/packet_tests.o \
1919
unittest/hdlc_tests.o \
2020
unittest/light_tests.o \
21-
unittest/tiny_fd_tests.o \
21+
unittest/tiny_fd_abm_tests.o \
22+
unittest/tiny_fd_nrm_tests.o \
2223
unittest/fd_tests.o \
2324
unittest/fd_multidrop_tests.o \
2425

src/hal/tiny_debug.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static FILE *get_log_file(uintptr_t id)
4848
return NULL;
4949
}
5050
// Num# - is frame number, Exp# - is expected frame number from remote peer
51-
fprintf(log_file, " time ms, DIR, FR, Type, Num#, Exp#\n");
51+
fprintf(log_file, " time ms, DIR, ADDR, FR, Type, Num#, Exp#\n");
5252
}
5353
return log_file;
5454
}

src/proto/fd/tiny_fd.c

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -46,26 +46,6 @@ static void on_frame_send(void *user_data, const uint8_t *data, int len);
4646
// Helper functions
4747
///////////////////////////////////////////////////////////////////////////////
4848

49-
static uint8_t __switch_to_next_peer(tiny_fd_handle_t handle)
50-
{
51-
const uint8_t start_peer = handle->next_peer;
52-
do
53-
{
54-
if ( ++handle->next_peer >= handle->peers_count )
55-
{
56-
handle->next_peer = 0;
57-
}
58-
if ( handle->peers[ handle->next_peer ].addr != HDLC_INVALID_PEER_INDEX )
59-
{
60-
break;
61-
}
62-
} while ( start_peer != handle->next_peer );
63-
LOG(TINY_LOG_INFO, "[%p] Switching to peer [%02X]\n", handle, handle->next_peer);
64-
return start_peer != handle->next_peer;
65-
}
66-
67-
///////////////////////////////////////////////////////////////////////////////
68-
6949
#if 0
7050
static inline uint8_t __number_of_awaiting_tx_i_frames(tiny_fd_handle_t handle, uint8_t peer)
7151
{
@@ -208,15 +188,24 @@ static void on_frame_read(void *user_data, uint8_t *data, int len)
208188
{
209189
LOG(TINY_LOG_WRN, "[%p] Unknown hdlc frame received\n", handle);
210190
}
211-
if ( control & HDLC_P_BIT )
191+
// Check that if we are in NRM mode then we have something to send
192+
if ( handle->mode == TINY_FD_MODE_NRM )
212193
{
213-
// Check that if we are in NRM mode then we have something to send
214-
if ( handle->mode == TINY_FD_MODE_NRM )
194+
if ( control & ( HDLC_P_BIT | HDLC_F_BIT ) )
215195
{
216196
LOG(TINY_LOG_INFO, "[%p] [CAPTURED MARKER]\n", handle);
197+
// Cool! Now we have marker again, and we can send
198+
tiny_events_set( &handle->events, FD_EVENT_HAS_MARKER );
199+
// For primary station
200+
// 1. Switch to the next peer
201+
// 2. If no I-frames to send, then put RR S-frame to the queue with poll bit set
202+
// 3. If I-frames to send, then send I-frames (1 or multiple)
203+
// 3.1. The last one should have final bit set
204+
// For secondary station
205+
// 1. If no I-frames to send, then put RR S-frame to the queue with poll bit set
206+
// 2. If I-frames to send, then send I-frames (1 or multiple)
207+
// 2.1. The last one should have final bit set
217208
}
218-
// Cool! Now we have marker again, and we can send
219-
tiny_events_set( &handle->events, FD_EVENT_HAS_MARKER );
220209
}
221210
tiny_mutex_unlock(&handle->frames.mutex);
222211
}
@@ -247,23 +236,28 @@ static void on_frame_send(void *user_data, const uint8_t *data, int len)
247236
tiny_fd_queue_free_by_header( &handle->frames.s_queue, data );
248237
}
249238
// Clear send flag and clear marker if final was transferred. For ABM mode the marker is never cleared
250-
uint8_t flags = FD_EVENT_TX_SENDING;
251-
if ( (control & HDLC_F_BIT) && handle->mode == TINY_FD_MODE_NRM )
239+
uint8_t flags_to_clear = FD_EVENT_TX_SENDING;
240+
if ( handle->mode == TINY_FD_MODE_NRM )
252241
{
253242
// Let's talk to the next station if we are primary
254243
// Of course, we could switch to the next peer upon receving response
255244
// from the peer we provided the marker to... But what? What if
256245
// remote peer never responds to us. So, having switch procedure
257246
// in this callback simplifies things
258-
if ( __is_primary_station( handle ) )
247+
if ( __is_primary_station( handle ) && (control & HDLC_P_BIT) )
259248
{
260249
__switch_to_next_peer( handle );
250+
LOG(TINY_LOG_INFO, "[%p] [RELEASED MARKER]\n", handle);
251+
flags_to_clear |= FD_EVENT_HAS_MARKER;
252+
}
253+
else if ( !__is_primary_station( handle ) && (control & HDLC_F_BIT) )
254+
{
255+
LOG(TINY_LOG_INFO, "[%p] [RELEASED MARKER]\n", handle);
256+
flags_to_clear |= FD_EVENT_HAS_MARKER;
261257
}
262-
LOG(TINY_LOG_INFO, "[%p] [RELEASED MARKER]\n", handle);
263-
flags |= FD_EVENT_HAS_MARKER;
264258
}
265-
tiny_events_clear( &handle->events, flags );
266-
tiny_mutex_unlock(&handle->frames.mutex);
259+
tiny_events_clear( &handle->events, flags_to_clear );
260+
tiny_mutex_unlock( &handle->frames.mutex );
267261
}
268262

269263
///////////////////////////////////////////////////////////////////////////////
@@ -421,6 +415,7 @@ int tiny_fd_init(tiny_fd_handle_t *handle, tiny_fd_init_t *init)
421415

422416
tiny_mutex_create(&protocol->frames.mutex);
423417
tiny_events_create(&protocol->events);
418+
// Primary station has marker by default
424419
tiny_events_set( &protocol->events, FD_EVENT_QUEUE_HAS_FREE_SLOTS |
425420
(__is_primary_station( protocol ) ? FD_EVENT_HAS_MARKER : 0) );
426421
*handle = protocol;
@@ -629,7 +624,12 @@ static void tiny_fd_disconnected_check_idle_timeout(tiny_fd_handle_t handle, uin
629624

630625
int tiny_fd_get_tx_data(tiny_fd_handle_t handle, void *data, int len, uint32_t timeout)
631626
{
627+
// TODO: !!!!!
628+
// We cannot generate data forever, and we should return result as soon as possible
629+
// Now this is not true for NRM mode, as we can generate data forever until
630+
// passed buffer is filled up.
632631
bool repeat = true;
632+
bool wait_point_passed = false;
633633
int result = 0;
634634
// TODO: Check for correct mutex usage here. Some fields are not protected
635635
const uint8_t peer = handle->next_peer;
@@ -656,6 +656,11 @@ int tiny_fd_get_tx_data(tiny_fd_handle_t handle, void *data, int len, uint32_t t
656656
{
657657
tiny_fd_disconnected_check_idle_timeout(handle, peer);
658658
}
659+
// TODO: This point cannot be reached twice!!!!
660+
if (wait_point_passed) {
661+
break;
662+
}
663+
wait_point_passed = true;
659664
// Since no send operation is in progress, check if we have something to send
660665
// Check if the station has marker to send FIRST (That means, we are allowed to send anything still)
661666
if ( tiny_events_wait(&handle->events, FD_EVENT_HAS_MARKER, EVENT_BITS_LEAVE, timeout ) )
@@ -689,7 +694,7 @@ int tiny_fd_get_tx_data(tiny_fd_handle_t handle, void *data, int len, uint32_t t
689694
{
690695
if ( __time_passed_since_last_marker_seen(handle) >= handle->retry_timeout )
691696
{
692-
// Return marker back as remote station not responding
697+
// Return marker back to primary station as remote station not responding
693698
LOG(TINY_LOG_CRIT, "[%p] RETURN MARKER BACK\n", handle );
694699
tiny_events_set( &handle->events, FD_EVENT_HAS_MARKER );
695700
}
@@ -699,7 +704,9 @@ int tiny_fd_get_tx_data(tiny_fd_handle_t handle, void *data, int len, uint32_t t
699704
}
700705
}
701706
}
702-
result += generated_data;
707+
if (result >= 0) {
708+
result += generated_data;
709+
}
703710
if ( !generated_data )
704711
{
705712
if ( !repeat )
@@ -964,6 +971,7 @@ int tiny_fd_register_peer(tiny_fd_handle_t handle, uint8_t address)
964971
tiny_mutex_lock(&handle->frames.mutex);
965972
if ( __address_field_to_peer( handle, address ) != HDLC_INVALID_PEER_INDEX )
966973
{
974+
// Peer already registered
967975
tiny_mutex_unlock(&handle->frames.mutex);
968976
return TINY_ERR_FAILED;
969977
}

src/proto/fd/tiny_fd_defines_int.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,47 @@
3838
#define LOG(lvl, fmt, ...) TINY_LOG(lvl, fmt, ##__VA_ARGS__)
3939
// id - unique id of the protocol instance
4040
// direction - direction of the log, can be "OUT" or "IN"
41+
// addr - address of the peer, can be primary or secondary station address
4142
// frame type - 'S', 'I' or 'U'
4243
// subtype - subtype of the frame, can be "RR", "REJ", "UA", etc.
4344
// ns - N(S) sequence number, nr - N(R) sequence number
44-
#define FILE_LOG(id, direction, frame, subtype, ns, nr) \
45-
TINY_FILE_LOG(id, "%s, %c, %s, %d, %d\n", direction, frame, subtype, ns, nr)
45+
#define FILE_LOG(id, direction, addr, frame, subtype, ns, nr) \
46+
TINY_FILE_LOG(id, "%s, %02X, %c, %s, %d, %d\n", direction, addr, frame, subtype, ns, nr)
4647
#else
4748
#define LOG(...)
4849
#define FILE_LOG(...)
4950
#endif
5051

5152
enum
5253
{
54+
/**
55+
* FD_EVENT_TX_SENDING indicates that currently frame is being sent.
56+
* Higer layer will not try to send new frames until this event is cleared.
57+
*/
5358
FD_EVENT_TX_SENDING = 0x01, // Global event
59+
60+
/**
61+
* FD_EVENT_TX_DATA_AVAILABLE indicates that there is data available for transmission.
62+
* This event is set when there is data in the TX queue.
63+
*/
5464
FD_EVENT_TX_DATA_AVAILABLE = 0x02, // Global event
65+
66+
/**
67+
* FD_EVENT_QUEUE_HAS_FREE_SLOTS indicates that there are free slots in the TX queue.
68+
* This event is set when there is at least one free slot in the TX queue.
69+
* It is used to notify higher layers that they can send more data.
70+
*/
5571
FD_EVENT_QUEUE_HAS_FREE_SLOTS = 0x04, // Global event
72+
73+
/**
74+
* FD_EVENT_CAN_ACCEPT_I_FRAMES indicates that the protocol can accept new I-frames for sending.
75+
* This event is set when the protocol is ready to accept new I-frames.
76+
*/
5677
FD_EVENT_CAN_ACCEPT_I_FRAMES = 0x08, // Local event
78+
79+
/**
80+
*
81+
*/
5782
FD_EVENT_HAS_MARKER = 0x10, // Global event
5883
};
5984

src/proto/fd/tiny_fd_peers_int.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,26 @@ static uint8_t __peer_to_address_field(tiny_fd_handle_t handle, uint8_t peer)
8989
{
9090
return handle->peers[peer].addr & (~HDLC_CR_BIT);
9191
}
92+
93+
///////////////////////////////////////////////////////////////////////////////
94+
95+
static uint8_t __switch_to_next_peer(tiny_fd_handle_t handle)
96+
{
97+
const uint8_t start_peer = handle->next_peer;
98+
do
99+
{
100+
if ( ++handle->next_peer >= handle->peers_count )
101+
{
102+
handle->next_peer = 0;
103+
}
104+
if ( handle->peers[ handle->next_peer ].addr != HDLC_INVALID_PEER_INDEX )
105+
{
106+
break;
107+
}
108+
} while ( start_peer != handle->next_peer );
109+
LOG(TINY_LOG_INFO, "[%p] Switching to peer [%02X]\n", handle, handle->next_peer);
110+
return start_peer != handle->next_peer;
111+
}
112+
113+
///////////////////////////////////////////////////////////////////////////////
114+

src/proto/fd/tiny_fd_proto_logger.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ void __tiny_fd_log_frame(tiny_fd_handle_t handle,
153153
}
154154
FILE_LOG((uintptr_t)handle,
155155
direction == TINY_FD_FRAME_DIRECTION_IN ? " IN" : "OUT",
156+
data[0],
156157
__get_frame_type_str(data[1]),
157158
__get_frame_subtype_str(data[1]),
158159
__get_frame_sequence(data[1]),

0 commit comments

Comments
 (0)