Skip to content
Extraits de code Groupes Projets
Valider a88165d8 rédigé par Samuel de Meester de Ravestein's avatar Samuel de Meester de Ravestein
Parcourir les fichiers

some progress

parent 982e39d6
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -9,6 +9,7 @@
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>
......@@ -18,14 +19,17 @@
#define SEQNUM_RANGE 256
#define TIMER_LIMIT 2
#define TIMER_LIMIT 2000 // we're in micro seconds
#define WINDOW_SIZE 31
/** When buffer field are not used they MUST be set to NULL */
typedef struct state {
uint8_t r_window_size; // reception buffer space
uint8_t s_window_size; // sender (our) buffer space
time_t timers[WINDOW_SIZE];
pkt_t buffer[WINDOW_SIZE];
suseconds_t timers[WINDOW_SIZE]; // Time in MICRO seconds
pkt_t *buffer[WINDOW_SIZE];
uint8_t head; // place last element insert +1 in the buffer (free place)
uint8_t tail; // place oldest element insert in the buffer
uint8_t last_ack_seqnum;
uint8_t last_sent_seqnum;
} sender_state_t;
......@@ -34,7 +38,9 @@ sender_state_t *state_new();
void state_del(sender_state_t *state);
int can_send(sender_state_t *state);
int handle_returning_ack_nack(sender_state_t *state, int socket_fd);
int loop_over_timers(sender_state_t *state, int socket_fd);
int read_and_send();
......
......@@ -114,8 +114,8 @@ int main(int argc, char **argv) {
int ack_received_done = false;
while (!(sending_file_read_done && ack_received_done))
{
// Blocking calling system
int rvalue = poll(pfd, 1, -1); // -1 means that there are no limit time out
// Blocking system call
int rvalue = poll(pfd, 1, -1); // -1 means that there are no setted time out
if (rvalue == -1)
{
close(socket_fd);
......@@ -124,82 +124,31 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
if ( !(sending_file_read_done) && (pfd->revents & POLLOUT) )
if (pfd->revents & POLLIN)
{
sending_file_read_done = read_and_send(state, sending_fd, socket_fd);
if (sending_file_read_done == -1)
ack_received_done = handle_returning_ack_nack(state, socket_fd);
rvalue = loop_over_timers(state, socket_fd);
if ((ack_received_done == -1) || (rvalue == -1))
{
close(socket_fd);
close(sending_fd);
ERROR("poll function failed\n");
ERROR("handle_returning_pkt or loop_over_timers function failed\n");
return EXIT_FAILURE;
}
}
else if (pfd->revents & POLLIN)
else if ( !(sending_file_read_done) && (pfd->revents & POLLOUT) )
{
ack_received_done = handle_returning_pkt();
if (ack_received_done == -1)
sending_file_read_done = read_and_send(state, sending_fd, socket_fd);
if (sending_file_read_done == -1)
{
close(socket_fd);
close(sending_fd);
ERROR("poll function failed\n");
ERROR("read_and_send function failed\n");
return EXIT_FAILURE;
}
}
}
}
// pkt_t buffer[MAX_WINDOW_SIZE];
// int buffer_space = MAX_WINDOW_SIZE;
// int seqnum = 0;
// pkt_t *pkt = pkt_new();
// ssize_t nbr_byte_read = read(fd, pkt->payload, MAX_PAYLOAD_SIZE);
// while (nbr_byte_read > 0)
// {
// // *** Step: Prepare the packet to be send ***
// pkt_set_type(pkt, PTYPE_DATA);
// pkt_set_tr(pkt, 0);
// pkt_set_window(pkt, buffer_space);
// pkt_set_length(pkt, nbr_byte_read);
// pkt_set_seqnum(pkt, (seqnum++) % MAX_SEQNUM_SIZE);
// pkt_set_timestamp(pkt, 0); // We're free to use as we want
// // We set the TR to 0 in order to calculcate the CRC on the header
// char modified_header[8];
// memcpy((void *) &modified_header, (void *) &pkt->header, 8);
// modified_header[0] = modified_header[0] & TR_SETTER_TO_ZERO;
// uint32_t crc1 = htonl(calculate_crc(modified_header, 8));
// pkt_set_crc1(pkt, crc1);
// uint32_t crc2 = htonl(calculate_crc((char *) pkt->payload, (uint32_t) pkt_get_length(pkt)));
// pkt_set_crc2(pkt, crc2);
// char paquet_to_be_sent[PKT_MAX_LEN];
// size_t len = PKT_MAX_LEN;
// if (pkt_encode(pkt, paquet_to_be_sent, &len) != PKT_OK)
// {
// close(fd);
// close(socket_fd);
// ERROR("An error occured when trying to encode a paquet\n");
// return EXIT_FAILURE;
// }
// ssize_t sent = send(socket_fd, paquet_to_be_sent, len, 0);
// if (sent == -1)
// {
// close(fd);
// close(socket_fd);
// ERROR("An error occured when trying to send a paquet\n");
// return EXIT_FAILURE;
// }
// pkt_del(pkt);
// pkt = pkt_new();
// nbr_byte_read = read(fd, pkt->payload, MAX_PAYLOAD_SIZE);
// }
// pkt_del(pkt);
state_del(state);
close(sending_fd);
close(socket_fd);
......
......@@ -11,7 +11,12 @@ sender_state_t *state_new()
state->r_window_size = 1; // defined in the report
state->s_window_size = WINDOW_SIZE;
state->head = 0;
state->tail = 0;
for (uint8_t i = 0; i < WINDOW_SIZE; i++)
{
state->buffer[i] = NULL;
}
return state;
}
......@@ -20,17 +25,56 @@ void state_del(sender_state_t *state)
free(state);
}
int can_send(sender_state_t *state)
int handle_returning_ack_nack(sender_state_t *state, int socket_fd)
{
if ((state->r_window_size == 0) || (state->s_window_size == 0)) return 0;
return 1;
char buffer[ACK_OR_NACK_HEADER_SIZE]; // Only 10 bytes
size_t read_bytes = read(socket_fd, buffer, ACK_OR_NACK_HEADER_SIZE);
if (read_bytes == (size_t) -1) return -1;
pkt_t *pkt = pkt_new();
pkt_status_code pkt_status = pkt_decode(buffer, read_bytes, pkt);
if (pkt_status != PKT_OK)
{
DEBUG("Decode function on a received pkt failed with status: %d", pkt_status);
return -1;
}
pkt_del(pkt);
return 0;
}
int loop_over_timers(sender_state_t *state, int socket_fd)
{
struct timeval time;
gettimeofday(&time, NULL);
suseconds_t curr_time = time.tv_usec;
for (uint8_t i = 0; i < WINDOW_SIZE; i++)
{
// The slot contains a sended packet
if (state->buffer[i] != NULL)
{
// When timer is over, we send back the packet
if ((curr_time - state->timers[i]) >= TIMER_LIMIT)
{
DEBUG("A packet is sent back");
pkt_t *pkt = state->buffer[i];
char packet_to_be_sent[PKT_MAX_LEN];
size_t len = PKT_MAX_LEN;
if (pkt_encode(pkt, packet_to_be_sent, &len) != PKT_OK) return -1;
ssize_t sent = send(socket_fd, packet_to_be_sent, len, 0);
if (sent == -1) return -1;
state->timers[i] = curr_time;
}
}
}
return 0;
}
int read_and_send(sender_state_t *state, int sending_fd, int socket_fd)
{
if (!can_send(state)) return 0;
if ((state->r_window_size == 0) || (state->s_window_size == 0)) return 0;
state->s_window_size--;
state->last_sent_seqnum = (uint8_t) (((uint16_t) state->last_sent_seqnum) + 1) % SEQNUM_RANGE; // Careful we need to convert to uint16_t to avoid overflow
......@@ -54,18 +98,24 @@ int read_and_send(sender_state_t *state, int sending_fd, int socket_fd)
uint32_t crc2 = htonl(calculate_crc((char *) pkt->payload, (uint32_t) pkt_get_length(pkt)));
pkt_set_crc2(pkt, crc2);
char paquet_to_be_sent[PKT_MAX_LEN];
char packet_to_be_sent[PKT_MAX_LEN];
size_t len = PKT_MAX_LEN;
if (pkt_encode(pkt, paquet_to_be_sent, &len) != PKT_OK) return -1;
if (pkt_encode(pkt, packet_to_be_sent, &len) != PKT_OK) return -1;
ssize_t sent = send(socket_fd, paquet_to_be_sent, len, 0);
ssize_t sent = send(socket_fd, packet_to_be_sent, len, 0);
if (sent == -1) return -1;
pkt_del(pkt);
// Insert the packet in the buffer
state->buffer[state->head] = pkt;
struct timeval time;
gettimeofday(&time, NULL);
state->timers[state->head] = time.tv_usec;
state->head = (state->head + 1) % WINDOW_SIZE;
// Checking if we're at the end of the file
off_t old_position = lseek(sending_fd, 0, SEEK_CUR);
off_t end_position = lseek(sending_fd, 0, SEEK_END);
// put back the cursor
// put back the reader cursor
lseek(sending_fd, 0, SEEK_SET);
return old_position == end_position;
}
......
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