diff --git a/headers/receiver_utils.h b/headers/receiver_utils.h index a5cc853683ab862eb9f2bbb7bdf21e4f092ea5fc..572e45a56d126586e1b7d0858a2d9d6410708ff3 100644 --- a/headers/receiver_utils.h +++ b/headers/receiver_utils.h @@ -7,4 +7,20 @@ #ifndef __RECEIVER_UTILS_ #define __RECEIVER_UTILS_ +/* We are using 8 bits to encode the seqnum therefore to fight redondance our window is of 2**(8)/2 */ +#define MAX_SELECTIVE_REPEAT_WINDOW 8 + +/* Represent the receiver's connection state */ +typedef struct __attribute__((__packed__)) +{ +} con_state_t; + + +/** + * Loop reading on socket and printing to the stdout + * @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); + #endif \ No newline at end of file diff --git a/src/our_utils.c b/src/our_utils.c index b81e2f8a853715277c47d790a73f20966f89d992..45e6305f02f4d03ec2d029378178fc70250d0dce 100644 --- a/src/our_utils.c +++ b/src/our_utils.c @@ -78,7 +78,7 @@ int create_socket_connect(struct sockaddr_in6 * dest_addr) int create_socket(struct sockaddr_in6 *source_addr, int src_port, struct sockaddr_in6 *dest_addr, int dst_port) { - if ( source_addr != NULL && dest_addr == NULL ) + if ( source_addr != NULL && dest_addr == NULL ) { source_addr->sin6_port = htons(src_port); return create_socket_bind(source_addr); diff --git a/src/receiver.c b/src/receiver.c index dbb84be46d34d61438c34c420085d9b0e02385fb..9afa9775c19c30501c8e0ad4911c8c7b5c27e1b1 100644 --- a/src/receiver.c +++ b/src/receiver.c @@ -13,7 +13,7 @@ #include "log.h" #include "packet_interface.h" #include "our_utils.h" - +#include "receiver_utils.h" int print_usage(char *prog_name) { ERROR("Usage:\n\t%s [-s stats_filename] listen_ip listen_port", prog_name); @@ -73,20 +73,11 @@ int main(int argc, char **argv) { ERROR("An error occured when creating the socket\n"); return (EXIT_FAILURE); } - // 2. Wait for a client - char * buff[PKT_MAX_LEN]; - ssize_t len; - int err = wait_for_client(socket, PKT_MAX_LEN,(char *)buff, &len); - if (err == 0) - { - close(socket); - return (EXIT_FAILURE); - } - - DEBUG_DUMP(buff, len); - // 3. Start listening till end + ASSERT(stats_filename == NULL); + receiver_read_write_loop(socket); close(socket); + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/receiver_utils.c b/src/receiver_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..9722c5553688598aa98af498046b537a024626fc --- /dev/null +++ b/src/receiver_utils.c @@ -0,0 +1,128 @@ + +#include "log.h" +#include "packet_interface.h" +#include <poll.h> +#include "our_utils.h" +#include "receiver_utils.h" + +int send_data_if_inneed() +{ + return 1; +} + +int handle_incoming_data() +{ + /* + char * buff; + ssize_t read_bytes = read(pfd->fd, (void *) buff, MAX_SIZE); + if (read_bytes == -1) + return 0; + err = fwrite((void *) buff, sizeof(char), read_bytes, stdout); + if (err == 0) + return 0; + err = fflush(stdout); + */ + return 1; +} + +int handle_revents(struct pollfd * pfd) +{ + DEBUG(" events: %s%s%s%s", + (pfd->revents & POLLIN) ? "POLLIN " : "", + (pfd->revents & POLLOUT) ? "POLLOUT " : "", + (pfd->revents & POLLHUP) ? "POLLHUP " : "", + (pfd->revents & POLLERR) ? "POLLERR " : ""); + + if (pfd->revents & POLLIN) /* POLLIN : There's data to read */ + { + return handle_incoming_data(); + } else if (pfd->revents & POLLHUP) /* POLLHUP : The other user disconnected from their side */ + { + DEBUG("The sender disconnected."); + return 0; + } else if (pfd->revents & POLLOUT) /* POLLOUT : Possible to send that */ + { + return send_data_if_inneed(); + } else { /* POLLERR : An error occurred */ + ERROR("Poll revents marks error."); + return 0; + } + return 1; +} + +void reception_loop(struct pollfd * pfd, con_state_t * state, pkt_t * pkt) +{ + ASSERT(state != NULL || pkt != NULL); + int not_eof = 1; + while (not_eof) + { + int ready = poll(pfd, 1, -1); + if (ready == -1) + return; + + if (pfd->revents != 0) + not_eof = handle_revents(pfd); + } +} + +/** + * Waits for a client to send data to the socket and then connectes to the client + * @return: 0 upon success, -1 in case of an error. a message will be displayed to the stderr + */ +int connect_to_a_client(int sfd, pkt_t * init_pkt) +{ + char * buffer[PKT_MAX_LEN]; + ssize_t written_in_buffer; + // We suppose that the first contact is going to be our client no need to check for more + int err = wait_for_client(sfd, PKT_MAX_LEN, (char *)buffer, &written_in_buffer); + if (err != 0) return -1; + + DEBUG_DUMP(buffer, written_in_buffer); + pkt_status_code status = pkt_decode((char *) buffer, (size_t) written_in_buffer, init_pkt); + if (status != PKT_OK) + { + ERROR("When encoding the init_packet got pkt_status = %d", status); + return -1; + } + return 0; +} + +/** + * This main loop for the receiver. + * @sfd: A valid socket. + * @return: As soon as an error occurs or, a the total transfer came through. + */ +void receiver_read_write_loop(int sfd) +{ + pkt_t * pkt = pkt_new(); + con_state_t * state = malloc(sizeof(con_state_t)); + struct pollfd * pfd = (struct pollfd *) calloc(1, sizeof(struct pollfd)); + if (pkt == NULL || state == NULL || pfd == NULL) return; + + pfd->fd = sfd; + pfd->events = POLLIN | POLLOUT; + + int err = connect_to_a_client(sfd, pkt); + if (err == 0) + return; + // Handle initial packet. + + err = fwrite((void *) pkt_get_payload(pkt), sizeof(char), pkt_get_length(pkt), stdout); + err = fflush(stdout); + + /* + if (err == 0) + reception_loop(pfd, state, pkt); + */ + + char * buffer[PKT_MAX_LEN]; + size_t len = PKT_MAX_LEN; + + err = pkt_encode(pkt, (char *) buffer, &len); + if (err == 0) + err = write(pfd->fd, (void *) buffer, len); + + pkt_del(pkt); + free(state); + free(pfd); +} \ No newline at end of file