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

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

12
void *encode_data_header(void *buf_ptr, const void *payload);
13

14
void *encode_redundancy_header(void *buf_ptr, const void *payload);
15

16
void *encode_feedback_header(void *buf_ptr, const void *payload);
17

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

Andreas Schmidt's avatar
Andreas Schmidt committed
20
void *decode_redundancy_header(void *dstBuffer, const void *srcBuffer);
21

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

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

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

34
35
uint16_t PrrtPacket_size(PrrtPacket *packet_ptr)
{
Andreas Schmidt's avatar
Andreas Schmidt committed
36
    return (uint16_t) (packet_ptr->payload_len + PRRT_PACKET_GENERAL_HEADER_SIZE);
37
38
}

39
40
int PrrtPacket_print(PrrtPacket *packet_ptr)
{
41
42
    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"
43
                   "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
44
    uint8_t type = PrrtPacket_type(packet_ptr);
45

46
47
    printf("| %5u | %5u | %13u | %29u |\n", type, PrrtPacket_priority(packet_ptr), packet_ptr->index,
           packet_ptr->seqno);
48
    printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
49

50
    if(type == PACKET_TYPE_DATA) {
51
        PrrtPacketDataPayload *payload = packet_ptr->payload;
52
53
54
55
        printf("| %61u |\n", payload->timestamp);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
        printf("| %29u | %29u |\n", payload->group_round_trip_time, payload->packet_timeout);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
56
57
        printf("| %29u | %29u |\n", payload->decoding_timeout, payload->feedback_timeout);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
58
59
        printf("| %61s |\n", (char *) (packet_ptr->payload + PRRT_PACKET_DATA_HEADER_SIZE));
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
60
    } else if(type == PACKET_TYPE_REDUNDANCY) {
61
62
63
        PrrtPacketRedundancyPayload *payload = packet_ptr->payload;
        printf("| %29u | %13u | %13u |\n", payload->base_seqno, payload->n, payload->k);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
64
    } else if(type == PACKET_TYPE_FEEDBACK) {
65
        PrrtPacketFeedbackPayload *payload = packet_ptr->payload;
66
        printf("| %61u |\n", payload->group_round_trip_time);
67
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
68
        printf("| %61u |\n", payload->forward_trip_time);
69
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
70
        printf("| %61u |\n", payload->packet_loss_rate);
71
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
72
        printf("| %29u | %29u |\n", payload->gap, payload->ngap);
73
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
74
        printf("| %29u | %29u |\n", payload->burst, payload->nburst);
75
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
76
        printf("| %61u |\n", payload->bandwidth_estimate);
77
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
78
79
        printf("| %61u |\n", payload->buffer_feedback);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
80
    } else {
81
82
        printf("| Unhandeled Type                                               |\n");
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
83
84
85
86
87
    }

    return 0;
}

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
PrrtPacket *PrrtPacket_copy(PrrtPacket *original)
{
    PrrtPacket *newPacket = calloc(1, sizeof(PrrtPacket));
    check_mem(newPacket);
    void *payload = calloc(1, original->payload_len);
    check_mem(payload);

    newPacket->payload = payload;
    newPacket->payload_len = original->payload_len;
    memcpy(newPacket->payload, original->payload, original->payload_len);

    newPacket->index = original->index;
    newPacket->seqno = original->seqno;
    newPacket->type_priority = original->type_priority;


    return newPacket;
    error:
106
    PERROR("Not enough memory for packet copies.%s", "");
107
108
}

Andreas Schmidt's avatar
Andreas Schmidt committed
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
PrrtPacket *create_header(uint8_t priority, uint16_t seqno, uint32_t size, uint8_t type, uint8_t index)
{
    PrrtPacket *packet = calloc(1, sizeof(PrrtPacket));
    check_mem(packet);

    packet->type_priority = type << 4;
    packet->type_priority |= priority & 0x0F;
    packet->index = index;
    packet->seqno = seqno;
    packet->payload_len = size;

    return packet;

    error:
    PERROR("Could not create packet.%s", "");
}

126
127
int PrrtPacket_encode(void *buf_ptr, uint16_t buf_size, PrrtPacket *packet_ptr)
{
128
    void *payload = packet_ptr->payload;
129

130
    check(packet_ptr->payload_len + PRRT_PACKET_GENERAL_HEADER_SIZE <= buf_size, "Buffer too small.");
131

132
133
    buf_ptr = encode_general_header(buf_ptr, packet_ptr);

134
    uint8_t type = PrrtPacket_type(packet_ptr);
135
    if(type == PACKET_TYPE_DATA) {
136
        buf_ptr = encode_data_header(buf_ptr, payload);
137
        PrrtPacket_copy_payload_to_buffer(buf_ptr, packet_ptr, PRRT_PACKET_DATA_HEADER_SIZE);
138
    } else if(type == PACKET_TYPE_REDUNDANCY) {
139
        buf_ptr = encode_redundancy_header(buf_ptr, payload);
140
        PrrtPacket_copy_payload_to_buffer(buf_ptr, packet_ptr, PRRT_PACKET_REDUNDANCY_HEADER_SIZE);
141
    } else if(type == PACKET_TYPE_FEEDBACK) {
142
        buf_ptr = encode_feedback_header(buf_ptr, payload);
143
        PrrtPacket_copy_payload_to_buffer(buf_ptr, packet_ptr, PRRT_PACKET_FEEDBACK_HEADER_SIZE);
144
145
146
147
148
    } else {
        perror("NOT IMPLEMENTED");
        return -1;
    }
    return 0;
149
150

    error:
151
    return -1;
152
153
}

154
155
void *encode_redundancy_header(void *buf_ptr, const void *payload)
{
156
    const PrrtPacketRedundancyPayload *redundancyPayload = payload;
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

    uint16_t *baseSeqNo = (uint16_t *) buf_ptr;
    *baseSeqNo = htons(redundancyPayload->base_seqno);
    buf_ptr += 2;

    uint8_t *n = (uint8_t *) buf_ptr;
    *n = redundancyPayload->n;
    buf_ptr += 1;

    uint8_t *k = (uint8_t *) buf_ptr;
    *k = redundancyPayload->k;
    buf_ptr += 1;

    return buf_ptr;
}

173
174
void *encode_feedback_header(void *buf_ptr, const void *payload)
{
175
    const PrrtPacketFeedbackPayload *feedbackPayload = payload;
176
177

    uint32_t *receiver_ip = (uint32_t *) buf_ptr;
178
    *receiver_ip = htonl(feedbackPayload->receiver_addr);
179
180
181
    buf_ptr += 4;

    uint32_t *group_round_trip_time = (uint32_t *) buf_ptr;
182
183
    *group_round_trip_time = htonl(feedbackPayload->group_round_trip_time);
    buf_ptr += 4;
184
185

    uint32_t *forward_trip_time = (uint32_t *) buf_ptr;
186
187
    *forward_trip_time = htonl(feedbackPayload->forward_trip_time);
    buf_ptr += 4;
188
189

    uint32_t *packet_loss_rate = (uint32_t *) buf_ptr;
190
191
    *packet_loss_rate = htonl(feedbackPayload->packet_loss_rate);
    buf_ptr += 4;
192
193

    uint16_t *gap = (uint16_t *) buf_ptr;
194
195
    *gap = htons(feedbackPayload->gap);
    buf_ptr += 2;
196
197

    uint16_t *ngap = (uint16_t *) buf_ptr;
198
199
    *ngap = htons(feedbackPayload->ngap);
    buf_ptr += 2;
200
201

    uint16_t *burst = (uint16_t *) buf_ptr;
202
203
    *burst = htons(feedbackPayload->burst);
    buf_ptr += 2;
204
205

    uint16_t *nburst = (uint16_t *) buf_ptr;
206
207
    *nburst = htons(feedbackPayload->nburst);
    buf_ptr += 2;
208
209

    uint32_t *bandwidth_estimate = (uint32_t *) buf_ptr;
210
211
    *bandwidth_estimate = htonl(feedbackPayload->bandwidth_estimate);
    buf_ptr += 4;
212
213

    uint32_t *buffer_feedback = (uint32_t *) buf_ptr;
214
215
    *buffer_feedback = htonl(feedbackPayload->buffer_feedback);
    buf_ptr += 4;
216
217
218
219

    return buf_ptr;
}

220
221
void *encode_data_header(void *buf_ptr, const void *payload)
{
222
    const PrrtPacketDataPayload *data_payload = payload;
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

    uint32_t *timestamp = (uint32_t *) buf_ptr;
    *timestamp = htonl(data_payload->timestamp);
    buf_ptr += 4;

    uint16_t *group_round_trip_time = (uint16_t *) buf_ptr;
    *group_round_trip_time = htons(data_payload->group_round_trip_time);
    buf_ptr += 2;

    uint16_t *packet_timeout = (uint16_t *) buf_ptr;
    *packet_timeout = htons(data_payload->packet_timeout);
    buf_ptr += 2;

    uint16_t *decoding_timeout = (uint16_t *) buf_ptr;
    *decoding_timeout = htons(data_payload->decoding_timeout);
    buf_ptr += 2;

    uint16_t *feedback_timeout = (uint16_t *) buf_ptr;
    *feedback_timeout = htons(data_payload->feedback_timeout);
    buf_ptr += 2;
    return buf_ptr;
}

246
247
void *encode_general_header(void *buf_ptr, const PrrtPacket *packet)
{
248
    uint8_t *type_priority = (uint8_t *) buf_ptr;
249
250
    *type_priority = packet->type_priority;
    buf_ptr += 1;
251

252
    uint8_t *index = (uint8_t *) buf_ptr;
253
254
    *index = packet->index;
    buf_ptr += 1;
255

256
    uint16_t *seqno = (uint16_t *) buf_ptr;
257
258
    *seqno = htons(packet->seqno);
    buf_ptr += 2;
259

260
    return buf_ptr;
261
262
}

Andreas Schmidt's avatar
Andreas Schmidt committed
263
int PrrtPacket_decode(void *srcBuffer, uint16_t srcBufferSize, PrrtPacket *targetPacket)
264
{
Andreas Schmidt's avatar
Andreas Schmidt committed
265
266
267
268
269
270
271
272
273
    uint32_t payload_len = (uint32_t) (srcBufferSize - PRRT_PACKET_GENERAL_HEADER_SIZE);
    targetPacket->type_priority = *(uint8_t *) srcBuffer;
    srcBuffer += 1;
    uint8_t *index_ptr = (uint8_t *) srcBuffer;
    targetPacket->index = *index_ptr;
    srcBuffer += 1;
    uint16_t *seqno_prt = (uint16_t *) srcBuffer;
    targetPacket->seqno = ntohs(*seqno_prt);
    srcBuffer += 2;
274

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

Andreas Schmidt's avatar
Andreas Schmidt committed
278
279
280
281
282
283
284
285
286
287
288
289
    targetPacket->payload = payload_buffer;
    targetPacket->payload_len = payload_len;

    if(PrrtPacket_type(targetPacket) == PACKET_TYPE_DATA) {
        srcBuffer = decode_data_header(srcBuffer, payload_buffer);
        PrrtPacket_copy_buffer_to_payload(targetPacket, srcBuffer, PRRT_PACKET_DATA_HEADER_SIZE);
    } else if(PrrtPacket_type(targetPacket)) {
        srcBuffer = decode_redundancy_header(srcBuffer, payload_buffer);
        PrrtPacket_copy_buffer_to_payload(targetPacket, srcBuffer, PRRT_PACKET_REDUNDANCY_HEADER_SIZE);
    } else if(PrrtPacket_type(targetPacket) == PACKET_TYPE_FEEDBACK) {
        srcBuffer = decode_feedback_header(srcBuffer, payload_buffer);
        PrrtPacket_copy_buffer_to_payload(targetPacket, srcBuffer, PRRT_PACKET_FEEDBACK_HEADER_SIZE);
Andreas Schmidt's avatar
Andreas Schmidt committed
290
    } else {
291
        printf("NOT IMPLEMENTED\n");
Andreas Schmidt's avatar
Andreas Schmidt committed
292
293
    }
    return 0;
294
295

    error:
296
    return EXIT_FAILURE;
Andreas Schmidt's avatar
Andreas Schmidt committed
297
}
298

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

Andreas Schmidt's avatar
Andreas Schmidt committed
303
    uint16_t *baseSeqNo = (uint16_t *) dstBuffer;
304
    redundancyPayload->base_seqno = ntohs(*baseSeqNo);
Andreas Schmidt's avatar
Andreas Schmidt committed
305
    dstBuffer += 2;
306

Andreas Schmidt's avatar
Andreas Schmidt committed
307
    uint8_t *n = (uint8_t *) dstBuffer;
308
    redundancyPayload->n = *n;
Andreas Schmidt's avatar
Andreas Schmidt committed
309
    dstBuffer += 1;
310

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

Andreas Schmidt's avatar
Andreas Schmidt committed
315
    return dstBuffer;
316
317
}

Andreas Schmidt's avatar
Andreas Schmidt committed
318
void *decode_feedback_header(void *dstBuffer, const void *srcBuffer)
319
{
Andreas Schmidt's avatar
Andreas Schmidt committed
320
    PrrtPacketFeedbackPayload *feedback_payload = (PrrtPacketFeedbackPayload *) srcBuffer;
321

Andreas Schmidt's avatar
Andreas Schmidt committed
322
323
324
    uint32_t *receiverAddr = (uint32_t *) dstBuffer;
    feedback_payload->receiver_addr = ntohl(*receiverAddr);
    dstBuffer += 4;
325

Andreas Schmidt's avatar
Andreas Schmidt committed
326
327
328
    uint32_t *groupRoundTripTime = (uint32_t *) dstBuffer;
    feedback_payload->group_round_trip_time = ntohl(*groupRoundTripTime);
    dstBuffer += 4;
329

Andreas Schmidt's avatar
Andreas Schmidt committed
330
331
332
    uint32_t *forwardTripTime = (uint32_t *) dstBuffer;
    feedback_payload->forward_trip_time = ntohl(*forwardTripTime);
    dstBuffer += 4;
333

Andreas Schmidt's avatar
Andreas Schmidt committed
334
335
336
    uint32_t *packetLossRate = (uint32_t *) dstBuffer;
    feedback_payload->packet_loss_rate = ntohl(*packetLossRate);
    dstBuffer += 4;
337

Andreas Schmidt's avatar
Andreas Schmidt committed
338
    uint16_t *gap = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
339
    feedback_payload->gap = ntohs(*gap);
Andreas Schmidt's avatar
Andreas Schmidt committed
340
    dstBuffer += 2;
341

Andreas Schmidt's avatar
Andreas Schmidt committed
342
    uint16_t *ngap = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
343
    feedback_payload->ngap = ntohs(*ngap);
Andreas Schmidt's avatar
Andreas Schmidt committed
344
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
345

Andreas Schmidt's avatar
Andreas Schmidt committed
346
    uint16_t *burst = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
347
    feedback_payload->burst = ntohs(*burst);
Andreas Schmidt's avatar
Andreas Schmidt committed
348
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
349

Andreas Schmidt's avatar
Andreas Schmidt committed
350
    uint16_t *nburst = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
351
    feedback_payload->nburst = ntohs(*nburst);
Andreas Schmidt's avatar
Andreas Schmidt committed
352
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
353

Andreas Schmidt's avatar
Andreas Schmidt committed
354
355
356
    uint32_t *bandwidthEstimate = (uint32_t *) dstBuffer;
    feedback_payload->bandwidth_estimate = ntohl(*bandwidthEstimate);
    dstBuffer += 4;
Andreas Schmidt's avatar
Andreas Schmidt committed
357

Andreas Schmidt's avatar
Andreas Schmidt committed
358
359
360
    uint32_t *bufferFeedback = (uint32_t *) dstBuffer;
    feedback_payload->buffer_feedback = ntohl(*bufferFeedback);
    dstBuffer += 4;
Andreas Schmidt's avatar
Andreas Schmidt committed
361

Andreas Schmidt's avatar
Andreas Schmidt committed
362
    return dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
363
364
}

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

Andreas Schmidt's avatar
Andreas Schmidt committed
369
    uint32_t *timestamp = (uint32_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
370
    data_payload->timestamp = ntohl(*timestamp);
Andreas Schmidt's avatar
Andreas Schmidt committed
371
    dstBuffer += 4;
Andreas Schmidt's avatar
Andreas Schmidt committed
372

Andreas Schmidt's avatar
Andreas Schmidt committed
373
    uint16_t *group_round_trip_time = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
374
    data_payload->group_round_trip_time = ntohs(*group_round_trip_time);
Andreas Schmidt's avatar
Andreas Schmidt committed
375
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
376

Andreas Schmidt's avatar
Andreas Schmidt committed
377
    uint16_t *packet_timeout = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
378
    data_payload->packet_timeout = ntohs(*packet_timeout);
Andreas Schmidt's avatar
Andreas Schmidt committed
379
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
380

Andreas Schmidt's avatar
Andreas Schmidt committed
381
    uint16_t *decoding_timeout = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
382
    data_payload->decoding_timeout = ntohs(*decoding_timeout);
Andreas Schmidt's avatar
Andreas Schmidt committed
383
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
384

Andreas Schmidt's avatar
Andreas Schmidt committed
385
    uint16_t *feedback_timeout = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
386
    data_payload->feedback_timeout = ntohs(*feedback_timeout);
Andreas Schmidt's avatar
Andreas Schmidt committed
387
388
    dstBuffer += 2;
    return dstBuffer;
389
390
}

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

Andreas Schmidt's avatar
Andreas Schmidt committed
400
401
PrrtPacket *PrrtPacket_create_data_packet(uint8_t priority, const void *payloadPointer, uint32_t payloadLength,
                                          uint16_t sequenceNumber)
402
{
Andreas Schmidt's avatar
Andreas Schmidt committed
403
404
    PrrtPacket *packet = create_header(priority, sequenceNumber,
                                       (uint32_t) (payloadLength + PRRT_PACKET_DATA_HEADER_SIZE), PACKET_TYPE_DATA, 0);
405

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

    struct timeval tv;
411
    gettimeofday(&tv, NULL);
412
413
    unsigned long time_in_micros = (unsigned long) (1000000 * tv.tv_sec + tv.tv_usec);

Andreas Schmidt's avatar
Andreas Schmidt committed
414
415
416
417
418
419
    dataPayload->timestamp = (uint32_t) time_in_micros;
    dataPayload->group_round_trip_time = 95; // TODO: payload->rtt = CURRENT ESTIMATE
    dataPayload->packet_timeout = 110; // TODO: payload->packet_timeout = NOW + maximum delay
    dataPayload->decoding_timeout = 150; // TODO: payload->decoding_timeout
    dataPayload->feedback_timeout = 170; // TODO: payload->feedback_timer
    PrrtPacket_copy_buffer_to_payload(packet, payloadPointer, PRRT_PACKET_DATA_HEADER_SIZE)
420

Andreas Schmidt's avatar
Andreas Schmidt committed
421
    return packet;
422

423
    error:
424
    PERROR("Could not create packet.%s","");
425
426
}

Andreas Schmidt's avatar
Andreas Schmidt committed
427
428
PrrtPacket *PrrtPacket_create_redundancy_packet(uint8_t priority, void *payloadPointer, uint32_t payloadLength,
                                                uint16_t sequenceNumber, uint8_t index, uint16_t baseSequenceNumber,
429
430
                                                PrrtCodingParams codingParams)
{
Andreas Schmidt's avatar
Andreas Schmidt committed
431
432
433
    PrrtPacket *packet = create_header(priority, sequenceNumber,
                                       (uint32_t) (payloadLength + PRRT_PACKET_REDUNDANCY_HEADER_SIZE),
                                       PACKET_TYPE_REDUNDANCY, index);
434

Andreas Schmidt's avatar
Andreas Schmidt committed
435
436
437
    PrrtPacketRedundancyPayload *redundancyPayload = calloc(1, packet->payload_len);
    check_mem(redundancyPayload);
    packet->payload = redundancyPayload;
438

Andreas Schmidt's avatar
Andreas Schmidt committed
439
440
441
442
    redundancyPayload->base_seqno = baseSequenceNumber;
    redundancyPayload->k = codingParams.k;
    redundancyPayload->n = codingParams.n;
    PrrtPacket_copy_buffer_to_payload(packet, payloadPointer, PRRT_PACKET_REDUNDANCY_HEADER_SIZE);
443

Andreas Schmidt's avatar
Andreas Schmidt committed
444
    return packet;
445
446

    error:
447
    return NULL;
448
449
}

Andreas Schmidt's avatar
Andreas Schmidt committed
450
451
452
453
PrrtPacket *PrrtPacket_create_feedback_packet(uint8_t priority, uint8_t index, uint16_t sequenceNumber,
                                              uint32_t roundTripTime, uint32_t forwardTripTime, uint32_t packetLossRate,
                                              uint16_t gap, uint16_t ngap, uint16_t burst, uint16_t nburst,
                                              uint32_t bandwidth, uint32_t bufferFeedback)
454
{
Andreas Schmidt's avatar
Andreas Schmidt committed
455
456
457
458
    PrrtPacket *packet = create_header(priority, sequenceNumber, PRRT_PACKET_FEEDBACK_HEADER_SIZE, PACKET_TYPE_FEEDBACK,
                                       index);

    PrrtPacketFeedbackPayload *payload = calloc(1, packet->payload_len);
459
    check_mem(payload);
Andreas Schmidt's avatar
Andreas Schmidt committed
460
    packet->payload = payload;
461

Andreas Schmidt's avatar
Andreas Schmidt committed
462
463
464
    payload->group_round_trip_time = roundTripTime;
    payload->forward_trip_time = forwardTripTime;
    payload->packet_loss_rate = packetLossRate;
465
466
467
468
    payload->gap = gap;
    payload->ngap = ngap;
    payload->burst = burst;
    payload->nburst = nburst;
469
    payload->bandwidth_estimate = bandwidth;
Andreas Schmidt's avatar
Andreas Schmidt committed
470
    payload->buffer_feedback = bufferFeedback;
471
472


Andreas Schmidt's avatar
Andreas Schmidt committed
473
    return packet;
474
475

    error:
476
    return NULL;
477
}