rlc_um_segment.c 42.4 KB
Newer Older
1
/*******************************************************************************
gauthier's avatar
gauthier committed
2
3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

gauthier's avatar
gauthier committed
5
6
7
8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9
10


gauthier's avatar
gauthier committed
11
12
13
14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

gauthier's avatar
gauthier committed
16
17
18
19
    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
   see <http://www.gnu.org/licenses/>.
20

gauthier's avatar
gauthier committed
21
22
23
24
25
  Contact Information
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
gauthier's avatar
gauthier committed
27
28

 *******************************************************************************/
29
30
31
32
33
34
35
36
37
#define RLC_UM_MODULE
#define RLC_UM_SEGMENT_C
//-----------------------------------------------------------------------------
#include "platform_types.h"
#include "platform_constants.h"
//-----------------------------------------------------------------------------
#ifdef USER_MODE
#include <assert.h>
#endif
38
#include "assertions.h"
39
40
41
42
43
44
#include "list.h"
#include "rlc_um.h"
#include "rlc_primitives.h"
#include "MAC_INTERFACE/extern.h"
#include "UTIL/LOG/log.h"

gauthier's avatar
gauthier committed
45
//#define TRACE_RLC_UM_SEGMENT 1
46
47
//-----------------------------------------------------------------------------
void
48
rlc_um_segment_10 (rlc_um_entity_t *rlc_pP,frame_t frameP)
49
50
51
52
53
54
{
//-----------------------------------------------------------------------------
    list_t              pdus;
    signed int          pdu_remaining_size;
    signed int          test_pdu_remaining_size;

gauthier's avatar
gauthier committed
55
56
57
58
    int                 nb_bytes_to_transmit = rlc_pP->nb_bytes_requested_by_mac;
    rlc_um_pdu_sn_10_t *pdu_p;
    struct mac_tb_req  *pdu_tb_req_p;
    mem_block_t        *pdu_mem_p;
59
    char               *data;
gauthier's avatar
gauthier committed
60
61
62
    char               *data_sdu_p;
    rlc_um_e_li_t      *e_li_p;
    struct rlc_um_tx_sdu_management *sdu_mngt_p;
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
    unsigned int       li_length_in_bytes;
    unsigned int       test_li_length_in_bytes;
    unsigned int       test_remaining_size_to_substract;
    unsigned int       test_remaining_num_li_to_substract;
    unsigned int       continue_fill_pdu_with_sdu;
    unsigned int       num_fill_sdu;
    unsigned int       test_num_li;
    unsigned int       fill_num_li;
    unsigned int       sdu_buffer_index;
    unsigned int       data_pdu_size;

    unsigned int       fi_first_byte_pdu_is_first_byte_sdu;
    unsigned int       fi_last_byte_pdu_is_last_byte_sdu;
    unsigned int       fi;
    unsigned int       max_li_overhead;

    if (nb_bytes_to_transmit < 3) {
gauthier's avatar
gauthier committed
80
81
82
83
84
85
86
87
88
#if defined(TRACE_RLC_UM_SEGMENT)
        LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] NO SEGMENTATION nb_bytes to transmit = %d\n",
                frameP,
                (rlc_pP->is_enb) ? "eNB" : "UE",
                rlc_pP->enb_module_id,
                rlc_pP->ue_module_id,
                rlc_pP->rb_id,
                nb_bytes_to_transmit);
#endif
89
90
        return;
    }
gauthier's avatar
gauthier committed
91
#if defined(TRACE_RLC_UM_SEGMENT)
92
93
94
95
96
97
    LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10\n",
          frameP,
          (rlc_pP->is_enb) ? "eNB" : "UE",
          rlc_pP->enb_module_id,
          rlc_pP->ue_module_id,
          rlc_pP->rb_id);
gauthier's avatar
gauthier committed
98
#endif
99
    list_init (&pdus, NULL);    // param string identifying the list is NULL
gauthier's avatar
gauthier committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    pdu_mem_p = NULL;

    while ((rlc_pP->input_sdus[rlc_pP->current_sdu_index]) && (nb_bytes_to_transmit > 0)) {
#if defined(TRACE_RLC_UM_SEGMENT)
        LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 nb_bytes_to_transmit %d BO %d\n",
                frameP,
                (rlc_pP->is_enb) ? "eNB" : "UE",
                rlc_pP->enb_module_id,
                rlc_pP->ue_module_id,
                rlc_pP->rb_id,
                nb_bytes_to_transmit,
                rlc_pP->buffer_occupancy);
#endif
        // pdu_p management
        if (!pdu_mem_p) {
            if (rlc_pP->nb_sdu <= 1) {
116
117
                max_li_overhead = 0;
            } else {
gauthier's avatar
gauthier committed
118
                max_li_overhead = (((rlc_pP->nb_sdu - 1) * 3) / 2) + ((rlc_pP->nb_sdu - 1) % 2);
119
            }
gauthier's avatar
gauthier committed
120
121
122
123
124
125
126
127
128
129
130
            if  (nb_bytes_to_transmit >= (rlc_pP->buffer_occupancy + rlc_pP->tx_header_min_length_in_bytes + max_li_overhead)) {
                data_pdu_size = rlc_pP->buffer_occupancy + rlc_pP->tx_header_min_length_in_bytes + max_li_overhead;
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 alloc PDU size %d bytes to contain not all bytes requested by MAC but all BO of RLC@1\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        data_pdu_size);
#endif
131
132
            } else {
                data_pdu_size = nb_bytes_to_transmit;
gauthier's avatar
gauthier committed
133
134
135
136
137
138
139
140
141
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 alloc PDU size %d bytes to contain all bytes requested by MAC@1\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        data_pdu_size);
#endif
142
            }
gauthier's avatar
gauthier committed
143
144
145
146
147
148
149
150
151
            if (!(pdu_mem_p = get_free_mem_block (data_pdu_size + sizeof(struct mac_tb_req)))) {
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_E(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 ERROR COULD NOT GET NEW PDU, EXIT\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id);
#endif
152
153
                return;
            }
gauthier's avatar
gauthier committed
154
155
156
157
158
159
160
161
162
#if defined(TRACE_RLC_UM_SEGMENT)
            LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 get new PDU %d bytes\n",
                    frameP,
                    (rlc_pP->is_enb) ? "eNB" : "UE",
                    rlc_pP->enb_module_id,
                    rlc_pP->ue_module_id,
                    rlc_pP->rb_id,
                    data_pdu_size);
#endif
163
            pdu_remaining_size = data_pdu_size - 2;
gauthier's avatar
gauthier committed
164
165
            pdu_p        = (rlc_um_pdu_sn_10_t*) (&pdu_mem_p->data[sizeof(struct mac_tb_req)]);
            pdu_tb_req_p = (struct mac_tb_req*) (pdu_mem_p->data);
166

gauthier's avatar
gauthier committed
167
            memset (pdu_mem_p->data, 0, sizeof (rlc_um_pdu_sn_10_t)+sizeof(struct mac_tb_req));
168
169
170
171
172
173
174
175
            li_length_in_bytes = 1;
        }
        //----------------------------------------
        // compute how many SDUS can fill the PDU
        //----------------------------------------
        continue_fill_pdu_with_sdu = 1;
        num_fill_sdu               = 0;
        test_num_li                = 0;
gauthier's avatar
gauthier committed
176
        sdu_buffer_index           = rlc_pP->current_sdu_index;
177
178
179
180
181
182
        test_pdu_remaining_size    = pdu_remaining_size;
        test_li_length_in_bytes    = 1;
        test_remaining_size_to_substract   = 0;
        test_remaining_num_li_to_substract = 0;


gauthier's avatar
gauthier committed
183
184
        while ((rlc_pP->input_sdus[sdu_buffer_index]) && (continue_fill_pdu_with_sdu > 0)) {
            sdu_mngt_p = ((struct rlc_um_tx_sdu_management *) (rlc_pP->input_sdus[sdu_buffer_index]->data));
185

gauthier's avatar
gauthier committed
186
            if (sdu_mngt_p->sdu_remaining_size > test_pdu_remaining_size) {
187
188
189
190
191
192
                // no LI
                continue_fill_pdu_with_sdu = 0;
                num_fill_sdu += 1;
                test_pdu_remaining_size = 0;
                test_remaining_size_to_substract = 0;
                test_remaining_num_li_to_substract = 0;
gauthier's avatar
gauthier committed
193
            } else if (sdu_mngt_p->sdu_remaining_size == test_pdu_remaining_size) {
194
195
196
197
198
199
                // fi will indicate end of PDU is end of SDU, no need for LI
                continue_fill_pdu_with_sdu = 0;
                num_fill_sdu += 1;
                test_pdu_remaining_size = 0;
                test_remaining_size_to_substract = 0;
                test_remaining_num_li_to_substract = 0;
gauthier's avatar
gauthier committed
200
            } else if ((sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3)) == test_pdu_remaining_size ) {
201
202
203
204
205
206
207
                // no LI
                continue_fill_pdu_with_sdu = 0;
                num_fill_sdu += 1;
                test_pdu_remaining_size = 0;
                test_remaining_size_to_substract = 0;
                test_remaining_num_li_to_substract = 0;
                pdu_remaining_size = pdu_remaining_size - (test_li_length_in_bytes ^ 3);
gauthier's avatar
gauthier committed
208
            } else if ((sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3)) < test_pdu_remaining_size ) {
209
210
                test_num_li += 1;
                num_fill_sdu += 1;
gauthier's avatar
gauthier committed
211
                test_pdu_remaining_size = test_pdu_remaining_size - (sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3));
212
213
214
215
                test_remaining_size_to_substract = test_li_length_in_bytes ^ 3;
                test_remaining_num_li_to_substract = 1;
                test_li_length_in_bytes = test_li_length_in_bytes ^ 3;
            } else {
gauthier's avatar
gauthier committed
216
217
218
219
220
221
222
223
224
225
226
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 sdu_mngt_p->sdu_remaining_size=%d test_pdu_remaining_size=%d test_li_length_in_bytes=%d\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        sdu_mngt_p->sdu_remaining_size,
                        test_pdu_remaining_size,
                        test_li_length_in_bytes ^ 3);
#endif
227
228
229
230
231
232
233
234
                // reduce the size of the PDU
                continue_fill_pdu_with_sdu = 0;
                num_fill_sdu += 1;
                test_pdu_remaining_size = 0;
                test_remaining_size_to_substract = 0;
                test_remaining_num_li_to_substract = 0;
                pdu_remaining_size = pdu_remaining_size - 1;
            }
gauthier's avatar
gauthier committed
235
            sdu_buffer_index = (sdu_buffer_index + 1) % rlc_pP->size_input_sdus_buffer;
236
237
238
239
240
241
242
        }
        if (test_remaining_num_li_to_substract > 0) {
            // there is a LI that is not necessary
            test_num_li = test_num_li - 1;
            pdu_remaining_size = pdu_remaining_size - test_remaining_size_to_substract;
        }
        //----------------------------------------
gauthier's avatar
gauthier committed
243
        // Do the real filling of the pdu_p
244
        //----------------------------------------
gauthier's avatar
gauthier committed
245
246
247
248
249
250
251
252
253
254
#if defined(TRACE_RLC_UM_SEGMENT)
        LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] data shift %d Bytes num_li %d\n",
                frameP,
                (rlc_pP->is_enb) ? "eNB" : "UE",
                rlc_pP->enb_module_id,
                rlc_pP->ue_module_id,
                rlc_pP->rb_id,
                ((test_num_li*3) +1) >> 1,
                test_num_li);
#endif
255

gauthier's avatar
gauthier committed
256
257
        data = ((char*)(&pdu_p->data[((test_num_li*3) +1) >> 1]));
        e_li_p = (rlc_um_e_li_t*)(pdu_p->data);
258
259
260
261
262
263
264
        continue_fill_pdu_with_sdu          = 1;
        li_length_in_bytes                  = 1;
        fill_num_li                         = 0;
        fi_first_byte_pdu_is_first_byte_sdu = 0;
        fi_last_byte_pdu_is_last_byte_sdu   = 0;

        if (
gauthier's avatar
gauthier committed
265
266
            ((struct rlc_um_tx_sdu_management *) (rlc_pP->input_sdus[rlc_pP->current_sdu_index]->data))->sdu_remaining_size ==
            ((struct rlc_um_tx_sdu_management *) (rlc_pP->input_sdus[rlc_pP->current_sdu_index]->data))->sdu_size) {
267
268
            fi_first_byte_pdu_is_first_byte_sdu = 1;
        }
gauthier's avatar
gauthier committed
269
270
271
272
273
274
275
276
277
278
279
280
281
        while ((rlc_pP->input_sdus[rlc_pP->current_sdu_index]) && (continue_fill_pdu_with_sdu > 0)) {
            sdu_mngt_p = ((struct rlc_um_tx_sdu_management *) (rlc_pP->input_sdus[rlc_pP->current_sdu_index]->data));
            if (sdu_mngt_p->sdu_segmented_size == 0) {
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 GET NEW SDU %p AVAILABLE SIZE %d Bytes\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        sdu_mngt_p,
                        sdu_mngt_p->sdu_remaining_size);
#endif
282
            } else {
gauthier's avatar
gauthier committed
283
284
285
286
287
288
289
290
291
292
293
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 GET AGAIN SDU %p REMAINING AVAILABLE SIZE %d Bytes / %d Bytes \n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        sdu_mngt_p,
                        sdu_mngt_p->sdu_remaining_size,
                        sdu_mngt_p->sdu_size);
#endif
294
            }
gauthier's avatar
gauthier committed
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
            data_sdu_p = &((rlc_pP->input_sdus[rlc_pP->current_sdu_index])->data[sizeof (struct rlc_um_tx_sdu_management) + sdu_mngt_p->sdu_segmented_size]);

            if (sdu_mngt_p->sdu_remaining_size > pdu_remaining_size) {
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 Filling all remaining PDU with %d bytes\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        pdu_remaining_size);
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 pdu_mem_p %p pdu_mem_p->data %p pdu_p %p pdu_p->data %p data %p data_sdu_p %p pdu_remaining_size %d\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        pdu_mem_p,
                        pdu_mem_p->data,
                        pdu_p,
                        pdu_p->data,
                        data,
                        data_sdu_p,
                        pdu_remaining_size);
#endif

                memcpy(data, data_sdu_p, pdu_remaining_size);
                sdu_mngt_p->sdu_remaining_size = sdu_mngt_p->sdu_remaining_size - pdu_remaining_size;
                sdu_mngt_p->sdu_segmented_size = sdu_mngt_p->sdu_segmented_size + pdu_remaining_size;
324
325
                fi_last_byte_pdu_is_last_byte_sdu = 0;
                // no LI
gauthier's avatar
gauthier committed
326
                rlc_pP->buffer_occupancy -= pdu_remaining_size;
327
328
                continue_fill_pdu_with_sdu = 0;
                pdu_remaining_size = 0;
gauthier's avatar
gauthier committed
329
330
331
332
333
334
335
336
337
338
339
            } else if (sdu_mngt_p->sdu_remaining_size == pdu_remaining_size) {
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 Exactly Filling remaining PDU with %d remaining bytes of SDU\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        pdu_remaining_size);
#endif
                memcpy(data, data_sdu_p, pdu_remaining_size);
340
341

                // free SDU
gauthier's avatar
gauthier committed
342
343
344
345
346
                rlc_pP->buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
                free_mem_block (rlc_pP->input_sdus[rlc_pP->current_sdu_index]);
                rlc_pP->input_sdus[rlc_pP->current_sdu_index] = NULL;
                rlc_pP->nb_sdu -= 1;
                rlc_pP->current_sdu_index = (rlc_pP->current_sdu_index + 1) % rlc_pP->size_input_sdus_buffer;
347
348
349
350
351

                fi_last_byte_pdu_is_last_byte_sdu = 1;
                // fi will indicate end of PDU is end of SDU, no need for LI
                continue_fill_pdu_with_sdu = 0;
                pdu_remaining_size = 0;
gauthier's avatar
gauthier committed
352
353
354
355
356
357
358
359
360
361
362
363
            } else if ((sdu_mngt_p->sdu_remaining_size + (li_length_in_bytes ^ 3)) < pdu_remaining_size ) {
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 Filling  PDU with %d all remaining bytes of SDU\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        sdu_mngt_p->sdu_remaining_size);
#endif
                memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
                data = &data[sdu_mngt_p->sdu_remaining_size];
364
365
366
367
                li_length_in_bytes = li_length_in_bytes ^ 3;
                fill_num_li += 1;
                if (li_length_in_bytes  == 2) {
                    if (fill_num_li == test_num_li) {
gauthier's avatar
gauthier committed
368
369
                        //e_li_p->e1  = 0;
                        e_li_p->b1 = 0;
370
                    } else {
gauthier's avatar
gauthier committed
371
372
                        //e_li_p->e1  = 1;
                        e_li_p->b1 =  0x80;
373
                    }
gauthier's avatar
gauthier committed
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
                    //e_li_p->li1 = sdu_mngt_p->sdu_remaining_size;
                    e_li_p->b1 = e_li_p->b1 | (sdu_mngt_p->sdu_remaining_size >> 4);
                    e_li_p->b2 = sdu_mngt_p->sdu_remaining_size << 4;
#if defined(TRACE_RLC_UM_SEGMENT)
                    LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 set e_li_p->b1=%02X set e_li_p->b2=%02X fill_num_li=%d test_num_li=%d\n",
                            frameP,
                            (rlc_pP->is_enb) ? "eNB" : "UE",
                            rlc_pP->enb_module_id,
                            rlc_pP->ue_module_id,
                            rlc_pP->rb_id,
                            e_li_p->b1,
                            e_li_p->b2,
                            fill_num_li,
                            test_num_li);
#endif
389
390
                } else {
                    if (fill_num_li != test_num_li) {
gauthier's avatar
gauthier committed
391
392
                        //e_li_p->e2  = 1;
                        e_li_p->b2  = e_li_p->b2 | 0x08;
393
                    }
gauthier's avatar
gauthier committed
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
                    //e_li_p->li2 = sdu_mngt_p->sdu_remaining_size;
                    e_li_p->b2 = e_li_p->b2 | (sdu_mngt_p->sdu_remaining_size >> 8);
                    e_li_p->b3 = sdu_mngt_p->sdu_remaining_size & 0xFF;
#if defined(TRACE_RLC_UM_SEGMENT)
                    LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 set e_li_p->b2=%02X set e_li_p->b3=%02X fill_num_li=%d test_num_li=%d\n",
                            frameP,
                            (rlc_pP->is_enb) ? "eNB" : "UE",
                            rlc_pP->enb_module_id,
                            rlc_pP->ue_module_id,
                            rlc_pP->rb_id,
                            e_li_p->b2,
                            e_li_p->b3,
                            fill_num_li,
                            test_num_li);
#endif
                    e_li_p++;
410
411
412
                }

                // free SDU
gauthier's avatar
gauthier committed
413
414
415
416
417
                rlc_pP->buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
                free_mem_block (rlc_pP->input_sdus[rlc_pP->current_sdu_index]);
                rlc_pP->input_sdus[rlc_pP->current_sdu_index] = NULL;
                rlc_pP->nb_sdu -= 1;
                rlc_pP->current_sdu_index = (rlc_pP->current_sdu_index + 1) % rlc_pP->size_input_sdus_buffer;
418

gauthier's avatar
gauthier committed
419
                pdu_remaining_size = pdu_remaining_size - (sdu_mngt_p->sdu_remaining_size + li_length_in_bytes);
420
            } else {
gauthier's avatar
gauthier committed
421
422
423
424
425
426
427
428
429
430
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT10 Filling  PDU with %d all remaining bytes of SDU and reduce TB size by %d bytes\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        sdu_mngt_p->sdu_remaining_size,
                        pdu_remaining_size - sdu_mngt_p->sdu_remaining_size);
#endif
431
432
433
#ifdef USER_MODE
                assert(1!=1);
#endif
gauthier's avatar
gauthier committed
434
                memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
435
                // free SDU
gauthier's avatar
gauthier committed
436
437
438
439
440
                rlc_pP->buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
                free_mem_block (rlc_pP->input_sdus[rlc_pP->current_sdu_index]);
                rlc_pP->input_sdus[rlc_pP->current_sdu_index] = NULL;
                rlc_pP->nb_sdu -= 1;
                rlc_pP->current_sdu_index = (rlc_pP->current_sdu_index + 1) % rlc_pP->size_input_sdus_buffer;
441
442
443
444

                // reduce the size of the PDU
                continue_fill_pdu_with_sdu = 0;
                fi_last_byte_pdu_is_last_byte_sdu = 1;
gauthier's avatar
gauthier committed
445
                pdu_remaining_size = pdu_remaining_size - sdu_mngt_p->sdu_remaining_size;
446
447
448
449
450
451
452
453
454
455
456
457
            }
        }

        // set framing info
        if (fi_first_byte_pdu_is_first_byte_sdu) {
            fi = 0;
        } else {
            fi = 2;
        }
        if (!fi_last_byte_pdu_is_last_byte_sdu) {
            fi = fi + 1;
        }
gauthier's avatar
gauthier committed
458
        pdu_p->b1 =  (fi << 3); //pdu_p->b1 |
459
460
461

        // set fist e bit
        if (fill_num_li > 0) {
gauthier's avatar
gauthier committed
462
            pdu_p->b1 = pdu_p->b1 | 0x04;
463
464
        }

gauthier's avatar
gauthier committed
465
466
467
        pdu_p->b1 = pdu_p->b1 | ((rlc_pP->vt_us >> 8) & 0x03);
        pdu_p->b2 = rlc_pP->vt_us & 0xFF;
        rlc_pP->vt_us = rlc_pP->vt_us+1;
468

gauthier's avatar
gauthier committed
469
470
471
472
473
474
475
        pdu_tb_req_p->data_ptr        = (unsigned char*)pdu_p;
        pdu_tb_req_p->tb_size = data_pdu_size - pdu_remaining_size;
        list_add_tail_eurecom (pdu_mem_p, &rlc_pP->pdus_to_mac_layer);
        //rlc_util_print_hex_octets(RLC, pdu_mem_p->data, data_pdu_size);
        AssertFatal( pdu_tb_req_p->tb_size > 0 , "SEGMENT10: FINAL RLC UM PDU LENGTH %d", pdu_tb_req_p->tb_size);
        pdu_p = NULL;
        pdu_mem_p = NULL;
476
477
478
479
480
481
482

        //nb_bytes_to_transmit = nb_bytes_to_transmit - data_pdu_size;
        nb_bytes_to_transmit = 0; // 1 PDU only
    }
}
//-----------------------------------------------------------------------------
void
483
rlc_um_segment_5 (rlc_um_entity_t *rlc_pP,frame_t frameP)
484
485
486
487
488
489
{
//-----------------------------------------------------------------------------
    list_t              pdus;
    signed int          pdu_remaining_size;
    signed int          test_pdu_remaining_size;

gauthier's avatar
gauthier committed
490
491
492
493
    int                 nb_bytes_to_transmit = rlc_pP->nb_bytes_requested_by_mac;
    rlc_um_pdu_sn_5_t  *pdu_p;
    struct mac_tb_req  *pdu_tb_req_p;
    mem_block_t        *pdu_mem_p;
494
    char               *data;
gauthier's avatar
gauthier committed
495
496
497
    char               *data_sdu_p;
    rlc_um_e_li_t      *e_li_p;
    struct rlc_um_tx_sdu_management *sdu_mngt_p;
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
    unsigned int       li_length_in_bytes;
    unsigned int       test_li_length_in_bytes;
    unsigned int       test_remaining_size_to_substract;
    unsigned int       test_remaining_num_li_to_substract;
    unsigned int       continue_fill_pdu_with_sdu;
    unsigned int       num_fill_sdu;
    unsigned int       test_num_li;
    unsigned int       fill_num_li;
    unsigned int       sdu_buffer_index;
    unsigned int       data_pdu_size;

    unsigned int       fi_first_byte_pdu_is_first_byte_sdu;
    unsigned int       fi_last_byte_pdu_is_last_byte_sdu;
    unsigned int       fi;
    unsigned int       max_li_overhead;

    if (nb_bytes_to_transmit < 2) {
gauthier's avatar
gauthier committed
515
516
517
518
519
520
521
522
523
#if defined(TRACE_RLC_UM_SEGMENT)
        LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] NO SEGMENTATION5 nb_bytes to transmit = %d\n",
                frameP,
                (rlc_pP->is_enb) ? "eNB" : "UE",
                rlc_pP->enb_module_id,
                rlc_pP->ue_module_id,
                rlc_pP->rb_id,
                nb_bytes_to_transmit);
#endif
524
525
        return;
    }
gauthier's avatar
gauthier committed
526
527
528
529
530
531
532
533
#if defined(TRACE_RLC_UM_SEGMENT)
    LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5\n",
            frameP,
            (rlc_pP->is_enb) ? "eNB" : "UE",
            rlc_pP->enb_module_id,
            rlc_pP->ue_module_id,
            rlc_pP->rb_id);
#endif
534
    list_init (&pdus, NULL);    // param string identifying the list is NULL
gauthier's avatar
gauthier committed
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
    pdu_mem_p = NULL;

    while ((rlc_pP->input_sdus[rlc_pP->current_sdu_index]) && (nb_bytes_to_transmit > 0)) {
#if defined(TRACE_RLC_UM_SEGMENT)
        LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 nb_bytes_to_transmit %d BO %d\n",
                frameP,
                (rlc_pP->is_enb) ? "eNB" : "UE",
                rlc_pP->enb_module_id,
                rlc_pP->ue_module_id,
                rlc_pP->rb_id,
                nb_bytes_to_transmit,
                rlc_pP->buffer_occupancy);
#endif
        // pdu_p management
        if (!pdu_mem_p) {
            if (rlc_pP->nb_sdu <= 1) {
551
552
                max_li_overhead = 0;
            } else {
gauthier's avatar
gauthier committed
553
                max_li_overhead = (((rlc_pP->nb_sdu - 1) * 3) / 2) + ((rlc_pP->nb_sdu - 1) % 2);
554
            }
gauthier's avatar
gauthier committed
555
556
557
558
559
560
561
562
563
564
565
            if  (nb_bytes_to_transmit >= (rlc_pP->buffer_occupancy + rlc_pP->tx_header_min_length_in_bytes + max_li_overhead)) {
                data_pdu_size = rlc_pP->buffer_occupancy + rlc_pP->tx_header_min_length_in_bytes + max_li_overhead;
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 alloc PDU size %d bytes to contain not all bytes requested by MAC but all BO of RLC@1\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        data_pdu_size);
#endif
566
567
            } else {
                data_pdu_size = nb_bytes_to_transmit;
gauthier's avatar
gauthier committed
568
569
570
571
572
573
574
575
576
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 alloc PDU size %d bytes to contain all bytes requested by MAC@1\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        data_pdu_size);
#endif
577
            }
gauthier's avatar
gauthier committed
578
579
580
581
582
583
584
585
586
            if (!(pdu_mem_p = get_free_mem_block (data_pdu_size + sizeof(struct mac_tb_req)))) {
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_E(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 ERROR COULD NOT GET NEW PDU, EXIT\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id);
#endif
587
588
                return;
            }
gauthier's avatar
gauthier committed
589
590
591
592
593
594
595
596
597
#if defined(TRACE_RLC_UM_SEGMENT)
            LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 get new PDU %d bytes\n",
                    frameP,
                    (rlc_pP->is_enb) ? "eNB" : "UE",
                    rlc_pP->enb_module_id,
                    rlc_pP->ue_module_id,
                    rlc_pP->rb_id,
                    data_pdu_size);
#endif
598
            pdu_remaining_size = data_pdu_size - 1;
gauthier's avatar
gauthier committed
599
600
            pdu_p        = (rlc_um_pdu_sn_5_t*) (&pdu_mem_p->data[sizeof(struct mac_tb_req)]);
            pdu_tb_req_p = (struct mac_tb_req*) (pdu_mem_p->data);
601

gauthier's avatar
gauthier committed
602
            memset (pdu_mem_p->data, 0, sizeof (rlc_um_pdu_sn_5_t)+sizeof(struct mac_tb_req));
603
604
605
606
607
608
609
610
            li_length_in_bytes = 1;
        }
        //----------------------------------------
        // compute how many SDUS can fill the PDU
        //----------------------------------------
        continue_fill_pdu_with_sdu = 1;
        num_fill_sdu               = 0;
        test_num_li                = 0;
gauthier's avatar
gauthier committed
611
        sdu_buffer_index           = rlc_pP->current_sdu_index;
612
613
614
615
616
617
        test_pdu_remaining_size    = pdu_remaining_size;
        test_li_length_in_bytes    = 1;
        test_remaining_size_to_substract   = 0;
        test_remaining_num_li_to_substract = 0;


gauthier's avatar
gauthier committed
618
619
        while ((rlc_pP->input_sdus[sdu_buffer_index]) && (continue_fill_pdu_with_sdu > 0)) {
            sdu_mngt_p = ((struct rlc_um_tx_sdu_management *) (rlc_pP->input_sdus[sdu_buffer_index]->data));
620

gauthier's avatar
gauthier committed
621
            if (sdu_mngt_p->sdu_remaining_size > test_pdu_remaining_size) {
622
623
624
625
626
627
                // no LI
                continue_fill_pdu_with_sdu = 0;
                num_fill_sdu += 1;
                test_pdu_remaining_size = 0;
                test_remaining_size_to_substract = 0;
                test_remaining_num_li_to_substract = 0;
gauthier's avatar
gauthier committed
628
            } else if (sdu_mngt_p->sdu_remaining_size == test_pdu_remaining_size) {
629
630
631
632
633
634
                // fi will indicate end of PDU is end of SDU, no need for LI
                continue_fill_pdu_with_sdu = 0;
                num_fill_sdu += 1;
                test_pdu_remaining_size = 0;
                test_remaining_size_to_substract = 0;
                test_remaining_num_li_to_substract = 0;
gauthier's avatar
gauthier committed
635
            } else if ((sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3)) == test_pdu_remaining_size ) {
636
637
638
639
640
641
642
                // no LI
                continue_fill_pdu_with_sdu = 0;
                num_fill_sdu += 1;
                test_pdu_remaining_size = 0;
                test_remaining_size_to_substract = 0;
                test_remaining_num_li_to_substract = 0;
                pdu_remaining_size = pdu_remaining_size - (test_li_length_in_bytes ^ 3);
643
		data_pdu_size -=  (test_li_length_in_bytes ^ 3);//modifier pour duy
gauthier's avatar
gauthier committed
644
            } else if ((sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3)) < test_pdu_remaining_size ) {
645
646
                test_num_li += 1;
                num_fill_sdu += 1;
gauthier's avatar
gauthier committed
647
                test_pdu_remaining_size = test_pdu_remaining_size - (sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3));
648
649
650
651
                test_remaining_size_to_substract = test_li_length_in_bytes ^ 3;
                test_remaining_num_li_to_substract = 1;
                test_li_length_in_bytes = test_li_length_in_bytes ^ 3;
            } else {
gauthier's avatar
gauthier committed
652
653
654
655
656
657
658
659
660
661
662
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 sdu_mngt_p->sdu_remaining_size=%d test_pdu_remaining_size=%d test_li_length_in_bytes=%d\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        sdu_mngt_p->sdu_remaining_size,
                        test_pdu_remaining_size,
                        test_li_length_in_bytes ^ 3);
#endif
663
664
665
666
667
668
669
                // reduce the size of the PDU
                continue_fill_pdu_with_sdu = 0;
                num_fill_sdu += 1;
                test_pdu_remaining_size = 0;
                test_remaining_size_to_substract = 0;
                test_remaining_num_li_to_substract = 0;
                pdu_remaining_size = pdu_remaining_size - 1;
670
                data_pdu_size -= 1;//modifier pour duy
671
            }
gauthier's avatar
gauthier committed
672
            sdu_buffer_index = (sdu_buffer_index + 1) % rlc_pP->size_input_sdus_buffer;
673
674
675
676
677
678
679
        }
        if (test_remaining_num_li_to_substract > 0) {
            // there is a LI that is not necessary
            test_num_li = test_num_li - 1;
            pdu_remaining_size = pdu_remaining_size - test_remaining_size_to_substract;
        }
        //----------------------------------------
gauthier's avatar
gauthier committed
680
        // Do the real filling of the pdu_p
681
        //----------------------------------------
gauthier's avatar
gauthier committed
682
683
684
685
686
687
688
689
690
691
#if defined(TRACE_RLC_UM_SEGMENT)
        LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] data shift %d Bytes num_li %d\n",
                frameP,
                (rlc_pP->is_enb) ? "eNB" : "UE",
                rlc_pP->enb_module_id,
                rlc_pP->ue_module_id,
                rlc_pP->rb_id,
                ((test_num_li*3) +1) >> 1,
                test_num_li);
#endif
692

gauthier's avatar
gauthier committed
693
694
        data = ((char*)(&pdu_p->data[((test_num_li*3) +1) >> 1]));
        e_li_p = (rlc_um_e_li_t*)(pdu_p->data);
695
696
697
698
699
700
701
        continue_fill_pdu_with_sdu          = 1;
        li_length_in_bytes                  = 1;
        fill_num_li                         = 0;
        fi_first_byte_pdu_is_first_byte_sdu = 0;
        fi_last_byte_pdu_is_last_byte_sdu   = 0;

        if (
gauthier's avatar
gauthier committed
702
703
            ((struct rlc_um_tx_sdu_management *) (rlc_pP->input_sdus[rlc_pP->current_sdu_index]->data))->sdu_remaining_size ==
            ((struct rlc_um_tx_sdu_management *) (rlc_pP->input_sdus[rlc_pP->current_sdu_index]->data))->sdu_size) {
704
705
            fi_first_byte_pdu_is_first_byte_sdu = 1;
        }
gauthier's avatar
gauthier committed
706
707
708
709
710
711
712
713
714
715
716
717
718
        while ((rlc_pP->input_sdus[rlc_pP->current_sdu_index]) && (continue_fill_pdu_with_sdu > 0)) {
            sdu_mngt_p = ((struct rlc_um_tx_sdu_management *) (rlc_pP->input_sdus[rlc_pP->current_sdu_index]->data));
            if (sdu_mngt_p->sdu_segmented_size == 0) {
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 GET NEW SDU %p AVAILABLE SIZE %d Bytes\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        sdu_mngt_p,
                        sdu_mngt_p->sdu_remaining_size);
#endif
719
            } else {
gauthier's avatar
gauthier committed
720
721
722
723
724
725
726
727
728
729
730
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 GET AGAIN SDU %p REMAINING AVAILABLE SIZE %d Bytes / %d Bytes \n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        sdu_mngt_p,
                        sdu_mngt_p->sdu_remaining_size,
                        sdu_mngt_p->sdu_size);
#endif
731
            }
gauthier's avatar
gauthier committed
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
            data_sdu_p = &((rlc_pP->input_sdus[rlc_pP->current_sdu_index])->data[sizeof (struct rlc_um_tx_sdu_management) + sdu_mngt_p->sdu_segmented_size]);

            if (sdu_mngt_p->sdu_remaining_size > pdu_remaining_size) {
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 Filling all remaining PDU with %d bytes\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        pdu_remaining_size);
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 pdu_mem_p %p pdu_p %p pdu_p->data %p data %p data_sdu_p %p pdu_remaining_size %d\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        pdu_mem_p,
                        pdu_p,
                        pdu_p->data,
                        data,
                        data_sdu_p,
                        pdu_remaining_size);
#endif
756

gauthier's avatar
gauthier committed
757
758
759
                memcpy(data, data_sdu_p, pdu_remaining_size);
                sdu_mngt_p->sdu_remaining_size = sdu_mngt_p->sdu_remaining_size - pdu_remaining_size;
                sdu_mngt_p->sdu_segmented_size = sdu_mngt_p->sdu_segmented_size + pdu_remaining_size;
760
761
                fi_last_byte_pdu_is_last_byte_sdu = 0;
                // no LI
gauthier's avatar
gauthier committed
762
                rlc_pP->buffer_occupancy -= pdu_remaining_size;
763
764
                continue_fill_pdu_with_sdu = 0;
                pdu_remaining_size = 0;
gauthier's avatar
gauthier committed
765
766
767
768
769
770
771
772
773
774
            } else if (sdu_mngt_p->sdu_remaining_size == pdu_remaining_size) {
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 Exactly Filling remaining PDU with %d remaining bytes of SDU\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        pdu_remaining_size);
#endif
775
                memcpy(data, data_sdu_p, pdu_remaining_size);
776
                // free SDU
gauthier's avatar
gauthier committed
777
778
779
780
781
                rlc_pP->buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
                free_mem_block (rlc_pP->input_sdus[rlc_pP->current_sdu_index]);
                rlc_pP->input_sdus[rlc_pP->current_sdu_index] = NULL;
                rlc_pP->nb_sdu -= 1;
                rlc_pP->current_sdu_index = (rlc_pP->current_sdu_index + 1) % rlc_pP->size_input_sdus_buffer;
782
783
784
785
786

                fi_last_byte_pdu_is_last_byte_sdu = 1;
                // fi will indicate end of PDU is end of SDU, no need for LI
                continue_fill_pdu_with_sdu = 0;
                pdu_remaining_size = 0;
gauthier's avatar
gauthier committed
787
788
789
790
791
792
793
794
795
796
797
798
            } else if ((sdu_mngt_p->sdu_remaining_size + (li_length_in_bytes ^ 3)) < pdu_remaining_size ) {
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 Filling  PDU with %d all remaining bytes of SDU\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        sdu_mngt_p->sdu_remaining_size);
#endif
                memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
                data = &data[sdu_mngt_p->sdu_remaining_size];
799
800
801
802
                li_length_in_bytes = li_length_in_bytes ^ 3;
                fill_num_li += 1;
                if (li_length_in_bytes  == 2) {
                    if (fill_num_li == test_num_li) {
gauthier's avatar
gauthier committed
803
804
                        //e_li_p->e1  = 0;
                        e_li_p->b1 = 0;
805
                    } else {
gauthier's avatar
gauthier committed
806
807
                        //e_li_p->e1  = 1;
                        e_li_p->b1 =  0x80;
808
                    }
gauthier's avatar
gauthier committed
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
                    //e_li_p->li1 = sdu_mngt_p->sdu_remaining_size;
                    e_li_p->b1 = e_li_p->b1 | (sdu_mngt_p->sdu_remaining_size >> 4);
                    e_li_p->b2 = sdu_mngt_p->sdu_remaining_size << 4;
#if defined(TRACE_RLC_UM_SEGMENT)
                    LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 set e_li_p->b1=%02X set e_li_p->b2=%02X fill_num_li=%d test_num_li=%d\n",
                            frameP,
                            (rlc_pP->is_enb) ? "eNB" : "UE",
                            rlc_pP->enb_module_id,
                            rlc_pP->ue_module_id,
                            rlc_pP->rb_id,
                            e_li_p->b1,
                            e_li_p->b2,
                            fill_num_li,
                            test_num_li);
#endif
824
825
                } else {
                    if (fill_num_li != test_num_li) {
gauthier's avatar
gauthier committed
826
827
                        //e_li_p->e2  = 1;
                        e_li_p->b2  = e_li_p->b2 | 0x08;
828
                    }
gauthier's avatar
gauthier committed
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
                    //e_li_p->li2 = sdu_mngt_p->sdu_remaining_size;
                    e_li_p->b2 = e_li_p->b2 | (sdu_mngt_p->sdu_remaining_size >> 8);
                    e_li_p->b3 = sdu_mngt_p->sdu_remaining_size & 0xFF;
#if defined(TRACE_RLC_UM_SEGMENT)
                    LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 set e_li_p->b2=%02X set e_li_p->b3=%02X fill_num_li=%d test_num_li=%d\n",
                            frameP,
                            (rlc_pP->is_enb) ? "eNB" : "UE",
                            rlc_pP->enb_module_id,
                            rlc_pP->ue_module_id,
                            rlc_pP->rb_id,
                            e_li_p->b2,
                            e_li_p->b3,
                            fill_num_li,
                            test_num_li);
#endif
                    e_li_p++;
845
846
847
                }

                // free SDU
gauthier's avatar
gauthier committed
848
849
850
851
852
                rlc_pP->buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
                free_mem_block (rlc_pP->input_sdus[rlc_pP->current_sdu_index]);
                rlc_pP->input_sdus[rlc_pP->current_sdu_index] = NULL;
                rlc_pP->nb_sdu -= 1;
                rlc_pP->current_sdu_index = (rlc_pP->current_sdu_index + 1) % rlc_pP->size_input_sdus_buffer;
853

gauthier's avatar
gauthier committed
854
                pdu_remaining_size = pdu_remaining_size - (sdu_mngt_p->sdu_remaining_size + li_length_in_bytes);
855
            } else {
gauthier's avatar
gauthier committed
856
857
858
859
860
861
862
863
864
865
#if defined(TRACE_RLC_UM_SEGMENT)
                LOG_D(RLC, "[FRAME %05u][%s][RLC_UM][MOD %u/%u][RB %u] SEGMENT5 Filling  PDU with %d all remaining bytes of SDU and reduce TB size by %d bytes\n",
                        frameP,
                        (rlc_pP->is_enb) ? "eNB" : "UE",
                        rlc_pP->enb_module_id,
                        rlc_pP->ue_module_id,
                        rlc_pP->rb_id,
                        sdu_mngt_p->sdu_remaining_size,
                        pdu_remaining_size - sdu_mngt_p->sdu_remaining_size);
#endif
866
867
868
#ifdef USER_MODE
                assert(1!=1);
#endif
gauthier's avatar
gauthier committed
869
                memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
870
                // free SDU
gauthier's avatar
gauthier committed
871
872
873
874
875
                rlc_pP->buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
                free_mem_block (rlc_pP->input_sdus[rlc_pP->current_sdu_index]);
                rlc_pP->input_sdus[rlc_pP->current_sdu_index] = NULL;
                rlc_pP->nb_sdu -= 1;
                rlc_pP->current_sdu_index = (rlc_pP->current_sdu_index + 1) % rlc_pP->size_input_sdus_buffer;
876
877
878
879

                // reduce the size of the PDU
                continue_fill_pdu_with_sdu = 0;
                fi_last_byte_pdu_is_last_byte_sdu = 1;
gauthier's avatar
gauthier committed
880
                pdu_remaining_size = pdu_remaining_size - sdu_mngt_p->sdu_remaining_size;
881
882
883
884
885
886
887
888
889
890
891
892
            }
        }

        // set framing info
        if (fi_first_byte_pdu_is_first_byte_sdu) {
            fi = 0;
        } else {
            fi = 2;
        }
        if (!fi_last_byte_pdu_is_last_byte_sdu) {
            fi = fi + 1;
        }
gauthier's avatar
gauthier committed
893
        pdu_p->b1 =  (fi << 6); //pdu_p->b1 |
894
895
896

        // set fist e bit
        if (fill_num_li > 0) {
gauthier's avatar
gauthier committed
897
            pdu_p->b1 = pdu_p->b1 | 0x20;
898
        }
gauthier's avatar
gauthier committed
899
900
        pdu_p->b1 = pdu_p->b1 | (rlc_pP->vt_us & 0x1F);
        rlc_pP->vt_us = rlc_pP->vt_us+1;
901

gauthier's avatar
gauthier committed
902
903
904
905
        pdu_tb_req_p->data_ptr        = (unsigned char*)pdu_p;
        pdu_tb_req_p->tb_size         = data_pdu_size - pdu_remaining_size;
        list_add_tail_eurecom (pdu_mem_p, &rlc_pP->pdus_to_mac_layer);
        rlc_util_print_hex_octets(RLC, (unsigned char*)pdu_mem_p->data, data_pdu_size);
906

gauthier's avatar
gauthier committed
907
        AssertFatal( pdu_tb_req_p->tb_size > 0 , "SEGMENT5: FINAL RLC UM PDU LENGTH %d", pdu_tb_req_p->tb_size);
908

gauthier's avatar
gauthier committed
909
910
        pdu_p = NULL;
        pdu_mem_p = NULL;
911
912
913
914
915
916

        //nb_bytes_to_transmit = nb_bytes_to_transmit - data_pdu_size;
        nb_bytes_to_transmit = 0; // 1 PDU only
    }
}