packet.c 16.8 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"
8
#include <stdbool.h>
9
#include <arpa/inet.h>
Andreas Schmidt's avatar
Andreas Schmidt committed
10
#include "packet.h"
11

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

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

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

18
void *encode_feedback_header(void *buf_ptr, const void *payload);
19

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

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

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

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

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

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

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

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

52
    if(type == PACKET_TYPE_DATA) {
53
        PrrtPacketDataPayload *payload = packet_ptr->payload;
54
55
56
57
        printf("| %61u |\n", payload->timestamp);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
        printf("| %29u | %29u |\n", payload->group_round_trip_time, payload->packet_timeout);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
58
59
        printf("| %29u | %29u |\n", payload->decoding_timeout, payload->feedback_timeout);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
60
61
        printf("| %61s |\n", (char *) (packet_ptr->payload + PRRT_PACKET_DATA_HEADER_SIZE));
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
62
    } else if(type == PACKET_TYPE_REDUNDANCY) {
63
64
65
        PrrtPacketRedundancyPayload *payload = packet_ptr->payload;
        printf("| %29u | %13u | %13u |\n", payload->base_seqno, payload->n, payload->k);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
66
    } else if(type == PACKET_TYPE_FEEDBACK) {
67
        PrrtPacketFeedbackPayload *payload = packet_ptr->payload;
68
69
70
71
72
73
74

        struct sockaddr_in receiver;
        receiver.sin_addr.s_addr = payload->receiver_addr;
        char* address = inet_ntoa(receiver.sin_addr);

        printf("| %61s |\n", address);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
75
        printf("| %61u |\n", payload->group_round_trip_time);
76
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
77
        printf("| %61u |\n", payload->forward_trip_time);
78
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
79
        printf("| %61u |\n", payload->packet_loss_rate);
80
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
81
        printf("| %29u | %29u |\n", payload->gap, payload->ngap);
82
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
83
        printf("| %29u | %29u |\n", payload->burst, payload->nburst);
84
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
85
        printf("| %61u |\n", payload->bandwidth_estimate);
86
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
87
88
        printf("| %61u |\n", payload->buffer_feedback);
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
89
    } else {
90
91
        printf("| Unhandeled Type                                               |\n");
        printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
92
93
94
95
96
    }

    return 0;
}

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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:
115
    PERROR("Not enough memory for packet copies.%s", "");
Andreas Schmidt's avatar
Andreas Schmidt committed
116
    return NULL;
117
118
}

Andreas Schmidt's avatar
Andreas Schmidt committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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", "");
Andreas Schmidt's avatar
Andreas Schmidt committed
134
    return NULL;
Andreas Schmidt's avatar
Andreas Schmidt committed
135
136
}

137
bool PrrtPacket_encode(void *buf_ptr, uint16_t buf_size, PrrtPacket *packet_ptr)
138
{
139
    void *payload = packet_ptr->payload;
140

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

143
144
    buf_ptr = encode_general_header(buf_ptr, packet_ptr);

145
    uint8_t type = PrrtPacket_type(packet_ptr);
146
    if(type == PACKET_TYPE_DATA) {
147
        buf_ptr = encode_data_header(buf_ptr, payload);
148
        PrrtPacket_copy_payload_to_buffer(buf_ptr, packet_ptr, PRRT_PACKET_DATA_HEADER_SIZE);
149
    } else if(type == PACKET_TYPE_REDUNDANCY) {
150
        buf_ptr = encode_redundancy_header(buf_ptr, payload);
151
        PrrtPacket_copy_payload_to_buffer(buf_ptr, packet_ptr, PRRT_PACKET_REDUNDANCY_HEADER_SIZE);
152
    } else if(type == PACKET_TYPE_FEEDBACK) {
153
        encode_feedback_header(buf_ptr, payload);
154
155
    } else {
        perror("NOT IMPLEMENTED");
156
        return false;
157
    }
158
    return true;
159
160

    error:
161
    return false;
162
163
}

164
165
void *encode_redundancy_header(void *buf_ptr, const void *payload)
{
166
    const PrrtPacketRedundancyPayload *redundancyPayload = payload;
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

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

183
184
void *encode_feedback_header(void *buf_ptr, const void *payload)
{
185
    const PrrtPacketFeedbackPayload *feedbackPayload = payload;
186
187

    uint32_t *receiver_ip = (uint32_t *) buf_ptr;
188
    *receiver_ip = feedbackPayload->receiver_addr;
189
190
191
    buf_ptr += 4;

    uint32_t *group_round_trip_time = (uint32_t *) buf_ptr;
192
193
    *group_round_trip_time = htonl(feedbackPayload->group_round_trip_time);
    buf_ptr += 4;
194
195

    uint32_t *forward_trip_time = (uint32_t *) buf_ptr;
196
197
    *forward_trip_time = htonl(feedbackPayload->forward_trip_time);
    buf_ptr += 4;
198
199

    uint32_t *packet_loss_rate = (uint32_t *) buf_ptr;
200
201
    *packet_loss_rate = htonl(feedbackPayload->packet_loss_rate);
    buf_ptr += 4;
202
203

    uint16_t *gap = (uint16_t *) buf_ptr;
204
205
    *gap = htons(feedbackPayload->gap);
    buf_ptr += 2;
206
207

    uint16_t *ngap = (uint16_t *) buf_ptr;
208
209
    *ngap = htons(feedbackPayload->ngap);
    buf_ptr += 2;
210
211

    uint16_t *burst = (uint16_t *) buf_ptr;
212
213
    *burst = htons(feedbackPayload->burst);
    buf_ptr += 2;
214
215

    uint16_t *nburst = (uint16_t *) buf_ptr;
216
217
    *nburst = htons(feedbackPayload->nburst);
    buf_ptr += 2;
218
219

    uint32_t *bandwidth_estimate = (uint32_t *) buf_ptr;
220
221
    *bandwidth_estimate = htonl(feedbackPayload->bandwidth_estimate);
    buf_ptr += 4;
222
223

    uint32_t *buffer_feedback = (uint32_t *) buf_ptr;
224
225
    *buffer_feedback = htonl(feedbackPayload->buffer_feedback);
    buf_ptr += 4;
226
227
228
229

    return buf_ptr;
}

230
231
void *encode_data_header(void *buf_ptr, const void *payload)
{
232
    const PrrtPacketDataPayload *data_payload = payload;
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255

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

256
257
void *encode_general_header(void *buf_ptr, const PrrtPacket *packet)
{
258
    uint8_t *type_priority = (uint8_t *) buf_ptr;
259
260
    *type_priority = packet->type_priority;
    buf_ptr += 1;
261

262
    uint8_t *index = (uint8_t *) buf_ptr;
263
264
    *index = packet->index;
    buf_ptr += 1;
265

266
    uint16_t *seqno = (uint16_t *) buf_ptr;
267
268
    *seqno = htons(packet->seqno);
    buf_ptr += 2;
269

270
    return buf_ptr;
271
272
}

273
bool PrrtPacket_decode(void *srcBuffer, uint16_t srcBufferSize, PrrtPacket *targetPacket)
274
{
Andreas Schmidt's avatar
Andreas Schmidt committed
275
276
277
278
279
280
281
282
283
    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;
284

Andreas Schmidt's avatar
Andreas Schmidt committed
285
    void *payload_buffer = calloc(1, payload_len);
286
287
    check_mem(payload_buffer);

Andreas Schmidt's avatar
Andreas Schmidt committed
288
289
290
    targetPacket->payload = payload_buffer;
    targetPacket->payload_len = payload_len;

291
292
    uint8_t packetType = PrrtPacket_type(targetPacket);
    if(packetType == PACKET_TYPE_DATA) {
Andreas Schmidt's avatar
Andreas Schmidt committed
293
294
        srcBuffer = decode_data_header(srcBuffer, payload_buffer);
        PrrtPacket_copy_buffer_to_payload(targetPacket, srcBuffer, PRRT_PACKET_DATA_HEADER_SIZE);
295
    } else if(packetType == PACKET_TYPE_REDUNDANCY) {
Andreas Schmidt's avatar
Andreas Schmidt committed
296
297
        srcBuffer = decode_redundancy_header(srcBuffer, payload_buffer);
        PrrtPacket_copy_buffer_to_payload(targetPacket, srcBuffer, PRRT_PACKET_REDUNDANCY_HEADER_SIZE);
298
299
    } else if(packetType == PACKET_TYPE_FEEDBACK) {
        decode_feedback_header(srcBuffer, payload_buffer);
Andreas Schmidt's avatar
Andreas Schmidt committed
300
    } else {
301
        printf("NOT IMPLEMENTED\n");
Andreas Schmidt's avatar
Andreas Schmidt committed
302
    }
303
    return true;
304
305

    error:
306
    return false;
Andreas Schmidt's avatar
Andreas Schmidt committed
307
}
308

Andreas Schmidt's avatar
Andreas Schmidt committed
309
void *decode_redundancy_header(void *dstBuffer, const void *srcBuffer)
310
{
Andreas Schmidt's avatar
Andreas Schmidt committed
311
    PrrtPacketRedundancyPayload *redundancyPayload = (PrrtPacketRedundancyPayload *) srcBuffer;
312

Andreas Schmidt's avatar
Andreas Schmidt committed
313
    uint16_t *baseSeqNo = (uint16_t *) dstBuffer;
314
    redundancyPayload->base_seqno = ntohs(*baseSeqNo);
Andreas Schmidt's avatar
Andreas Schmidt committed
315
    dstBuffer += 2;
316

Andreas Schmidt's avatar
Andreas Schmidt committed
317
    uint8_t *n = (uint8_t *) dstBuffer;
318
    redundancyPayload->n = *n;
Andreas Schmidt's avatar
Andreas Schmidt committed
319
    dstBuffer += 1;
320

Andreas Schmidt's avatar
Andreas Schmidt committed
321
    uint8_t *k = (uint8_t *) dstBuffer;
322
    redundancyPayload->k = *k;
Andreas Schmidt's avatar
Andreas Schmidt committed
323
    dstBuffer += 1;
324

Andreas Schmidt's avatar
Andreas Schmidt committed
325
    return dstBuffer;
326
327
}

Andreas Schmidt's avatar
Andreas Schmidt committed
328
void *decode_feedback_header(void *dstBuffer, const void *srcBuffer)
329
{
Andreas Schmidt's avatar
Andreas Schmidt committed
330
    PrrtPacketFeedbackPayload *feedback_payload = (PrrtPacketFeedbackPayload *) srcBuffer;
331

Andreas Schmidt's avatar
Andreas Schmidt committed
332
    uint32_t *receiverAddr = (uint32_t *) dstBuffer;
333
    feedback_payload->receiver_addr = *receiverAddr;
Andreas Schmidt's avatar
Andreas Schmidt committed
334
    dstBuffer += 4;
335

Andreas Schmidt's avatar
Andreas Schmidt committed
336
337
338
    uint32_t *groupRoundTripTime = (uint32_t *) dstBuffer;
    feedback_payload->group_round_trip_time = ntohl(*groupRoundTripTime);
    dstBuffer += 4;
339

Andreas Schmidt's avatar
Andreas Schmidt committed
340
341
342
    uint32_t *forwardTripTime = (uint32_t *) dstBuffer;
    feedback_payload->forward_trip_time = ntohl(*forwardTripTime);
    dstBuffer += 4;
343

Andreas Schmidt's avatar
Andreas Schmidt committed
344
345
346
    uint32_t *packetLossRate = (uint32_t *) dstBuffer;
    feedback_payload->packet_loss_rate = ntohl(*packetLossRate);
    dstBuffer += 4;
347

Andreas Schmidt's avatar
Andreas Schmidt committed
348
    uint16_t *gap = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
349
    feedback_payload->gap = ntohs(*gap);
Andreas Schmidt's avatar
Andreas Schmidt committed
350
    dstBuffer += 2;
351

Andreas Schmidt's avatar
Andreas Schmidt committed
352
    uint16_t *ngap = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
353
    feedback_payload->ngap = ntohs(*ngap);
Andreas Schmidt's avatar
Andreas Schmidt committed
354
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
355

Andreas Schmidt's avatar
Andreas Schmidt committed
356
    uint16_t *burst = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
357
    feedback_payload->burst = ntohs(*burst);
Andreas Schmidt's avatar
Andreas Schmidt committed
358
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
359

Andreas Schmidt's avatar
Andreas Schmidt committed
360
    uint16_t *nburst = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
361
    feedback_payload->nburst = ntohs(*nburst);
Andreas Schmidt's avatar
Andreas Schmidt committed
362
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
363

Andreas Schmidt's avatar
Andreas Schmidt committed
364
365
366
    uint32_t *bandwidthEstimate = (uint32_t *) dstBuffer;
    feedback_payload->bandwidth_estimate = ntohl(*bandwidthEstimate);
    dstBuffer += 4;
Andreas Schmidt's avatar
Andreas Schmidt committed
367

Andreas Schmidt's avatar
Andreas Schmidt committed
368
369
370
    uint32_t *bufferFeedback = (uint32_t *) dstBuffer;
    feedback_payload->buffer_feedback = ntohl(*bufferFeedback);
    dstBuffer += 4;
Andreas Schmidt's avatar
Andreas Schmidt committed
371

Andreas Schmidt's avatar
Andreas Schmidt committed
372
    return dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
373
374
}

Andreas Schmidt's avatar
Andreas Schmidt committed
375
void *decode_data_header(void *dstBuffer, const void *srcBuffer)
376
{
Andreas Schmidt's avatar
Andreas Schmidt committed
377
    PrrtPacketDataPayload *data_payload = (PrrtPacketDataPayload *) srcBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
378

Andreas Schmidt's avatar
Andreas Schmidt committed
379
    uint32_t *timestamp = (uint32_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
380
    data_payload->timestamp = ntohl(*timestamp);
Andreas Schmidt's avatar
Andreas Schmidt committed
381
    dstBuffer += 4;
Andreas Schmidt's avatar
Andreas Schmidt committed
382

Andreas Schmidt's avatar
Andreas Schmidt committed
383
    uint16_t *group_round_trip_time = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
384
    data_payload->group_round_trip_time = ntohs(*group_round_trip_time);
Andreas Schmidt's avatar
Andreas Schmidt committed
385
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
386

Andreas Schmidt's avatar
Andreas Schmidt committed
387
    uint16_t *packet_timeout = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
388
    data_payload->packet_timeout = ntohs(*packet_timeout);
Andreas Schmidt's avatar
Andreas Schmidt committed
389
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
390

Andreas Schmidt's avatar
Andreas Schmidt committed
391
    uint16_t *decoding_timeout = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
392
    data_payload->decoding_timeout = ntohs(*decoding_timeout);
Andreas Schmidt's avatar
Andreas Schmidt committed
393
    dstBuffer += 2;
Andreas Schmidt's avatar
Andreas Schmidt committed
394

Andreas Schmidt's avatar
Andreas Schmidt committed
395
    uint16_t *feedback_timeout = (uint16_t *) dstBuffer;
Andreas Schmidt's avatar
Andreas Schmidt committed
396
    data_payload->feedback_timeout = ntohs(*feedback_timeout);
Andreas Schmidt's avatar
Andreas Schmidt committed
397
398
    dstBuffer += 2;
    return dstBuffer;
399
400
}

Andreas Schmidt's avatar
Andreas Schmidt committed
401
int PrrtPacket_destroy(PrrtPacket *packet)
402
{
Andreas Schmidt's avatar
Andreas Schmidt committed
403
404
    if(packet->payload != NULL) {
        free(packet->payload);
405
    }
Andreas Schmidt's avatar
Andreas Schmidt committed
406
    free(packet);
407
408
409
    return 0;
}

Andreas Schmidt's avatar
Andreas Schmidt committed
410
411
PrrtPacket *PrrtPacket_create_data_packet(uint8_t priority, const void *payloadPointer, uint32_t payloadLength,
                                          uint16_t sequenceNumber)
412
{
Andreas Schmidt's avatar
Andreas Schmidt committed
413
414
    PrrtPacket *packet = create_header(priority, sequenceNumber,
                                       (uint32_t) (payloadLength + PRRT_PACKET_DATA_HEADER_SIZE), PACKET_TYPE_DATA, 0);
415

Andreas Schmidt's avatar
Andreas Schmidt committed
416
417
418
    PrrtPacketDataPayload *dataPayload = calloc(1, packet->payload_len);
    check_mem(dataPayload);
    packet->payload = dataPayload;
419
420

    struct timeval tv;
421
    gettimeofday(&tv, NULL);
422
423
    unsigned long time_in_micros = (unsigned long) (1000000 * tv.tv_sec + tv.tv_usec);

Andreas Schmidt's avatar
Andreas Schmidt committed
424
425
426
427
428
429
    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)
430

Andreas Schmidt's avatar
Andreas Schmidt committed
431
    return packet;
432

433
    error:
434
    PERROR("Could not create packet.%s","");
Andreas Schmidt's avatar
Andreas Schmidt committed
435
    return NULL;
436
437
}

Andreas Schmidt's avatar
Andreas Schmidt committed
438
439
PrrtPacket *PrrtPacket_create_redundancy_packet(uint8_t priority, void *payloadPointer, uint32_t payloadLength,
                                                uint16_t sequenceNumber, uint8_t index, uint16_t baseSequenceNumber,
440
441
                                                PrrtCodingParams codingParams)
{
Andreas Schmidt's avatar
Andreas Schmidt committed
442
443
444
    PrrtPacket *packet = create_header(priority, sequenceNumber,
                                       (uint32_t) (payloadLength + PRRT_PACKET_REDUNDANCY_HEADER_SIZE),
                                       PACKET_TYPE_REDUNDANCY, index);
445

Andreas Schmidt's avatar
Andreas Schmidt committed
446
447
448
    PrrtPacketRedundancyPayload *redundancyPayload = calloc(1, packet->payload_len);
    check_mem(redundancyPayload);
    packet->payload = redundancyPayload;
449

Andreas Schmidt's avatar
Andreas Schmidt committed
450
451
452
453
    redundancyPayload->base_seqno = baseSequenceNumber;
    redundancyPayload->k = codingParams.k;
    redundancyPayload->n = codingParams.n;
    PrrtPacket_copy_buffer_to_payload(packet, payloadPointer, PRRT_PACKET_REDUNDANCY_HEADER_SIZE);
454

Andreas Schmidt's avatar
Andreas Schmidt committed
455
    return packet;
456
457

    error:
458
    return NULL;
459
460
}

Andreas Schmidt's avatar
Andreas Schmidt committed
461
462
463
464
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)
465
{
Andreas Schmidt's avatar
Andreas Schmidt committed
466
467
468
469
    PrrtPacket *packet = create_header(priority, sequenceNumber, PRRT_PACKET_FEEDBACK_HEADER_SIZE, PACKET_TYPE_FEEDBACK,
                                       index);

    PrrtPacketFeedbackPayload *payload = calloc(1, packet->payload_len);
470
    check_mem(payload);
Andreas Schmidt's avatar
Andreas Schmidt committed
471
    packet->payload = payload;
472

473
    payload->receiver_addr = inet_addr("10.0.0.1");
Andreas Schmidt's avatar
Andreas Schmidt committed
474
475
476
    payload->group_round_trip_time = roundTripTime;
    payload->forward_trip_time = forwardTripTime;
    payload->packet_loss_rate = packetLossRate;
477
478
479
480
    payload->gap = gap;
    payload->ngap = ngap;
    payload->burst = burst;
    payload->nburst = nburst;
481
    payload->bandwidth_estimate = bandwidth;
Andreas Schmidt's avatar
Andreas Schmidt committed
482
    payload->buffer_feedback = bufferFeedback;
483
484


Andreas Schmidt's avatar
Andreas Schmidt committed
485
    return packet;
486
487

    error:
488
    return NULL;
489
}