|
36 | 36 | #include "tiny_fd_service_queue_int.h" |
37 | 37 | #include <stdint.h> |
38 | 38 |
|
| 39 | +typedef struct on_confirmed_ctx_t |
| 40 | +{ |
| 41 | + tiny_fd_handle_t handle; |
| 42 | + uint8_t peer; |
| 43 | +} on_confirmed_ctx_t; |
39 | 44 |
|
40 | 45 | /////////////////////////////////////////////////////////////////////////////// |
41 | 46 |
|
42 | | -void __confirm_sent_frames(tiny_fd_handle_t handle, uint8_t peer, uint8_t nr) |
| 47 | +static bool __on_frame_confirmed(void *ctx, uint8_t nr) |
43 | 48 | { |
44 | | - // Repeat the loop for all frames that are not confirmed yet till we reach N(r) |
45 | | - while ( nr != handle->peers[peer].i_queue_control.tx_state.confirm_ns ) |
| 49 | + on_confirmed_ctx_t *c = (on_confirmed_ctx_t *)ctx; |
| 50 | + tiny_fd_handle_t handle = c->handle; |
| 51 | + uint8_t peer = c->peer; |
| 52 | + |
| 53 | + uint8_t address = __peer_to_address_field( handle, peer ); |
| 54 | + tiny_fd_frame_info_t *slot = tiny_fd_queue_get_next( &handle->frames.i_queue, TINY_FD_QUEUE_I_FRAME, address, nr ); |
| 55 | + if ( slot != NULL ) |
46 | 56 | { |
47 | | - // if we reached the last sent frame index, but we have something to confirm |
48 | | - // it means that remote side is out of sync. |
49 | | - if ( !((handle->peers[peer].i_queue_control.tx_state.confirm_ns != handle->peers[peer].i_queue_control.tx_state.last_ns))) |
| 57 | + if ( handle->on_send_cb ) |
50 | 58 | { |
51 | | - // TODO: Out of sync |
52 | | - // No solution for this part yet. |
53 | | - LOG(TINY_LOG_CRIT, "[%p] Confirmation contains wrong N(r). Remote side is out of sync\n", handle); |
54 | | - break; |
| 59 | + tiny_mutex_unlock(&handle->frames.mutex); |
| 60 | + handle->on_send_cb(handle->user_data, |
| 61 | + __is_primary_station( handle ) ? (__peer_to_address_field( handle, peer ) >> 2) : TINY_FD_PRIMARY_ADDR, |
| 62 | + &slot->payload[0], slot->len); |
| 63 | + tiny_mutex_lock(&handle->frames.mutex); |
55 | 64 | } |
56 | | - uint8_t address = __peer_to_address_field( handle, peer ); |
57 | | - // Call on_send_cb to inform application that frame was sent |
58 | | - tiny_fd_frame_info_t *slot = tiny_fd_queue_get_next( &handle->frames.i_queue, TINY_FD_QUEUE_I_FRAME, address, handle->peers[peer].i_queue_control.tx_state.confirm_ns ); |
59 | | - if ( slot != NULL ) |
| 65 | + tiny_fd_queue_free( &handle->frames.i_queue, slot ); |
| 66 | + if ( tiny_fd_queue_has_free_slots( &handle->frames.i_queue ) ) |
60 | 67 | { |
61 | | - if ( handle->on_send_cb ) |
62 | | - { |
63 | | - tiny_mutex_unlock(&handle->frames.mutex); |
64 | | - handle->on_send_cb(handle->user_data, |
65 | | - __is_primary_station( handle ) ? (__peer_to_address_field( handle, peer ) >> 2) : TINY_FD_PRIMARY_ADDR, |
66 | | - &slot->payload[0], slot->len); |
67 | | - tiny_mutex_lock(&handle->frames.mutex); |
68 | | - } |
69 | | - tiny_fd_queue_free( &handle->frames.i_queue, slot ); |
70 | | - if ( tiny_fd_queue_has_free_slots( &handle->frames.i_queue ) ) |
71 | | - { |
72 | | - // Unblock tx queue to allow application to put new frames for sending |
73 | | - tiny_events_set(&handle->events, FD_EVENT_QUEUE_HAS_FREE_SLOTS); |
74 | | - } |
| 68 | + // Unblock tx queue to allow application to put new frames for sending |
| 69 | + tiny_events_set(&handle->events, FD_EVENT_QUEUE_HAS_FREE_SLOTS); |
75 | 70 | } |
76 | | - else |
77 | | - { |
78 | | - // This should never happen !!! |
79 | | - // TODO: Add error processing |
80 | | - LOG(TINY_LOG_ERR, "[%p] The frame cannot be confirmed: %02X\n", handle, handle->peers[peer].i_queue_control.tx_state.confirm_ns); |
81 | | - } |
82 | | - handle->peers[peer].i_queue_control.tx_state.confirm_ns = (handle->peers[peer].i_queue_control.tx_state.confirm_ns + 1) & seq_bits_mask; |
83 | 71 | handle->peers[peer].retries = handle->retries; |
| 72 | + return true; |
| 73 | + } |
| 74 | + else |
| 75 | + { |
| 76 | + handle->peers[peer].retries = handle->retries; |
| 77 | + return false; |
84 | 78 | } |
85 | | - // Check if we can accept new frames from the application. |
86 | | - if ( __can_accept_i_frames( &handle->peers[peer].i_queue_control ) ) |
| 79 | +} |
| 80 | + |
| 81 | +/////////////////////////////////////////////////////////////////////////////// |
| 82 | + |
| 83 | +void __confirm_sent_frames(tiny_fd_handle_t handle, uint8_t peer, uint8_t nr) |
| 84 | +{ |
| 85 | + on_confirmed_ctx_t ctx = { |
| 86 | + .handle = handle, |
| 87 | + .peer = peer |
| 88 | + }; |
| 89 | + if (__i_queue_control_confirm_sent_frames(&handle->peers[peer].i_queue_control, nr, __on_frame_confirmed, &ctx)) |
87 | 90 | { |
88 | 91 | // Unblock specific peer to accept new frames for sending |
89 | 92 | tiny_events_set(&handle->peers[peer].events, FD_EVENT_CAN_ACCEPT_I_FRAMES); |
90 | 93 | } |
91 | | - LOG(TINY_LOG_DEB, "[%p] Last confirmed frame: %02X\n", handle, handle->peers[peer].i_queue_control.tx_state.confirm_ns); |
92 | 94 | } |
93 | 95 |
|
94 | 96 | /////////////////////////////////////////////////////////////////////////////// |
|
0 commit comments