packet.c 19.7 KB
Newer Older
1 2 3
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
4
#include <netinet/in.h>
5
#include <stdbool.h>
6 7 8
#include "../../util/common.h"
#include "../../util/dbg.h"
#include "../clock.h"
Andreas Schmidt's avatar
Andreas Schmidt committed
9
#include "packet.h"
10

11
static void *encode_general_header(void *buf_ptr, const PrrtPacket *packet);
12

13
static void *encode_data_header(void *buf_ptr, const void *payload);
14

15
static void *encode_redundancy_header(void *buf_ptr, const void *payload);
16

17
static void *encode_feedback_header(void *buf_ptr, const void *payload);
18

19
static void *decode_data_header(void *dstBuffer, const void *srcBuffer);
Andreas Schmidt's avatar
Andreas Schmidt committed
20

21
static void *decode_redundancy_header(void *dstBuffer, const void *srcBuffer);
22

23
static void *decode_feedback_header(void *dstBuffer, const void *srcBuffer);
Andreas Schmidt's avatar
Andreas Schmidt committed
24

25
prrtPacketType_t PrrtPacket_type(PrrtPacket *packet_ptr) {
26
    return (prrtPacketType_t) ((packet_ptr->type_priority >> 4) & 0x0F);
27 28
}

29
uint8_t PrrtPacket_priority(PrrtPacket *packet_ptr) {
30 31 32
    return (uint8_t) (packet_ptr->type_priority & 0x0F);
}

33
prrtPacketLength_t PrrtPacket_size(PrrtPacket *packet_ptr) {
34
    return (prrtPacketLength_t) (packet_ptr->payloadLength + PRRT_PACKET_GENERAL_HEADER_SIZE);
35 36
}

37
int PrrtPacket_print(PrrtPacket *packet_ptr) {
38 39
    printf(" 0                   1                   2                   3\n"
                   " 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n"
40
                   "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
41
    prrtPacketType_t type = PrrtPacket_type(packet_ptr);
42

43
    printf("| %5u | %5u | %13u | %29u |\n", type, PrrtPacket_priority(packet_ptr), packet_ptr->index,
44
           packet_ptr->sequenceNumber);
45
    printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
46

47
    if (type == PACKET_TYPE_DATA) {
48
        PrrtPacketDataPayload *payload = packet_ptr->payload;
49 50
        printf("| %61u |\n", payload->timestamp);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
51
        printf("| %61u |\n", payload->groupRTprop_us);
52
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
53 54
        printf("| %61u |\n", payload->packetTimeout_us);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
55 56
        printf("| %61s |\n", (char *) (packet_ptr->payload + PRRT_PACKET_DATA_HEADER_SIZE));
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
57
    } else if (type == PACKET_TYPE_REDUNDANCY) {
58
        PrrtPacketRedundancyPayload *payload = packet_ptr->payload;
59
        printf("| %29u | %13u | %13u |\n", payload->baseSequenceNumber, payload->n, payload->k);
60
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
61
    } else if (type == PACKET_TYPE_FEEDBACK) {
62 63
        prrtPacketLength_t i = 0;

64
        PrrtPacketFeedbackPayload *payload = packet_ptr->payload;
65

66
        printf("| %61u |\n", payload->groupRTT_us);
67
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
68
        printf("| %61u |\n", payload->forwardTripTimestamp_us);
69
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
70
        printf("| %29u | %29u |\n", payload->erasureCount, payload->packetCount);
71
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
72
        printf("| %29u | %29u |\n", payload->gapLength, payload->gapCount);
73
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
74
        printf("| %29u | %29u |\n", payload->burstLength, payload->burstCount);
75
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
76 77 78 79 80

        prrtPacketLength_t remainingSpace = ((prrtPacketLength_t) (packet_ptr->payloadLength -
                                                                   PRRT_PACKET_FEEDBACK_HEADER_SIZE));
        prrtPacketLength_t blockCount = (prrtPacketLength_t) (remainingSpace / sizeof(PrrtIncompleteBlock));

81
        for (i = 0; i < blockCount; ++i) {
82 83 84 85
            PrrtIncompleteBlock block = payload->incompleteBlocks[i];
            printf("| %29u | %29u |\n", block.sequenceNumberBase, block.repairCycleIndex);
            printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
        }
86
    } else {
87 88
        printf("| Unhandeled Type                                               |\n");
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
89 90 91 92 93
    }

    return 0;
}

94
PrrtPacket *PrrtPacket_copy(PrrtPacket *original) {
95 96
    PrrtPacket *newPacket = calloc(1, sizeof(PrrtPacket));
    check_mem(newPacket);
97
    void *payload = calloc(1, original->payloadLength);
98 99 100
    check_mem(payload);

    newPacket->payload = payload;
101 102
    newPacket->payloadLength = original->payloadLength;
    memcpy(newPacket->payload, original->payload, original->payloadLength);
103 104

    newPacket->index = original->index;
105
    newPacket->sequenceNumber = original->sequenceNumber;
106 107 108 109 110
    newPacket->type_priority = original->type_priority;


    return newPacket;
    error:
111
    PERROR("Not enough memory for packet copies.%s", "");
Andreas Schmidt's avatar
Andreas Schmidt committed
112
    return NULL;
113 114
}

115 116
static PrrtPacket *
create_header(uint8_t priority, prrtSequenceNumber_t seqno, prrtPacketLength_t size, uint8_t type, uint8_t index) {
Andreas Schmidt's avatar
Andreas Schmidt committed
117 118 119 120 121 122
    PrrtPacket *packet = calloc(1, sizeof(PrrtPacket));
    check_mem(packet);

    packet->type_priority = type << 4;
    packet->type_priority |= priority & 0x0F;
    packet->index = index;
123 124
    packet->sequenceNumber = seqno;
    packet->payloadLength = size;
Andreas Schmidt's avatar
Andreas Schmidt committed
125 126 127 128 129

    return packet;

    error:
    PERROR("Could not create packet.%s", "");
Andreas Schmidt's avatar
Andreas Schmidt committed
130
    return NULL;
Andreas Schmidt's avatar
Andreas Schmidt committed
131 132
}

133
bool PrrtPacket_encode(void *buf_ptr, uint16_t buf_size, PrrtPacket *packet_ptr) {
134
    void *payload = packet_ptr->payload;
135

136
    check(packet_ptr->payloadLength + PRRT_PACKET_GENERAL_HEADER_SIZE <= buf_size, "Buffer too small.");
137

138 139
    buf_ptr = encode_general_header(buf_ptr, packet_ptr);

140
    prrtPacketType_t type = PrrtPacket_type(packet_ptr);
141
    if (type == PACKET_TYPE_DATA) {
142
        buf_ptr = encode_data_header(buf_ptr, payload);
143
        PrrtPacket_copy_payload_to_buffer(buf_ptr, packet_ptr, PRRT_PACKET_DATA_HEADER_SIZE);
144
    } else if (type == PACKET_TYPE_REDUNDANCY) {
145
        buf_ptr = encode_redundancy_header(buf_ptr, payload);
146
        PrrtPacket_copy_payload_to_buffer(buf_ptr, packet_ptr, PRRT_PACKET_REDUNDANCY_HEADER_SIZE);
147
    } else if (type == PACKET_TYPE_FEEDBACK) {
148
        encode_feedback_header(buf_ptr, payload);
149 150
    } else {
        perror("NOT IMPLEMENTED");
151
        return false;
152
    }
153
    return true;
154 155

    error:
156
    return false;
157 158
}

159
void *encode_redundancy_header(void *buf_ptr, const void *payload) {
160
    const PrrtPacketRedundancyPayload *redundancyPayload = payload;
161

162 163 164
    prrtSequenceNumber_t *baseSeqNo = (prrtSequenceNumber_t *) buf_ptr;
    *baseSeqNo = htons(redundancyPayload->baseSequenceNumber);
    buf_ptr += sizeof(prrtSequenceNumber_t);
165

166 167 168 169
    prrtTimestamp_t *timestamp = (prrtTimestamp_t *) buf_ptr;
    *timestamp = htonl(redundancyPayload->timestamp);
    buf_ptr += sizeof(prrtTimestamp_t);

170 171
    uint8_t *n = (uint8_t *) buf_ptr;
    *n = redundancyPayload->n;
172
    buf_ptr += sizeof(uint8_t);
173 174 175

    uint8_t *k = (uint8_t *) buf_ptr;
    *k = redundancyPayload->k;
176
    buf_ptr += sizeof(uint8_t);
177 178 179 180

    return buf_ptr;
}

181
void *encode_feedback_header(void *buf_ptr, const void *payload) {
182
    const PrrtPacketFeedbackPayload *feedbackPayload = payload;
183

184 185 186
    prrtTimedelta_t *groupRoundTripTime = (prrtTimedelta_t *) buf_ptr;
    *groupRoundTripTime = htonl(feedbackPayload->groupRTT_us);
    buf_ptr += sizeof(prrtTimedelta_t);
187

188 189 190
    prrtTimestamp_t *forwardTripTimestamp = (prrtTimestamp_t *) buf_ptr;
    *forwardTripTimestamp = htonl(feedbackPayload->forwardTripTimestamp_us);
    buf_ptr += sizeof(prrtTimestamp_t);
191

192 193 194
    prrtSequenceNumber_t *erasureCount = (prrtSequenceNumber_t *) buf_ptr;
    *erasureCount = htons(feedbackPayload->erasureCount);
    buf_ptr += sizeof(prrtSequenceNumber_t);
195

196 197 198
    prrtSequenceNumber_t *packetCount = (prrtSequenceNumber_t *) buf_ptr;
    *packetCount = htons(feedbackPayload->packetCount);
    buf_ptr += sizeof(prrtSequenceNumber_t);
199

200 201 202
    prrtSequenceNumber_t *gap = (prrtSequenceNumber_t *) buf_ptr;
    *gap = htons(feedbackPayload->gapLength);
    buf_ptr += sizeof(prrtSequenceNumber_t);
203

204 205 206
    prrtSequenceNumber_t *ngap = (prrtSequenceNumber_t *) buf_ptr;
    *ngap = htons(feedbackPayload->gapCount);
    buf_ptr += sizeof(prrtSequenceNumber_t);
207

208 209 210
    prrtSequenceNumber_t *burstLength = (prrtSequenceNumber_t *) buf_ptr;
    *burstLength = htons(feedbackPayload->burstLength);
    buf_ptr += sizeof(prrtSequenceNumber_t);
211

212 213 214
    prrtSequenceNumber_t *burstCount = (prrtSequenceNumber_t *) buf_ptr;
    *burstCount = htons(feedbackPayload->burstCount);
    buf_ptr += sizeof(prrtSequenceNumber_t);
215

216 217 218 219 220 221 222 223
    prrtPacketType_t *ackPacketType = (prrtPacketType_t *) buf_ptr;
    *ackPacketType = feedbackPayload->ackPacketType;
    buf_ptr += sizeof(prrtPacketType_t);

    prrtSequenceNumber_t *ackSequenceNumber = (prrtSequenceNumber_t *) buf_ptr;
    *ackSequenceNumber = htons(feedbackPayload->ackSequenceNumber);
    buf_ptr += sizeof(prrtSequenceNumber_t);

224 225 226
    return buf_ptr;
}

227
void *encode_data_header(void *buf_ptr, const void *payload) {
228
    const PrrtPacketDataPayload *data_payload = payload;
229

230
    prrtPacketLength_t *packetLength = (prrtPacketLength_t *) buf_ptr;
rna's avatar
rna committed
231 232 233
    *packetLength = htonl(data_payload->dataLength);
    buf_ptr += sizeof(prrtPacketLength_t);

234
    prrtTimestamp_t *timestamp = (prrtTimestamp_t *) buf_ptr;
235
    *timestamp = htonl(data_payload->timestamp);
236
    buf_ptr += sizeof(prrtTimestamp_t);
237

238
    prrtTimedelta_t *group_round_trip_time = (prrtTimedelta_t *) buf_ptr;
239
    *group_round_trip_time = htonl(data_payload->groupRTprop_us);
240
    buf_ptr += sizeof(prrtTimedelta_t);
241

242 243 244
    prrtTimedelta_t *packet_timeout = (prrtTimedelta_t *) buf_ptr;
    *packet_timeout = htonl(data_payload->packetTimeout_us);
    buf_ptr += sizeof(prrtTimedelta_t);
245 246 247 248

    return buf_ptr;
}

249
void *encode_general_header(void *buf_ptr, const PrrtPacket *packet) {
250
    uint8_t *type_priority = (uint8_t *) buf_ptr;
251
    *type_priority = packet->type_priority;
252
    buf_ptr += sizeof(uint8_t);
253

254
    uint8_t *index = (uint8_t *) buf_ptr;
255
    *index = packet->index;
256
    buf_ptr += sizeof(uint8_t);
257

258 259 260
    prrtSequenceNumber_t *seqno = (prrtSequenceNumber_t *) buf_ptr;
    *seqno = htons(packet->sequenceNumber);
    buf_ptr += sizeof(prrtSequenceNumber_t);
261

262
    return buf_ptr;
263 264
}

265
bool PrrtPacket_decode(void *srcBuffer, uint16_t srcBufferSize, PrrtPacket *targetPacket) {
266
    prrtPacketLength_t payload_len = (prrtPacketLength_t) (srcBufferSize - PRRT_PACKET_GENERAL_HEADER_SIZE);
Andreas Schmidt's avatar
Andreas Schmidt committed
267 268 269 270 271
    targetPacket->type_priority = *(uint8_t *) srcBuffer;
    srcBuffer += 1;
    uint8_t *index_ptr = (uint8_t *) srcBuffer;
    targetPacket->index = *index_ptr;
    srcBuffer += 1;
272 273 274
    prrtSequenceNumber_t *seqno_prt = (prrtSequenceNumber_t *) srcBuffer;
    targetPacket->sequenceNumber = ntohs(*seqno_prt);
    srcBuffer += sizeof(prrtSequenceNumber_t);
275

Andreas Schmidt's avatar
Andreas Schmidt committed
276
    void *payload_buffer = calloc(1, payload_len);
277 278
    check_mem(payload_buffer);

Andreas Schmidt's avatar
Andreas Schmidt committed
279
    targetPacket->payload = payload_buffer;
280
    targetPacket->payloadLength = payload_len;
Andreas Schmidt's avatar
Andreas Schmidt committed
281

282
    prrtPacketType_t packetType = PrrtPacket_type(targetPacket);
283
    if (packetType == PACKET_TYPE_DATA) {
Andreas Schmidt's avatar
Andreas Schmidt committed
284 285
        srcBuffer = decode_data_header(srcBuffer, payload_buffer);
        PrrtPacket_copy_buffer_to_payload(targetPacket, srcBuffer, PRRT_PACKET_DATA_HEADER_SIZE);
286
    } else if (packetType == PACKET_TYPE_REDUNDANCY) {
Andreas Schmidt's avatar
Andreas Schmidt committed
287 288
        srcBuffer = decode_redundancy_header(srcBuffer, payload_buffer);
        PrrtPacket_copy_buffer_to_payload(targetPacket, srcBuffer, PRRT_PACKET_REDUNDANCY_HEADER_SIZE);
289
    } else if (packetType == PACKET_TYPE_FEEDBACK) {
290
        decode_feedback_header(srcBuffer, payload_buffer);
Andreas Schmidt's avatar
Andreas Schmidt committed
291
    } else {
292
        printf("NOT IMPLEMENTED\n");
Andreas Schmidt's avatar
Andreas Schmidt committed
293
    }
294
    return true;
295 296

    error:
297
    return false;
Andreas Schmidt's avatar
Andreas Schmidt committed
298
}
299

300
void *decode_redundancy_header(void *dstBuffer, const void *srcBuffer) {
Andreas Schmidt's avatar
Andreas Schmidt committed
301
    PrrtPacketRedundancyPayload *redundancyPayload = (PrrtPacketRedundancyPayload *) srcBuffer;
302

303 304 305
    prrtSequenceNumber_t *baseSeqNo = (prrtSequenceNumber_t *) dstBuffer;
    redundancyPayload->baseSequenceNumber = ntohs(*baseSeqNo);
    dstBuffer += sizeof(prrtSequenceNumber_t);
306

307 308 309 310
    prrtTimestamp_t *timestamp = (prrtTimestamp_t*) dstBuffer;
    redundancyPayload->timestamp = ntohl(*timestamp);
    dstBuffer += sizeof(prrtTimestamp_t);

Andreas Schmidt's avatar
Andreas Schmidt committed
311
    uint8_t *n = (uint8_t *) dstBuffer;
312
    redundancyPayload->n = *n;
313
    dstBuffer += sizeof(uint8_t);
314

Andreas Schmidt's avatar
Andreas Schmidt committed
315
    uint8_t *k = (uint8_t *) dstBuffer;
316
    redundancyPayload->k = *k;
317
    dstBuffer += sizeof(uint8_t);
318

Andreas Schmidt's avatar
Andreas Schmidt committed
319
    return dstBuffer;
320 321
}

322
void *decode_feedback_header(void *dstBuffer, const void *srcBuffer) {
Andreas Schmidt's avatar
Andreas Schmidt committed
323
    PrrtPacketFeedbackPayload *feedback_payload = (PrrtPacketFeedbackPayload *) srcBuffer;
324

325 326 327
    prrtTimedelta_t *groupRoundTripTime = (prrtTimedelta_t *) dstBuffer;
    feedback_payload->groupRTT_us = ntohl(*groupRoundTripTime);
    dstBuffer += sizeof(prrtTimedelta_t);
328

329 330 331
    prrtTimestamp_t *forwardTripTime = (prrtTimestamp_t *) dstBuffer;
    feedback_payload->forwardTripTimestamp_us = ntohl(*forwardTripTime);
    dstBuffer += sizeof(prrtTimestamp_t);
332

333 334 335
    prrtSequenceNumber_t *erasureCount = (prrtSequenceNumber_t *) dstBuffer;
    feedback_payload->erasureCount = ntohs(*erasureCount);
    dstBuffer += sizeof(prrtSequenceNumber_t);
336

337 338 339
    prrtSequenceNumber_t *packetCount = (prrtSequenceNumber_t *) dstBuffer;
    feedback_payload->packetCount = ntohs(*packetCount);
    dstBuffer += sizeof(prrtSequenceNumber_t);
340

341 342 343
    prrtSequenceNumber_t *gap = (prrtSequenceNumber_t *) dstBuffer;
    feedback_payload->gapLength = ntohs(*gap);
    dstBuffer += sizeof(prrtSequenceNumber_t);
Andreas Schmidt's avatar
Andreas Schmidt committed
344

345 346 347
    prrtSequenceNumber_t *ngap = (prrtSequenceNumber_t *) dstBuffer;
    feedback_payload->gapCount = ntohs(*ngap);
    dstBuffer += sizeof(prrtSequenceNumber_t);
Andreas Schmidt's avatar
Andreas Schmidt committed
348

349 350 351
    prrtSequenceNumber_t *burst = (prrtSequenceNumber_t *) dstBuffer;
    feedback_payload->burstLength = ntohs(*burst);
    dstBuffer += sizeof(prrtSequenceNumber_t);
Andreas Schmidt's avatar
Andreas Schmidt committed
352

353 354 355
    prrtSequenceNumber_t *nburst = (prrtSequenceNumber_t *) dstBuffer;
    feedback_payload->burstCount = ntohs(*nburst);
    dstBuffer += sizeof(prrtSequenceNumber_t);
Andreas Schmidt's avatar
Andreas Schmidt committed
356

357 358 359 360 361 362 363 364
    prrtPacketType_t *ackPacketType = (prrtPacketType_t *) dstBuffer;
    feedback_payload->ackPacketType = *ackPacketType;
    dstBuffer += sizeof(prrtPacketType_t);

    prrtSequenceNumber_t *ackSequenceNumber = (prrtSequenceNumber_t *) dstBuffer;
    feedback_payload->ackSequenceNumber = ntohs(*ackSequenceNumber);
    dstBuffer += sizeof(prrtSequenceNumber_t);

Andreas Schmidt's avatar
Andreas Schmidt committed
365
    return dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
366 367
}

368
void *decode_data_header(void *dstBuffer, const void *srcBuffer) {
Andreas Schmidt's avatar
Andreas Schmidt committed
369
    PrrtPacketDataPayload *data_payload = (PrrtPacketDataPayload *) srcBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
370

rna's avatar
rna committed
371 372 373 374
    prrtPacketLength_t *dataLength = (prrtPacketLength_t *) dstBuffer;
    data_payload->dataLength = ntohl(*dataLength);
    dstBuffer += sizeof(prrtPacketLength_t);

375
    prrtTimestamp_t *timestamp = (prrtTimestamp_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
376
    data_payload->timestamp = ntohl(*timestamp);
377
    dstBuffer += sizeof(prrtTimestamp_t);
Andreas Schmidt's avatar
Andreas Schmidt committed
378

379
    prrtTimedelta_t *group_round_trip_time = (prrtTimedelta_t *) dstBuffer;
380
    data_payload->groupRTprop_us = ntohl(*group_round_trip_time);
381
    dstBuffer += sizeof(prrtTimedelta_t);
Andreas Schmidt's avatar
Andreas Schmidt committed
382

383 384 385
    prrtTimedelta_t *packet_timeout = (prrtTimedelta_t *) dstBuffer;
    data_payload->packetTimeout_us = ntohl(*packet_timeout);
    dstBuffer += sizeof(prrtTimedelta_t);
Andreas Schmidt's avatar
Andreas Schmidt committed
386

Andreas Schmidt's avatar
Andreas Schmidt committed
387
    return dstBuffer;
388 389
}

390 391
int PrrtPacket_destroy(PrrtPacket *packet) {
    if (packet->payload != NULL) {
Andreas Schmidt's avatar
Andreas Schmidt committed
392
        free(packet->payload);
393
    }
Andreas Schmidt's avatar
Andreas Schmidt committed
394
    free(packet);
395 396 397
    return 0;
}

398
PrrtPacket *PrrtPacket_create_data_packet(uint8_t priority, const void *payloadPointer,
rna's avatar
rna committed
399
                                          prrtPacketLength_t dataLength, prrtSequenceNumber_t sequenceNumber,
400
                                          prrtTimedelta_t targetDelay) {
Andreas Schmidt's avatar
Andreas Schmidt committed
401
    PrrtPacket *packet = create_header(priority, sequenceNumber,
402 403
                                       (prrtPacketLength_t) (dataLength + PRRT_PACKET_DATA_HEADER_SIZE),
                                       PACKET_TYPE_DATA, 0);
404

405
    PrrtPacketDataPayload *dataPayload = calloc(1, packet->payloadLength);
Andreas Schmidt's avatar
Andreas Schmidt committed
406 407
    check_mem(dataPayload);
    packet->payload = dataPayload;
408

rna's avatar
rna committed
409
    dataPayload->dataLength = dataLength;
410
    dataPayload->timestamp = PrrtClock_get_current_time_us();
411
    dataPayload->packetTimeout_us = dataPayload->timestamp + targetDelay;
412
    dataPayload->groupRTprop_us = 0;
Andreas Schmidt's avatar
Andreas Schmidt committed
413
    PrrtPacket_copy_buffer_to_payload(packet, payloadPointer, PRRT_PACKET_DATA_HEADER_SIZE)
414

Andreas Schmidt's avatar
Andreas Schmidt committed
415
    return packet;
416

417
    error:
418
    PERROR("Could not create packet.%s", "");
Andreas Schmidt's avatar
Andreas Schmidt committed
419
    return NULL;
420 421
}

422 423
PrrtPacket *PrrtPacket_reconstruct_data_packet(PrrtPacketDataPayload *payload, prrtIndex_t index,
                                               prrtSequenceNumber_t sequenceNumber) {
rna's avatar
rna committed
424 425 426
    prrtPacketLength_t dataLength = payload->dataLength;

    PrrtPacket *packet = create_header(0, sequenceNumber,
427 428
                                       (prrtPacketLength_t) (dataLength + PRRT_PACKET_DATA_HEADER_SIZE),
                                       PACKET_TYPE_DATA, index);
rna's avatar
rna committed
429 430 431 432 433 434 435 436 437 438 439 440 441 442

    PrrtPacketDataPayload *dataPayload = calloc(1, packet->payloadLength);
    check_mem(dataPayload);
    packet->payload = dataPayload;

    PrrtPacket_copy_buffer_to_payload(packet, payload, 0)

    return packet;
    error:
    PERROR("Could not reconstruct packet.%s", "");
    return NULL;

}

443 444 445
PrrtPacket *PrrtPacket_create_redundancy_packet(uint8_t priority, void *payloadPointer,
                                                prrtPacketLength_t payloadLength,
                                                prrtSequenceNumber_t sequenceNumber, uint8_t index,
446
                                                prrtSequenceNumber_t baseSequenceNumber,
447
                                                PrrtCodingConfiguration *codingParams) {
Andreas Schmidt's avatar
Andreas Schmidt committed
448
    PrrtPacket *packet = create_header(priority, sequenceNumber,
449
                                       (prrtPacketLength_t) (payloadLength + PRRT_PACKET_REDUNDANCY_HEADER_SIZE),
Andreas Schmidt's avatar
Andreas Schmidt committed
450
                                       PACKET_TYPE_REDUNDANCY, index);
451

452
    PrrtPacketRedundancyPayload *redundancyPayload = calloc(1, packet->payloadLength);
Andreas Schmidt's avatar
Andreas Schmidt committed
453 454
    check_mem(redundancyPayload);
    packet->payload = redundancyPayload;
455

456
    redundancyPayload->baseSequenceNumber = baseSequenceNumber;
457
    redundancyPayload->timestamp = PrrtClock_get_current_time_us();
458 459
    redundancyPayload->k = codingParams->k;
    redundancyPayload->n = codingParams->n;
Andreas Schmidt's avatar
Andreas Schmidt committed
460
    PrrtPacket_copy_buffer_to_payload(packet, payloadPointer, PRRT_PACKET_REDUNDANCY_HEADER_SIZE);
461

Andreas Schmidt's avatar
Andreas Schmidt committed
462
    return packet;
463 464

    error:
465
    PERROR("Out of memory%s.", "");
466
    return NULL;
467 468
}

469 470 471 472 473 474 475
PrrtPacket *
PrrtPacket_create_feedback_packet(uint8_t priority, prrtSequenceNumber_t sequenceNumber, prrtTimedelta_t groupRTT,
                                  prrtSequenceNumber_t gapLength, prrtSequenceNumber_t gapCount,
                                  prrtSequenceNumber_t burstLength, prrtSequenceNumber_t burstCount,
                                  prrtTimestamp_t forwardTripTime, prrtSequenceNumber_t erasureCount,
                                  prrtSequenceNumber_t packetCount, prrtSequenceNumber_t ackSequenceNumber,
                                  prrtPacketType_t ackPacketType) {
Andreas Schmidt's avatar
Andreas Schmidt committed
476
    PrrtPacket *packet = create_header(priority, sequenceNumber, PRRT_PACKET_FEEDBACK_HEADER_SIZE, PACKET_TYPE_FEEDBACK,
477
                                       0);
Andreas Schmidt's avatar
Andreas Schmidt committed
478

479
    PrrtPacketFeedbackPayload *payload = calloc(1, packet->payloadLength);
480
    check_mem(payload);
Andreas Schmidt's avatar
Andreas Schmidt committed
481
    packet->payload = payload;
482

483 484
    payload->groupRTT_us = groupRTT;
    payload->forwardTripTimestamp_us = forwardTripTime;
Andreas Schmidt's avatar
Andreas Schmidt committed
485 486
    payload->erasureCount = erasureCount;
    payload->packetCount = packetCount;
487 488 489 490
    payload->gapLength = gapLength;
    payload->gapCount = gapCount;
    payload->burstLength = burstLength;
    payload->burstCount = burstCount;
491 492
    payload->ackSequenceNumber = ackSequenceNumber;
    payload->ackPacketType = ackPacketType;
493

Andreas Schmidt's avatar
Andreas Schmidt committed
494
    return packet;
495 496

    error:
497
    return NULL;
498
}