Skip to content
Extraits de code Groupes Projets
Valider d8c4b406 rédigé par Vany Ingenzi's avatar Vany Ingenzi
Parcourir les fichiers

Started working on FEC

parent 821a4b9c
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Fichier ajouté
Fichier ajouté
......@@ -42,7 +42,6 @@ int send_if_inneed(struct pollfd * pfd, receiver_state_t * state)
return -1;
}
DEBUG("Sent ACK saying we are waiting for %d, timestamp %d", pkt_get_seqnum(state->ack_to_send), pkt_get_timestamp(state->ack_to_send));
DEBUG_DUMP(buffer, len);
pkt_del(state->ack_to_send);
state->ack_to_send = NULL;
}
......@@ -68,8 +67,8 @@ 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
if (state->recvd_buf[seqnum] == NULL)
{
......@@ -78,30 +77,37 @@ int update_buffer_upon_new_data(receiver_state_t * state, const pkt_t * pkt)
return -1;
memcpy((void *) pkt_to_store, (void *) pkt, sizeof(pkt_t));
state->recvd_buf[seqnum] = pkt_to_store;
state->curr_recv_window = (state->curr_recv_window > 0) ? state->curr_recv_window-1 : 0;
}
if (seqnum == (state->last_received_in_order + 1) % TWO_EXP_EIGHT)
{
state->last_received_in_order = seqnum;
} else
{
DEBUG("Out of sequence");
return 0;
uint16_t idx = seqnum;
for (;state->recvd_buf[idx] != NULL; idx = (idx + 1) % TWO_EXP_EIGHT)
state->last_received_in_order = idx;
}
// We only reach here when we received packets in sequence.
uint16_t next_wait = state->last_received_in_order;
while (state->recvd_buf[next_wait] != NULL)
if (seqnum % 3 != 0 && pkt_get_length(pkt) != 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("Consuming packet : %d | curr_recv_window = %d, recv_window_start = %d",
next_wait, state->curr_recv_window, state->recv_window_start);
state->next_to_consume, state->curr_recv_window, state->recv_window_start);
if (consume_data(state, next_wait) != 0) return -1;
state->last_received_in_order = next_wait;
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;
state->recv_window_start = (state->recv_window_start + 1) % TWO_EXP_EIGHT;
next_wait = (next_wait + 1) % TWO_EXP_EIGHT;
state->next_to_consume = (state->next_to_consume + 1) % TWO_EXP_EIGHT;
}
return 0;
}
......@@ -152,7 +158,22 @@ int prepare_ack_to_send(receiver_state_t * state)
}
/**
* @brief This function handles PTYPE_DATA arriving packets amd updates the state.
* @brief This function handles PTYPE_FEC arriving packets and updates the state.
*
* @param state: The receiver state.
* @param pkt: The DATA packet.
* @returns 0 upon success else -1.
*
* @modifies: state.
*/
int handle_fec_pkt(receiver_state_t * state, const pkt_t * pkt)
{
ASSERT(state != NULL && pkt != NULL);
return 0;
}
/**
* @brief This function handles PTYPE_DATA arriving packets and updates the state.
*
* @param state: The receiver state
* @param pkt: The DATA packet
......@@ -200,6 +221,8 @@ int handle_data_pkt(receiver_state_t * state, const pkt_t * pkt)
*/
int handle_truncated_pkt(receiver_state_t * state, const pkt_t * pkt)
{
if (pkt_get_type(pkt) != PTYPE_DATA) return 0;
int free_idx = 0;
for (; free_idx < RECV_MAX_SLCTV_RPT_WDW && state->nack_to_send[free_idx] != NULL; free_idx++);
......@@ -253,10 +276,16 @@ int handle_valid_pkt(receiver_state_t * state, const pkt_t * pkt)
}
uint8_t tr = pkt_get_tr(pkt);
if (tr == 1) /* If truncated */
if (tr == 1)
{ /* If truncated */
return handle_truncated_pkt(state, pkt);
else /* If not truncated */
} else if (pkt_get_type(pkt) == PTYPE_DATA)
{ /* Not */
return handle_data_pkt(state, pkt);
} else if (pkt_get_type(pkt) == PTYPE_FEC)
{
return handle_fec_pkt(state, pkt);
}
return 0;
}
......@@ -266,7 +295,7 @@ int handle_valid_pkt(receiver_state_t * state, const pkt_t * pkt)
*
* @warning Modifiers state
*
* @param pfd: The struct pollfd sur lequel cherche le fd et lire.
* @param pfd: The struct pollfd sur lequel cherche le fd et lire.
* @returns 0 upon success and -1 in cas of failure.
*/
int handle_incoming(struct pollfd * pfd, receiver_state_t * state)
......@@ -287,13 +316,13 @@ int handle_incoming(struct pollfd * pfd, receiver_state_t * state)
{
DEBUG("Received packet seqnum %d with timestamp %d | current_window_size : %d, current_window_start : %d",
pkt_get_seqnum(pkt), pkt_get_timestamp(pkt), state->curr_recv_window, state->recv_window_start);
if (handle_valid_pkt(state, (const pkt_t *) pkt) != 0) return -1;
} else
} else
{
/* If the packet has been damaged we can discuss if it's better to send a ACK
or not but for now we just ignore it */
DEBUG("Received a damaged packet with %d status.", pkt_status);
pkt_del(pkt);
return prepare_ack_to_send(state);
}
pkt_del(pkt);
......@@ -353,28 +382,29 @@ void reception_loop(struct pollfd * pfd, receiver_state_t * state)
*/
receiver_state_t * state_new()
{
receiver_state_t * toReturn = (receiver_state_t *) calloc(1, sizeof(receiver_state_t));
if (toReturn == NULL) return NULL;
receiver_state_t * to_return = (receiver_state_t *) calloc(1, sizeof(receiver_state_t));
if (to_return == NULL) return NULL;
for (size_t i = 0; i < TWO_EXP_EIGHT; i++)
toReturn->recvd_buf[i] = NULL;
to_return->recvd_buf[i] = NULL;
for (size_t i = 0; i < RECV_MAX_SLCTV_RPT_WDW; i++)
toReturn->nack_to_send[i] = NULL;
to_return->nack_to_send[i] = NULL;
toReturn->curr_recv_window = RECV_MAX_SLCTV_RPT_WDW;
toReturn->recv_window_start = 0;
toReturn->last_received_in_order = -1; // Sign indicating that it hasn't received something
toReturn->ack_to_send = NULL; // Sign that there's no ack to send
toReturn->transfer_done = 0;
toReturn->last_packet = 256; // No validseqnum will reach this value, max value 255
toReturn->last_data_packet = 256;
return toReturn;
to_return->curr_recv_window = RECV_MAX_SLCTV_RPT_WDW;
to_return->recv_window_start = 0;
to_return->last_received_in_order = -1; // Sign indicating that it hasn't received something
to_return->ack_to_send = NULL; // Sign that there's no ack to send
to_return->transfer_done = 0;
to_return->next_to_consume = 0;
to_return->last_packet = 256; // No valid seqnum will reach this value, max value 255
to_return->last_data_packet = 256;
return to_return;
}
/**
* @brief This function frees the memory allocated by the state_new() function.
* @state: The structure to free.
* @param state: The structure to free.
*/
void state_del(receiver_state_t * state)
{
......
......@@ -31,6 +31,7 @@
#define TIMER_MULTIPLIER_BY_1 1
#define TIMER_MULTIPLIER_BY_2 2
#define RECEIVER_INACTIVE_TIMEOUT 20
#define FEC_CALCULATED_ON 4
/* Represent the receiver's connection state */
......@@ -46,12 +47,13 @@ typedef struct __attribute__((__packed__))
uint8_t transfer_done;
uint16_t last_packet;
uint16_t last_data_packet;
uint16_t next_to_consume;
} receiver_state_t;
/**
* Loop reading on socket and printing to the stdout
* @sfd : The socket file descriptor. It is both bound and connected.
* @param sfd : The socket file descriptor. It is both bound and connected.
* @return: as soon as the whole transfer is done.
*/
void receiver_read_write_loop(int sfd);
......@@ -66,7 +68,7 @@ receiver_state_t * state_new();
/**
* Deletes the receiver_state_t structure pointed by the
* state argument.
* @state: the state to delete.
* @param state: the state to delete.
* @return: /
*/
void state_del(receiver_state_t * state);
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter