rlc_am_segment.c 30.7 KB
Newer Older
1
2
/*******************************************************************************
Eurecom OpenAirInterface 2
gauthier's avatar
Licence    
gauthier committed
3
Copyright(c) 1999 - 2014 Eurecom
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.

This program is distributed in the hope 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.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

The full GNU General Public License is included in this distribution in
the file called "COPYING".

Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums       : http://forums.eurecom.fsr/openairinterface
gauthier's avatar
Licence    
gauthier committed
25
26
27
28
29
30
Address      : EURECOM,
               Campus SophiaTech,
               450 Route des Chappes,
               CS 50193
               06904 Biot Sophia Antipolis cedex,
               FRANCE
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
*******************************************************************************/
#define RLC_AM_MODULE
#define RLC_AM_SEGMENT_C
//-----------------------------------------------------------------------------
#ifdef USER_MODE
#include <assert.h>
#endif
//-----------------------------------------------------------------------------
//#include "rtos_header.h"
#include "platform_types.h"
//-----------------------------------------------------------------------------
#include "list.h"
#include "rlc_am.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"

//-----------------------------------------------------------------------------
48
49
50
51
52
void rlc_am_pdu_polling (
        rlc_am_entity_t *const rlc_pP,
        const frame_t frameP,
        rlc_am_pdu_sn_10_t *const pdu_pP,
        const int16_t payload_sizeP)
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//-----------------------------------------------------------------------------
{
    // 5.2.2 Polling
    // An AM RLC entity can poll its peer AM RLC entity in order to trigger STATUS reporting at the peer AM RLC entity.
    // 5.2.2.1 Transmission of a AMD PDU or AMD PDU segment
    // Upon assembly of a new AMD PDU, the transmitting side of an AM RLC entity shall:
    //     - increment PDU_WITHOUT_POLL by one;
    //     - increment BYTE_WITHOUT_POLL by every new byte of Data field element that it maps to the Data field of
    //       the RLC data PDU;
    //     - if PDU_WITHOUT_POLL >= pollPDU; or
    //     - if BYTE_WITHOUT_POLL >= pollByte;
    //         -include a poll in the RLC data PDU as described below.
    // Upon assembly of an AMD PDU or AMD PDU segment, the transmitting side of an AM RLC entity shall:
    //     - if both the transmission buffer and the retransmission buffer becomes empty (excluding transmitted RLC data
    //       PDU awaiting for acknowledgements) after the transmission of the RLC data PDU; or
    //     - if no new RLC data PDU can be transmitted after the transmission of the RLC data PDU (e.g. due to window
    //       stalling);
    //         - include a poll in the RLC data PDU as described below.
    // To include a poll in a RLC data PDU, the transmitting side of an AM RLC entity shall:
    //     - set the P field of the RLC data PDU to "1";
    //     - set PDU_WITHOUT_POLL to 0;
    //     - set BYTE_WITHOUT_POLL to 0;
    // After delivering a RLC data PDU including a poll to lower layer and after incrementing of VT(S) if necessary, the
    // transmitting side of an AM RLC entity shall:
    //     - set POLL_SN to VT(S) – 1;
    //     - if t-PollRetransmit is not running:
    //         - start t-PollRetransmit;
    //     - else:
    //         - restart t-PollRetransmit;
gauthier's avatar
gauthier committed
82
83
    rlc_pP->c_pdu_without_poll     += 1;
    rlc_pP->c_byte_without_poll    += payload_sizeP;
84
85

    if (
gauthier's avatar
gauthier committed
86
87
88
89
        (rlc_pP->c_pdu_without_poll >= rlc_pP->poll_pdu) ||
        (rlc_pP->c_byte_without_poll >= rlc_pP->poll_byte) ||
        ((rlc_pP->sdu_buffer_occupancy == 0) && (rlc_pP->retrans_num_bytes_to_retransmit == 0)) ||
        (rlc_pP->vt_s == rlc_pP->vt_ms)
90
91
        ) {

gauthier's avatar
gauthier committed
92
93
94
95
96
97
98
99
        if (rlc_pP->c_pdu_without_poll >= rlc_pP->poll_pdu) {
            LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][POLL] SET POLL BECAUSE TX NUM PDU THRESHOLD %d  HAS BEEN REACHED\n",
                  frameP,
                  (rlc_pP->is_enb) ? "eNB" : "UE",
                  rlc_pP->enb_module_id,
                  rlc_pP->ue_module_id,
                  rlc_pP->rb_id,
                  rlc_pP->poll_pdu);
100
        }
gauthier's avatar
gauthier committed
101
102
103
104
105
106
107
108
        if (rlc_pP->c_pdu_without_poll >= rlc_pP->poll_pdu) {
            LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][POLL] SET POLL BECAUSE TX NUM BYTES THRESHOLD %d  HAS BEEN REACHED\n",
                  frameP,
                  (rlc_pP->is_enb) ? "eNB" : "UE",
                  rlc_pP->enb_module_id,
                  rlc_pP->ue_module_id,
                  rlc_pP->rb_id,
                  rlc_pP->poll_byte);
109
        }
gauthier's avatar
gauthier committed
110
111
112
113
114
115
116
        if ((rlc_pP->sdu_buffer_occupancy == 0) && (rlc_pP->retrans_num_bytes_to_retransmit == 0)) {
            LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][POLL] SET POLL BECAUSE TX BUFFERS ARE EMPTY\n",
                  frameP,
                  (rlc_pP->is_enb) ? "eNB" : "UE",
                  rlc_pP->enb_module_id,
                  rlc_pP->ue_module_id,
                  rlc_pP->rb_id);
117
        }
gauthier's avatar
gauthier committed
118
119
120
121
122
123
124
        if (rlc_pP->vt_s == rlc_pP->vt_ms) {
            LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][POLL] SET POLL BECAUSE OF WINDOW STALLING\n",
                  frameP,
                  (rlc_pP->is_enb) ? "eNB" : "UE",
                  rlc_pP->enb_module_id,
                  rlc_pP->ue_module_id,
                  rlc_pP->rb_id);
125
        }
gauthier's avatar
gauthier committed
126
127
128
        pdu_pP->b1 = pdu_pP->b1 | 0x20;
        rlc_pP->c_pdu_without_poll     = 0;
        rlc_pP->c_byte_without_poll    = 0;
129

gauthier's avatar
gauthier committed
130
131
132
        rlc_pP->poll_sn = (rlc_pP->vt_s -1) & RLC_AM_SN_MASK;
        //optimisation if (!rlc_pP->t_poll_retransmit.running) {
        rlc_am_start_timer_poll_retransmit(rlc_pP,frameP);
133
        //optimisation } else {
gauthier's avatar
gauthier committed
134
        //optimisation     rlc_pP->t_poll_retransmit.frame_time_out = frameP + rlc_pP->t_poll_retransmit.time_out;
135
136
        //optimisation }
    } else {
gauthier's avatar
gauthier committed
137
        pdu_pP->b1 = pdu_pP->b1 & 0xDF;
138
139
140
    }
}
//-----------------------------------------------------------------------------
141
142
143
void rlc_am_segment_10 (
        rlc_am_entity_t *const rlc_pP,
        const frame_t frameP)
144
145
146
{
//-----------------------------------------------------------------------------
    list_t              pdus;
147
148
    sdu_size_t          pdu_remaining_size      = 0;
    sdu_size_t          test_pdu_remaining_size = 0;
gauthier's avatar
gauthier committed
149

150
    sdu_size_t                       nb_bytes_to_transmit = rlc_pP->nb_bytes_requested_by_mac;
gauthier's avatar
gauthier committed
151
152
153
154
155
156
157
158
159
    rlc_am_pdu_sn_10_t              *pdu_p        = NULL;
    struct mac_tb_req               *pdu_tb_req_p = NULL;
    mem_block_t                     *pdu_mem_p    = NULL;
    unsigned char                   *data         = NULL;
    unsigned char                   *data_sdu_p   = NULL;
    rlc_am_e_li_t                   *e_li_p       = NULL;
    rlc_am_tx_sdu_management_t      *sdu_mngt_p   = NULL;
    rlc_am_tx_data_pdu_management_t *pdu_mngt_p   = NULL;

160
161
162
    sdu_size_t         li_length_in_bytes         = 0;
    sdu_size_t         test_li_length_in_bytes    = 0;
    sdu_size_t         test_remaining_size_to_substract= 0;
gauthier's avatar
gauthier committed
163
164
165
166
167
168
    unsigned int       test_remaining_num_li_to_substract = 0;
    unsigned int       continue_fill_pdu_with_sdu         = 0;
    unsigned int       num_fill_sdu                       = 0;
    unsigned int       test_num_li                        = 0;
    unsigned int       fill_num_li                        = 0;
    unsigned int       sdu_buffer_index                   = 0;
169
    sdu_size_t         data_pdu_size                      = 0;
gauthier's avatar
gauthier committed
170
171
172
173

    unsigned int       fi_first_byte_pdu_is_first_byte_sdu = 0;
    unsigned int       fi_last_byte_pdu_is_last_byte_sdu   = 0;
    unsigned int       fi                                  = 0;
174
    signed int         max_li_overhead                     = 0;
gauthier's avatar
gauthier committed
175
176
177
178
179
180
181
182
183
184
185
186

    LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] rlc_pP->current_sdu_index %d rlc_pP->next_sdu_index %d rlc_pP->input_sdus[rlc_pP->current_sdu_index].mem_block %p sdu_buffer_occupancy %d\n",
          frameP,
          (rlc_pP->is_enb) ? "eNB" : "UE",
          rlc_pP->enb_module_id,
          rlc_pP->ue_module_id,
          rlc_pP->rb_id,
          rlc_pP->current_sdu_index,
          rlc_pP->next_sdu_index,
          rlc_pP->input_sdus[rlc_pP->current_sdu_index].mem_block,
          rlc_pP->sdu_buffer_occupancy);
    if (rlc_pP->sdu_buffer_occupancy <= 0) {
187
188
189
        return;
    }

gauthier's avatar
gauthier committed
190
    //msg ("[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT]\n", rlc_pP->module_id, rlc_pP->rb_id, frameP);
191
    list_init (&pdus, NULL);    // param string identifying the list is NULL
gauthier's avatar
gauthier committed
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
    pdu_mem_p = NULL;


    while ((rlc_pP->input_sdus[rlc_pP->current_sdu_index].mem_block) && (nb_bytes_to_transmit > 0) ) {
        LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] 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->sdu_buffer_occupancy);
        // pdu_p management
        if (!pdu_mem_p) {
            if (rlc_pP->nb_sdu_no_segmented <= 1) {
207
208
                max_li_overhead = 0;
            } else {
gauthier's avatar
gauthier committed
209
                max_li_overhead = (((rlc_pP->nb_sdu_no_segmented - 1) * 3) / 2) + ((rlc_pP->nb_sdu_no_segmented - 1) % 2);
210
            }
gauthier's avatar
gauthier committed
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
            LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] max_li_overhead %d\n",
                  frameP,
                  (rlc_pP->is_enb) ? "eNB" : "UE",
                  rlc_pP->enb_module_id,
                  rlc_pP->ue_module_id,
                  rlc_pP->rb_id,
                  max_li_overhead);
            if  (nb_bytes_to_transmit >= (rlc_pP->sdu_buffer_occupancy + RLC_AM_HEADER_MIN_SIZE + max_li_overhead)) {
                data_pdu_size = rlc_pP->sdu_buffer_occupancy + RLC_AM_HEADER_MIN_SIZE + max_li_overhead;
                LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] 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);
227
228
            } else {
                data_pdu_size = nb_bytes_to_transmit;
gauthier's avatar
gauthier committed
229
230
231
232
233
234
235
               LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] 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);
236
            }
gauthier's avatar
gauthier committed
237
238
239
240
241
242
243
            if (!(pdu_mem_p = get_free_mem_block (data_pdu_size + sizeof(struct mac_tb_req)))) {
                LOG_C(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] 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);
244
245
                return;
            }
gauthier's avatar
gauthier committed
246
247
248
249
250
251
252
            LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] 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);
253
            pdu_remaining_size = data_pdu_size - RLC_AM_HEADER_MIN_SIZE;
gauthier's avatar
gauthier committed
254
255
256
257
            pdu_p        = (rlc_am_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);
            pdu_mngt_p   = &rlc_pP->pdu_retrans_buffer[rlc_pP->vt_s % RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE];
            memset(pdu_mngt_p, 0, sizeof (rlc_am_tx_data_pdu_management_t));
258

gauthier's avatar
gauthier committed
259
            memset (pdu_mem_p->data, 0, sizeof (rlc_am_pdu_sn_10_t)+sizeof(struct mac_tb_req));
260
261
262
263
264
265
266
267
            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
268
        sdu_buffer_index           = rlc_pP->current_sdu_index;
269
270
271
272
273
274
        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
275
276
        while ((rlc_pP->input_sdus[sdu_buffer_index].mem_block) && (continue_fill_pdu_with_sdu > 0)) {
            sdu_mngt_p = &rlc_pP->input_sdus[sdu_buffer_index];
277

gauthier's avatar
gauthier committed
278
            if (sdu_mngt_p->sdu_remaining_size > test_pdu_remaining_size) {
279
280
281
282
283
284
                // 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
285
            } else if (sdu_mngt_p->sdu_remaining_size == test_pdu_remaining_size) {
286
287
288
289
290
291
                // 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
292
            } else if ((sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3)) == test_pdu_remaining_size ) {
293
294
295
296
297
298
299
                // 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
300
301
            } else if ((sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3)) < test_pdu_remaining_size ) {
                if (pdu_mngt_p->nb_sdus >= (RLC_AM_MAX_SDU_IN_PDU-1)) {
302
303
304
305
306
307
308
309
310
                    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;
                } else {
                    test_num_li += 1;
                    num_fill_sdu += 1;
gauthier's avatar
gauthier committed
311
                    test_pdu_remaining_size = test_pdu_remaining_size - (sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3));
312
313
314
315
316
                    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
317
318
319
320
321
322
323
324
325
                LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] 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);
326
327
328
329
330
331
332
333
                // 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
334
335
336
            pdu_mngt_p->sdus_index[pdu_mngt_p->nb_sdus++] = sdu_buffer_index;
            sdu_mngt_p->pdus_index[sdu_mngt_p->nb_pdus++] = rlc_pP->vt_s % RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE;
            assert(sdu_mngt_p->nb_pdus < RLC_AM_MAX_SDU_FRAGMENTS);
337
338
339
340
341
342
343
344
            sdu_buffer_index = (sdu_buffer_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE;
        }
        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
345
        // Do the real filling of the pdu_p
346
        //----------------------------------------
gauthier's avatar
gauthier committed
347
348
349
350
351
352
353
354
355
356
357
        LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][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);
        data = ((unsigned char*)(&pdu_p->data[((test_num_li*3) +1) >> 1]));
        pdu_mngt_p->payload = data;
        e_li_p = (rlc_am_e_li_t*)(pdu_p->data);
358
359
360
361
362
363
        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;

gauthier's avatar
gauthier committed
364
365
        if (rlc_pP->input_sdus[rlc_pP->current_sdu_index].sdu_remaining_size ==
            rlc_pP->input_sdus[rlc_pP->current_sdu_index].sdu_size) {
366
367
            fi_first_byte_pdu_is_first_byte_sdu = 1;
        }
gauthier's avatar
gauthier committed
368
369
370
371
372
373
374
375
376
377
378
        while ((rlc_pP->input_sdus[rlc_pP->current_sdu_index].mem_block) && (continue_fill_pdu_with_sdu > 0)) {
            sdu_mngt_p = &rlc_pP->input_sdus[rlc_pP->current_sdu_index];
            if (sdu_mngt_p->sdu_segmented_size == 0) {
                LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] 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);
379
            } else {
gauthier's avatar
gauthier committed
380
381
382
383
384
385
386
387
388
                LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] GET AGAIN SDU %p REMAINING AVAILABLE SIZE %d Bytes / %d Bytes LENGTH \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);
389
            }
gauthier's avatar
gauthier committed
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
            data_sdu_p = &sdu_mngt_p->first_byte[sdu_mngt_p->sdu_segmented_size];

            if (sdu_mngt_p->sdu_remaining_size > pdu_remaining_size) {
                LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] 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);
                //msg ("[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] pdu_mem_p %p pdu_p %p pdu_p->data %p data %p data_sdu_p %p pdu_remaining_size %d\n", rlc_pP->module_id, rlc_pP->rb_id, frameP, pdu_mem_p, pdu_p, pdu_p->data, data, data_sdu_p,pdu_remaining_size);

                memcpy(data, data_sdu_p, pdu_remaining_size);
                pdu_mngt_p->payload_size += 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;
406
407
                fi_last_byte_pdu_is_last_byte_sdu = 0;
                // no LI
gauthier's avatar
gauthier committed
408
                rlc_pP->sdu_buffer_occupancy -= pdu_remaining_size;
409
410
                continue_fill_pdu_with_sdu = 0;
                pdu_remaining_size = 0;
gauthier's avatar
gauthier committed
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
                LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] sdu_remaining_size %d bytes sdu_segmented_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_remaining_size,
                      sdu_mngt_p->sdu_segmented_size);
            } else if (sdu_mngt_p->sdu_remaining_size == pdu_remaining_size) {
                LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] 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);
                memcpy(data, data_sdu_p, pdu_remaining_size);
                pdu_mngt_p->payload_size += pdu_remaining_size;
429
430

                // free SDU
gauthier's avatar
gauthier committed
431
432
433
434
435
436
                rlc_pP->sdu_buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
                rlc_am_free_in_sdu_data(rlc_pP, rlc_pP->current_sdu_index);
                //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_AM_SDU_CONTROL_BUFFER_SIZE;
437
438
439
440
441

                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
442
            } else if ((sdu_mngt_p->sdu_remaining_size + (li_length_in_bytes ^ 3)) < pdu_remaining_size ) {
443
                if (fill_num_li == (RLC_AM_MAX_SDU_IN_PDU - 1)) {
gauthier's avatar
gauthier committed
444
445
446
447
448
449
450
451
452
453
                    LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] [SIZE %d] REACHING RLC_AM_MAX_SDU_IN_PDU LIs -> STOP SEGMENTATION FOR THIS PDU 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);
                    memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
                    pdu_mngt_p->payload_size += sdu_mngt_p->sdu_remaining_size;
                    pdu_remaining_size = 0; //Forced to 0 pdu_remaining_size - sdu_mngt_p->sdu_remaining_size;
454
                    // free SDU
gauthier's avatar
gauthier committed
455
456
457
458
459
                    rlc_pP->sdu_buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
                    rlc_am_free_in_sdu_data(rlc_pP, 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_AM_SDU_CONTROL_BUFFER_SIZE;
460
461
462
463
464

                    // reduce the size of the PDU
                    continue_fill_pdu_with_sdu = 0;
                    fi_last_byte_pdu_is_last_byte_sdu = 1;
                } else {
gauthier's avatar
gauthier committed
465
466
467
468
469
470
471
472
473
474
                    LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] 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);
                    memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
                    pdu_mngt_p->payload_size += sdu_mngt_p->sdu_remaining_size;
                    data = &data[sdu_mngt_p->sdu_remaining_size];
475
476
477
478
                    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
479
480
                            //e_li_p->e1  = 0;
                            e_li_p->b1 = 0;
481
                        } else {
gauthier's avatar
gauthier committed
482
483
                            //e_li_p->e1  = 1;
                            e_li_p->b1 =  0x80;
484
                        }
gauthier's avatar
gauthier committed
485
486
487
488
489
490
491
492
493
494
495
496
497
                        //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;
                        LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] set e_li_p->b1=0x%02X set e_li_p->b2=0x%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);
498
499
                    } else {
                        if (fill_num_li != test_num_li) {
gauthier's avatar
gauthier committed
500
501
                            //e_li_p->e2  = 1;
                            e_li_p->b2  = e_li_p->b2 | 0x08;
502
                        }
gauthier's avatar
gauthier committed
503
504
505
506
507
508
509
510
511
512
513
514
515
516
                        //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;
                        LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] set e_li_p->b2=0x%02X set e_li_p->b3=0x%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);
                        e_li_p++;
517
518
                    }

gauthier's avatar
gauthier committed
519
                    pdu_remaining_size = pdu_remaining_size - (sdu_mngt_p->sdu_remaining_size + li_length_in_bytes);
520
                    // free SDU
gauthier's avatar
gauthier committed
521
522
523
524
525
526
527
528
                    rlc_pP->sdu_buffer_occupancy  -= sdu_mngt_p->sdu_remaining_size;
                    sdu_mngt_p->sdu_remaining_size = 0;

                    rlc_am_free_in_sdu_data(rlc_pP, rlc_pP->current_sdu_index);
                    //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_AM_SDU_CONTROL_BUFFER_SIZE;
529
530
                }
            } else {
gauthier's avatar
gauthier committed
531
532
533
534
535
536
537
538
                LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] 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);
539
540
541
#ifdef USER_MODE
                assert(1!=1);
#endif
gauthier's avatar
gauthier committed
542
543
544
                memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
                pdu_mngt_p->payload_size += sdu_mngt_p->sdu_remaining_size;
                pdu_remaining_size = pdu_remaining_size - sdu_mngt_p->sdu_remaining_size;
545
                // free SDU
gauthier's avatar
gauthier committed
546
547
548
549
550
                rlc_pP->sdu_buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
                rlc_am_free_in_sdu_data(rlc_pP, 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_AM_SDU_CONTROL_BUFFER_SIZE;
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566

                // reduce the size of the PDU
                continue_fill_pdu_with_sdu = 0;
                fi_last_byte_pdu_is_last_byte_sdu = 1;
            }
        }

        // 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
567
        pdu_p->b1 = pdu_p->b1 | (fi << 3);
568
569
570

        // set fist e bit
        if (fill_num_li > 0) {
gauthier's avatar
gauthier committed
571
            pdu_p->b1 = pdu_p->b1 | 0x04;
572
        }
gauthier's avatar
gauthier committed
573
574
575
576
577
578
579
        LOG_T(RLC, "[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] SEND PDU SN %04d  SIZE %d BYTES PAYLOAD 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,
             rlc_pP->vt_s,
580
             data_pdu_size - pdu_remaining_size,
gauthier's avatar
gauthier committed
581
             pdu_mngt_p->payload_size);
582

gauthier's avatar
gauthier committed
583
584
        rlc_pP->stat_tx_data_pdu   += 1;
        rlc_pP->stat_tx_data_bytes += (data_pdu_size - pdu_remaining_size);
585

gauthier's avatar
gauthier committed
586
587
588
589
590
        //pdu_p->sn = rlc_pP->vt_s;
        pdu_p->b1 = pdu_p->b1 | 0x80; // DATA/CONTROL field is DATA PDU
        pdu_p->b1 = pdu_p->b1 | (rlc_pP->vt_s >> 8);
        pdu_p->b2 = rlc_pP->vt_s & 0xFF;
        rlc_pP->vt_s = (rlc_pP->vt_s+1) & RLC_AM_SN_MASK;
591

gauthier's avatar
gauthier committed
592
593
        pdu_tb_req_p->data_ptr        = (unsigned char*)pdu_p;
        pdu_tb_req_p->tb_size         = data_pdu_size - pdu_remaining_size;
594
595
#warning "why 3000: changed to RLC_SDU_MAX_SIZE "
        assert(pdu_tb_req_p->tb_size < RLC_SDU_MAX_SIZE );
gauthier's avatar
gauthier committed
596
        rlc_am_pdu_polling(rlc_pP, frameP,pdu_p, pdu_mngt_p->payload_size);
597

gauthier's avatar
gauthier committed
598
599
600
601
602
        //list_add_tail_eurecom (pdu_mem_p, &rlc_pP->segmentation_pdu_list);
        pdu_mngt_p->mem_block  = pdu_mem_p;
        pdu_mngt_p->first_byte = (unsigned char*)pdu_p;
        pdu_mngt_p->header_and_payload_size  = data_pdu_size - pdu_remaining_size;
        pdu_mngt_p->retx_count = -1;
603

gauthier's avatar
gauthier committed
604
605
        rlc_pP->retrans_num_pdus  += 1;
        rlc_pP->retrans_num_bytes += pdu_mngt_p->header_and_payload_size;
606

gauthier's avatar
gauthier committed
607
608
        pdu_p = NULL;
        pdu_mem_p = NULL;
609
610
611
612

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

gauthier's avatar
gauthier committed
613
614
        mem_block_t* copy = rlc_am_retransmit_get_copy (rlc_pP, frameP,(rlc_pP->vt_s-1) & RLC_AM_SN_MASK);
        list_add_tail_eurecom (copy, &rlc_pP->segmentation_pdu_list);
615
616
617

    }
}