packet.c 16.7 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
#include "clock.h"
12

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return 0;
}

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

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

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

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

144
145
    buf_ptr = encode_general_header(buf_ptr, packet_ptr);

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

    error:
162
    return false;
163
164
}

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

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

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

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

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

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

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

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

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

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

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

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

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

    return buf_ptr;
}

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

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

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

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

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

271
    return buf_ptr;
272
273
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

421
    dataPayload->timestamp = PrrtClock_get_current_time();
Andreas Schmidt's avatar
Andreas Schmidt committed
422
423
424
425
426
    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)
427

Andreas Schmidt's avatar
Andreas Schmidt committed
428
    return packet;
429

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

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

Andreas Schmidt's avatar
Andreas Schmidt committed
443
444
445
    PrrtPacketRedundancyPayload *redundancyPayload = calloc(1, packet->payload_len);
    check_mem(redundancyPayload);
    packet->payload = redundancyPayload;
446

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

Andreas Schmidt's avatar
Andreas Schmidt committed
452
    return packet;
453
454

    error:
455
    return NULL;
456
457
}

Andreas Schmidt's avatar
Andreas Schmidt committed
458
PrrtPacket *PrrtPacket_create_feedback_packet(uint8_t priority, uint8_t index, uint16_t sequenceNumber,
459
460
461
                                              uint32_t roundTripTime, uint32_t packetLossRate, uint16_t gap,
                                              uint16_t ngap, uint16_t burst, uint16_t nburst, uint32_t bandwidth,
                                              uint32_t bufferFeedback)
462
{
Andreas Schmidt's avatar
Andreas Schmidt committed
463
464
465
466
    PrrtPacket *packet = create_header(priority, sequenceNumber, PRRT_PACKET_FEEDBACK_HEADER_SIZE, PACKET_TYPE_FEEDBACK,
                                       index);

    PrrtPacketFeedbackPayload *payload = calloc(1, packet->payload_len);
467
    check_mem(payload);
Andreas Schmidt's avatar
Andreas Schmidt committed
468
    packet->payload = payload;
469

470
    payload->receiver_addr = inet_addr("10.0.0.1");
Andreas Schmidt's avatar
Andreas Schmidt committed
471
    payload->group_round_trip_time = roundTripTime;
472
    payload->forward_trip_timestamp = 0;
Andreas Schmidt's avatar
Andreas Schmidt committed
473
    payload->packet_loss_rate = packetLossRate;
474
475
476
477
    payload->gap = gap;
    payload->ngap = ngap;
    payload->burst = burst;
    payload->nburst = nburst;
478
    payload->bandwidth_estimate = bandwidth;
Andreas Schmidt's avatar
Andreas Schmidt committed
479
    payload->buffer_feedback = bufferFeedback;
480
481


Andreas Schmidt's avatar
Andreas Schmidt committed
482
    return packet;
483
484

    error:
485
    return NULL;
486
}