Skip to content
Extraits de code Groupes Projets
receiver_utils.c 3,44 Kio

#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);
}