Commit 00f430d8 authored by Andreas Schmidt's avatar Andreas Schmidt
Browse files

Multiplex packets by type and not socket.

* Single thread for reception of data and feedback.
parent 973501b7
Loading
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -94,7 +94,6 @@ cdef extern from "proto/receiver.h":
cdef extern from "proto/socket.h":
    cdef struct prrtSocket:
        int socketFd
        pthread_t receiveFeedbackThread

        pthread_t sendDataThread
        pthread_mutex_t outQueueFilledMutex
+0 −1
Original line number Diff line number Diff line
@@ -8,7 +8,6 @@ add_library(PRRT ../defines.h
        ../xlap/xlap.c ../xlap/xlap.h
        applicationConstraints.c applicationConstraints.h
        processes/dataReceiver.c processes/dataReceiver.h
        processes/feedbackReceiver.c processes/feedbackReceiver.h
        processes/dataTransmitter.c processes/dataTransmitter.h
        stores/dataPacketStore.c stores/dataPacketStore.h
        stores/deliveredPacketTable.c stores/deliveredPacketTable.h
+38 −6
Original line number Diff line number Diff line
@@ -203,6 +203,32 @@ static void handle_redundancy_packet(PrrtSocket *socket, PrrtPacket *packet) {
    return;
}

void handle_feedback_packet(const PrrtSocket *prrtSocket, const PrrtPacket *prrtPacket, prrtTimestamp_t receiveTime) {
    check(prrtPacket != NULL, "Cannot be null");
    debug(DEBUG_DATARECEIVER, "handle_feedback_packet");
    PrrtPacketFeedbackPayload *feedbackPayload = (PrrtPacketFeedbackPayload *) prrtPacket->payload;
    prrtTimestamp_t forwardTripTimestamp = feedbackPayload->forwardTripTimestamp_us;

    bool valid_sample = PrrtReceiver_updateAndGenerateRateSample(prrtSocket->receiver, feedbackPayload->ackSequenceNumber, feedbackPayload->ackPacketType, receiveTime);
    debug(DEBUG_DATARECEIVER, "PrrtReceiver_updateAndGenerateRateSample ");

    if(valid_sample) {
        PrrtChannelStateInformation_update_delivery_rate(prrtSocket->receiver->csi, prrtPacket, prrtSocket->receiver->rateSample);
    }
    PrrtChannelStateInformation_update_app_limited(prrtSocket->receiver->csi, prrtSocket->receiver->rateSample->is_app_limited);
    debug(DEBUG_DATARECEIVER, "PrrtChannelStateInformation_update_app_limited ");

    PrrtChannelStateInformation_update_rtprop(prrtSocket->receiver->csi,
                                              (prrtTimedelta_t) (receiveTime - forwardTripTimestamp));
    debug(DEBUG_DATARECEIVER, "PrrtChannelStateInformation_update_rtprop ");
    PrrtChannelStateInformation_update_plr(prrtSocket->receiver->csi, feedbackPayload->erasureCount, feedbackPayload->packetCount);
    debug(DEBUG_DATARECEIVER, "PrrtChannelStateInformation_update_plr ");
    return;

    error:
    PERROR("handle_feedback_packet failed.");
}

void receive_from_socket(PrrtSocket *socket_ptr, unsigned char buffer_ptr[65528], ssize_t *received_size,
                         struct sockaddr_in *remote_ptr, socklen_t *remote_len_ptr, struct timespec *packet_timestamp_ptr,
                         uint64_t *packet_cyclestamp_ptr) {
@@ -255,6 +281,7 @@ void *receive_data_loop(void *ptr) {
    PrrtSocket *sock_ptr = ptr;

    while (1) {
        debug(DEBUG_DATARECEIVER, "About to receive.");
        XlapTimestampPlaceholder tsph1;
        XlapTimestampPlaceholder tsph2;
        XlapTimestampPlaceholder tsph3;
@@ -267,20 +294,16 @@ void *receive_data_loop(void *ptr) {
        receive_from_socket(sock_ptr, buffer, &n, &remote, &addrlen, &packet_recv_timestamp, &packet_recv_cyclestamp);
        debug(DEBUG_HARDSTAMPING, "Packet TS:\t%ld.%09ld; Who? %s", (long) packet_recv_timestamp.tv_sec,
              packet_recv_timestamp.tv_nsec, inet_ntoa(remote.sin_addr));
        prrtTimestamp_t prrt_recv_timestamp = PrrtClock_TimespecToPrrtTimestamp(packet_recv_timestamp);
        sock_ptr->lastReceivedTimestamp = prrt_recv_timestamp;

        XlapTimeStampClock(&tsph1, ts_any_packet, 0, LinkReceive);
        XlapTimeStampCycle(&tsph1, ts_any_packet, 0, LinkReceive);

        PrrtPacket *packet = (PrrtPacket *) calloc(1, sizeof(PrrtPacket));
        check_mem(packet);

        XlapTimeStampCycle(&tsph2, ts_any_packet, 0, DecodeStart);
        check(PrrtPacket_decode(buffer, (uint16_t) n, packet), "Decode failed.");
        XlapTimeStampCycle(&tsph3, ts_any_packet, 0, DecodeEnd);

        prrtSequenceNumber_t seqno = packet->sequenceNumber;
        prrtTimestamp_t prrt_recv_timestamp = PrrtClock_TimespecToPrrtTimestamp(packet_recv_timestamp);

        prrtPacketType_t packetType = PrrtPacket_type(packet);
        debug(DEBUG_DATARECEIVER, "received packet %d:%u", (int) packetType, seqno);
@@ -293,8 +316,12 @@ void *receive_data_loop(void *ptr) {
        } else if (packetType == PACKET_TYPE_REDUNDANCY) {
            kind = ts_redundancy_packet;
            sentTimestamp = PrrtPacket_get_redundancy_timestamp(packet);
        } else if (packetType == PACKET_TYPE_FEEDBACK) {
            kind = ts_feedback_packet;
        }
        if (packetType == PACKET_TYPE_DATA || packetType == PACKET_TYPE_REDUNDANCY) {
            sock_ptr->lastReceivedTimestamp = prrt_recv_timestamp;

            XlapCycleStampValue(sock_ptr, kind, seqno, ChannelReceive, packet_recv_cyclestamp);
            XlapTimeStampValue(sock_ptr, kind, seqno, ChannelReceive, packet_recv_timestamp);

@@ -313,12 +340,17 @@ void *receive_data_loop(void *ptr) {
            }
            send_feedback(sock_ptr, remote, seqno, prrt_recv_timestamp, sentTimestamp, packetType);
            XlapTimeStampCycle(sock_ptr, kind, seqno, HandlePacketEnd);
        } else if (packetType == PACKET_TYPE_FEEDBACK) {
            handle_feedback_packet(sock_ptr, packet, prrt_recv_timestamp);
            PrrtPacket_destroy(packet);
        } else {
            PrrtPacket_print(packet);
            PrrtPacket_destroy(packet);
        }

        debug(DEBUG_DATARECEIVER, "Cleanup");
        PrrtSocket_cleanup(sock_ptr);
        debug(DEBUG_DATARECEIVER, "Cleaned");
    }

    error:
+1 −1
Original line number Diff line number Diff line
@@ -152,6 +152,7 @@ void *send_data_loop(void *ptr) {
        payload->groupRTprop_us = PrrtSocket_get_rtprop_fwd(sock_ptr);

        PrrtPacket *packetToSend = PrrtPacket_copy(packet);
        debug(DEBUG_DATATRANSMITTER, "Send: %i", packet->sequenceNumber);
        send_packet(sock_ptr, packetToSend);
        XlapTimeStampClock(sock_ptr, ts_data_packet, packet->sequenceNumber, PrrtTransmitEnd);
        XlapTimeStampCycle(sock_ptr, ts_data_packet, packet->sequenceNumber, PrrtTransmitEnd);
@@ -175,6 +176,5 @@ void *send_data_loop(void *ptr) {
            PrrtBlock_destroy(block);
            block = NULL;
        }
        PrrtSocket_cleanup(sock_ptr);
    }
}
+0 −71
Original line number Diff line number Diff line
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/poll.h>
#include "../../defines.h"
#include "../../util/common.h"
#include "../../util/dbg.h"
#include "../clock.h"
#include "../socket.h"
#include "feedbackReceiver.h"

static void handle_feedback(PrrtSocket *prrtSocket, const size_t length)
{
    char bufin[MAX_PAYLOAD_LENGTH];
    PrrtPacket *prrtPacket = NULL;
    ssize_t n;
    struct sockaddr_in remote;
    socklen_t addrlen = sizeof(remote);

    struct pollfd fds;
    int timeout_msecs = 1000;
    fds.fd = prrtSocket->socketFd;
    fds.events = POLLIN;

    n = poll(&fds, 1, timeout_msecs);
    check(n >= 0, "Select failed.");
    if(n == 0) {
        return;
    }
    prrtTimestamp_t receiveTime = PrrtClock_get_current_time_us();

    n = recvfrom(prrtSocket->socketFd, bufin, length, 0, (struct sockaddr *) &remote, &addrlen);
    check(n >= 0, "Receiving feedback failed.");

    prrtPacket = calloc(1, sizeof(PrrtPacket));
    check_mem(prrtPacket);
    PrrtPacket_decode(bufin, (uint16_t) n, prrtPacket);

    PrrtPacketFeedbackPayload *feedbackPayload = (PrrtPacketFeedbackPayload *) prrtPacket->payload;
    prrtTimestamp_t forwardTripTimestamp = feedbackPayload->forwardTripTimestamp_us;

    bool valid_sample = PrrtReceiver_updateAndGenerateRateSample(prrtSocket->receiver, feedbackPayload->ackSequenceNumber, feedbackPayload->ackPacketType, receiveTime);

    if(valid_sample) {
        PrrtChannelStateInformation_update_delivery_rate(prrtSocket->receiver->csi, prrtPacket, prrtSocket->receiver->rateSample);
    }
    PrrtChannelStateInformation_update_app_limited(prrtSocket->receiver->csi, prrtSocket->receiver->rateSample->is_app_limited);

    PrrtChannelStateInformation_update_rtprop(prrtSocket->receiver->csi,
                                              (prrtTimedelta_t) (receiveTime - forwardTripTimestamp));
    PrrtChannelStateInformation_update_plr(prrtSocket->receiver->csi, feedbackPayload->erasureCount, feedbackPayload->packetCount);

    error:
    if(prrtPacket != NULL) { PrrtPacket_destroy(prrtPacket); }
}

void *receive_feedback_loop(void *ptr)
{
    PrrtSocket *sock_ptr = ptr;

    while (!atomic_load_explicit(&sock_ptr->closing, memory_order_acquire)) {
        handle_feedback(sock_ptr, MAX_PAYLOAD_LENGTH);
    }

    return NULL;

//    error:
//    PERROR("Feedback reception failed.%s","");
//    return NULL;
}
Loading