diff --git a/receiver b/receiver deleted file mode 100755 index b3012da168018ce8b34993d0c477e5d8bd2a24be..0000000000000000000000000000000000000000 Binary files a/receiver and /dev/null differ diff --git a/sender b/sender deleted file mode 100755 index 811a7a9727367dd055c14d51bcfa2aff83e99eb8..0000000000000000000000000000000000000000 Binary files a/sender and /dev/null differ diff --git a/src/receiver_utils.c b/src/receiver_utils.c index 28b29bbc03e10904918b87fb8594546d08d0ff64..423b4a22b2d9028d0c949bfafc1a3399aaeaabb4 100644 --- a/src/receiver_utils.c +++ b/src/receiver_utils.c @@ -48,8 +48,9 @@ int send_if_inneed(struct pollfd * pfd, receiver_state_t * state) return 0; } -int consume_data(receiver_state_t * state, uint8_t seqnum_to_consume) +int consume_data_pkt(receiver_state_t * state, uint8_t seqnum_to_consume) { + ASSERT(state->recvd_buf[seqnum_to_consume] != NULL); size_t written = fwrite((void *) pkt_get_payload(state->recvd_buf[seqnum_to_consume]), sizeof(char), (size_t) pkt_get_length(state->recvd_buf[seqnum_to_consume]), stdout); if (written != pkt_get_length(state->recvd_buf[seqnum_to_consume])) { @@ -61,12 +62,57 @@ int consume_data(receiver_state_t * state, uint8_t seqnum_to_consume) pkt_del(state->recvd_buf[seqnum_to_consume]); state->recvd_buf[seqnum_to_consume] = NULL; return 0; +} + +uint16_t next_four_packets_received(receiver_state_t * state, uint16_t position_to_start) +{ + /* + 256 is dividable by 4 if the the sender respects the constraint of sending a FEC each 4 packets then + we just have to check increasingly only. Hence why the loop consition checks if the next 4 packets are received + and doesn't check the circular condition. + */ + ASSERT(position_to_start < TWO_EXP_EIGHT); + if ( position_to_start > TWO_EXP_EIGHT - FEC_CALCULATED_ON) + return 0; + + for (uint16_t i = position_to_start; i < position_to_start + FEC_CALCULATED_ON; i++) + { + if (state->recvd_buf[i] == NULL) + return 0; + } + return 1; +} + +/** + * @brief Checks if we can consume data from the buffer. + * + * @param state: The current receiver state. + * @param latest_packet_received: The latest valid packet we received + * + * @return The number of packets to consume. + * @modifies: state. + */ +uint16_t can_consume(receiver_state_t * state, const pkt_t * latest_packet_received){ + // We have received the last 4 paquets harmless or we just received the last packet + int to_consume = 0; + ASSERT(state->next_to_consume >= 0 && state->next_to_consume < TWO_EXP_EIGHT); + if (pkt_get_length(latest_packet_received) == 0) + { // Last packet we read everything from the buffer + for (uint16_t i = state->next_to_consume; state->recvd_buf[i] != NULL; i = (i + 1) % TWO_EXP_EIGHT ) + to_consume++; + } else + { // We only read blocks of 4 packets. + uint16_t start_to_consume = state->next_to_consume; + for (; next_four_packets_received(state, start_to_consume % TWO_EXP_EIGHT); start_to_consume+=4) + to_consume+=4; + } + + return to_consume; } int update_buffer_upon_new_data(receiver_state_t * state, const pkt_t * pkt) { // Find free space - state->curr_recv_window = (state->curr_recv_window > 0) ? state->curr_recv_window-1 : 0; uint8_t seqnum = pkt_get_seqnum(pkt); // New packet @@ -80,6 +126,7 @@ int update_buffer_upon_new_data(receiver_state_t * state, const pkt_t * pkt) state->curr_recv_window = (state->curr_recv_window > 0) ? state->curr_recv_window-1 : 0; } + // Update last received in order if (seqnum == (state->last_received_in_order + 1) % TWO_EXP_EIGHT) { state->last_received_in_order = seqnum; @@ -87,27 +134,21 @@ int update_buffer_upon_new_data(receiver_state_t * state, const pkt_t * pkt) for (;state->recvd_buf[idx] != NULL; idx = (idx + 1) % TWO_EXP_EIGHT) state->last_received_in_order = idx; } - - - if (seqnum % 3 != 0 && pkt_get_length(pkt) != 0) + uint16_t to_consume = can_consume(state, pkt); + if (to_consume == 0) return 0; - for (uint16_t i = state->next_to_consume; i < state->next_to_consume + FEC_CALCULATED_ON && pkt_get_length(pkt) != 0; i++) - { - if (state->recvd_buf[i] == NULL) - return 0; - } - - // We only reach here when we received 4 last packets in sequence or it's the last paquet. - while (state->recvd_buf[state->next_to_consume] != NULL) + DEBUG("Going to consume the next %d packets.", to_consume); + while (to_consume > 0) { DEBUG("Consuming packet : %d | curr_recv_window = %d, recv_window_start = %d", state->next_to_consume, state->curr_recv_window, state->recv_window_start); - if (consume_data(state, state->next_to_consume) != 0) return -1; - state->curr_recv_window = (state->curr_recv_window < RECV_MAX_SLCTV_RPT_WDW) ? state->curr_recv_window+1 : RECV_MAX_SLCTV_RPT_WDW; + if (consume_data_pkt(state, state->next_to_consume) != 0) return -1; + state->curr_recv_window = (state->curr_recv_window < RECV_MAX_SLCTV_RPT_WDW) ? state->curr_recv_window + 1 : RECV_MAX_SLCTV_RPT_WDW; state->recv_window_start = (state->recv_window_start + 1) % TWO_EXP_EIGHT; state->next_to_consume = (state->next_to_consume + 1) % TWO_EXP_EIGHT; + to_consume--; } return 0; } @@ -270,8 +311,8 @@ int handle_valid_pkt(receiver_state_t * state, const pkt_t * pkt) if (!in_window) { - DEBUG("Received packet [%d] Out of window with %d | receive window start at : %d (included) till %d (excluded)", - seqnum, pkt_get_timestamp(pkt), state->recv_window_start, seqnum < (state->recv_window_start + RECV_MAX_SLCTV_RPT_WDW) % TWO_EXP_EIGHT); + DEBUG("Received packet [%d] Out of window with timestamp %d | receive window start at : %d (included) till %d (excluded)", + seqnum, pkt_get_timestamp(pkt), state->recv_window_start, (state->recv_window_start + RECV_MAX_SLCTV_RPT_WDW) % TWO_EXP_EIGHT); return prepare_ack_to_send(state); }