block.c 5.64 KB
Newer Older
1
#include <string.h>
Andreas Schmidt's avatar
Andreas Schmidt committed
2
3
4
5
#include <src/defines.h>
#include <src/prrt/vdmcode/block_code.h>
#include <stdlib.h>
#include <src/util/list.h>
6
7
#include <src/util/dbg.h>
#include <src/util/common.h>
8
#include "block.h"
9
#include "coding_params.h"
10
11
#include "packet.h"

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void gather_redundancy_packets(const PrrtBlock *block_ptr, gf *const *fec, int *idx_p) {
    int m = block_ptr->data_count;
    LIST_FOREACH(block_ptr->redundancy_blocks, first, next, cur) {
        PrrtPacket* packet = cur->value;
        memcpy(fec[m], packet->payload + PRRT_PACKET_REDUNDANCY_HEADER_SIZE, packet->payload_len - PRRT_PACKET_REDUNDANCY_HEADER_SIZE);
        idx_p[m] = packet->index;
        m++;
    }
}

void gather_data_packets(PrrtBlock *block_ptr, gf *const *fec, int *idx_p) {
    int m = 0;
    uint32_t count = block_ptr->data_count;
    for (m = 0; m < count; ++m) {
        PrrtPacket* packet = List_shift(block_ptr->data_blocks);
        memcpy(fec[m], packet->payload + PRRT_PACKET_DATA_HEADER_SIZE, packet->payload_len - PRRT_PACKET_DATA_HEADER_SIZE);
        idx_p[m] = packet->index;
        m++;
    }
    block_ptr->data_count = 0;
    // TODO: this setting of data count is horrible and should be fixed
}
Andreas Schmidt's avatar
Andreas Schmidt committed
34

35
36
37
38
39
40
void clear_list(gf *const *src, uint8_t k) {
    int j = 0;
    for(j = 0; j < k; j++) {
        free(src[j]);
    }
}
Andreas Schmidt's avatar
Andreas Schmidt committed
41
42
43
44
45

void PrrtBlock_free(PrrtBlock **mblock) {

}

46
int PrrtBlock_alloc(PrrtBlock **mblock, const PrrtCodingParams *cpar, uint16_t base_seqno) {
47
48
    *mblock = calloc(1, sizeof(PrrtBlock));
    check_mem(mblock);
Andreas Schmidt's avatar
Andreas Schmidt committed
49

50
    (*mblock)->coding_params = *cpar;
51
    (*mblock)->data_count = 0;
52
    (*mblock)->data_blocks =List_create();
53
    (*mblock)->redundancy_count = 0;
54
    (*mblock)->redundancy_blocks =List_create();
55
    (*mblock)->base_seqno = base_seqno;
56

Andreas Schmidt's avatar
Andreas Schmidt committed
57
    return 0;
58
59
    error:
        PNOTIMPLEMENTED("TODO");
Andreas Schmidt's avatar
Andreas Schmidt committed
60
}
61

62
int PrrtBlock_insert_data_packet(PrrtBlock *block_ptr, const PrrtPacket *packet_ptr) {
63
    check(block_ptr->data_count < block_ptr->coding_params.k, "Inserting an unnecessary item.");
64
65
66
67
    List_push(block_ptr->data_blocks, packet_ptr);
    block_ptr->data_count++;
    block_ptr->largest_data_length = MAX(block_ptr->largest_data_length, packet_ptr->payload_len - PRRT_PACKET_DATA_HEADER_SIZE);
    return 0;
68
69
70

    error:
        PNOTIMPLEMENTED("HANDLING MISSING");
71
}
72
int PrrtBlock_insert_redundancy_packet(PrrtBlock *block_ptr, const PrrtPacket *ptr) {
73
74
    List_push(block_ptr->redundancy_blocks, ptr);
    block_ptr->redundancy_count++;
75
    block_ptr->largest_data_length = MAX(block_ptr->largest_data_length, ptr->payload_len - PRRT_PACKET_REDUNDANCY_HEADER_SIZE);
76
77
    return 0;
}
78

79
int PrrtBlock_encode_ready(const PrrtBlock *block_ptr) {
80
81
82
    return (block_ptr->data_count == block_ptr->coding_params.k) ? TRUE : FALSE;
}

83
84
85
86
int PrrtBlock_decode_ready(const PrrtBlock *block_ptr) {
    return (block_ptr->data_count + block_ptr->redundancy_count == block_ptr->coding_params.k) ? TRUE : FALSE;
}

87
88
89
90
91
PrrtPacket *PrrtBlock_get_first_data(PrrtBlock *block_ptr) {
    block_ptr->data_count--;
    return List_shift(block_ptr->data_blocks);
}

92
void PrrtBlock_encode(PrrtBlock *block_ptr, uint16_t *seqno) {
93
    int j = 0, m = 0;
94
95
96
    uint8_t k = block_ptr->coding_params.k;
    uint8_t n = block_ptr->coding_params.n;
    uint8_t r = block_ptr->coding_params.r;
97
    uint32_t length = block_ptr->largest_data_length;
98
99
100
101
102

    PrrtCoder* coder = NULL;

    PrrtCoder_get_coder(&coder, n, k);

Andreas Schmidt's avatar
Andreas Schmidt committed
103
    gf** src = calloc(1, sizeof(gf*) * k);
104
105

    LIST_FOREACH(block_ptr->data_blocks, first, next, cur) {
Andreas Schmidt's avatar
Andreas Schmidt committed
106
        src[j] = calloc(1, sizeof(gf) * length);
107
108
        memset(src[j], 0, sizeof(gf) * length);
        PrrtPacket* pkt = cur->value;
109
        pkt->index = (uint8_t) j;
110
        memcpy(src[j], pkt->payload + PRRT_PACKET_DATA_HEADER_SIZE, pkt->payload_len - PRRT_PACKET_DATA_HEADER_SIZE);
111
112
113
        j++;
    }

114
115
    PrrtPacket *first_packet = (PrrtPacket*) block_ptr->data_blocks->first->value;
    uint16_t base_seqno = first_packet->seqno;
116

Andreas Schmidt's avatar
Andreas Schmidt committed
117
    gf** fec = calloc(1, sizeof(gf*) * r);
118
    for(j = 0; j < r; j++) {
Andreas Schmidt's avatar
Andreas Schmidt committed
119
        fec[j] = calloc(1, sizeof(gf) * length);
120
        memset(fec[j], 0, sizeof(gf) * length);
121
        PrrtCoder_encode(coder, src, fec[j], j+k, length); // gf **src, gf *fec, int index, int sz
122
123
        PrrtPacket* red_packet_ptr = PrrtPacket_create_redundancy_packet(0, (void*) fec[j], length, *seqno,
                                                                         (uint8_t) (k + j), base_seqno, block_ptr->coding_params);
124
        *seqno = (uint16_t) (*seqno + 1 % SEQNO_SPACE);
125
126
        PrrtBlock_insert_redundancy_packet(block_ptr, red_packet_ptr);
    }
127

128
129
    block_ptr->is_coded = TRUE;

130
131
132
    clear_list(fec, r);
    free(fec);

133
134
    clear_list(src, k);
    free(src);
135
136
}

137
void PrrtBlock_decode(PrrtBlock *block_ptr) {
138
    int i, j;
139
140
141
142
143
144
145
146
147
    uint8_t n = block_ptr->coding_params.n;
    uint8_t k = block_ptr->coding_params.k;

    uint32_t length = block_ptr->largest_data_length;

    PrrtCoder* coder = NULL;

    PrrtCoder_get_coder(&coder, n, k);

Andreas Schmidt's avatar
Andreas Schmidt committed
148
    gf** fec = calloc(n, sizeof(gf*));
149
150
151
152
    for (i = 0; i < n; i++) {
        fec[i] = calloc(block_ptr->largest_data_length, sizeof(gf));
    }

Andreas Schmidt's avatar
Andreas Schmidt committed
153
    int *idx_p = calloc(k,sizeof(int));
154

155
    gather_redundancy_packets(block_ptr, fec, idx_p);
156
    gather_data_packets(block_ptr, fec, idx_p);
157
158

    PrrtCoder_decode(coder, fec, idx_p, length);
159

160
    for(j = 0; j < k; j++) {
161
        PrrtPacket *packet = calloc(1, sizeof(PrrtPacket));
162
        PrrtPacket_create_data_packet(packet, 0, fec[j], length, block_ptr->base_seqno + j);
163
        PrrtBlock_insert_data_packet(block_ptr, packet);
164
165
166
167
168
169
170
    }

    clear_list(fec, n);
    free(fec);
    free(idx_p);
}

171
172
173
PrrtPacket *PrrtBlock_get_first_red_data(PrrtBlock *block_ptr) {
    block_ptr->redundancy_count--;
    return List_shift(block_ptr->redundancy_blocks);
174
}