rlc_am_segment.c 30.6 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"

//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
48
void rlc_am_pdu_polling (rlc_am_entity_t *rlc_pP, frame_t frameP, rlc_am_pdu_sn_10_t *pdu_pP, int16_t payload_sizeP)
49
50
51
52
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
//-----------------------------------------------------------------------------
{
    // 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
78
79
    rlc_pP->c_pdu_without_poll     += 1;
    rlc_pP->c_byte_without_poll    += payload_sizeP;
80
81

    if (
gauthier's avatar
gauthier committed
82
83
84
85
        (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)
86
87
        ) {

gauthier's avatar
gauthier committed
88
89
90
91
92
93
94
95
        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);
96
        }
gauthier's avatar
gauthier committed
97
98
99
100
101
102
103
104
        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);
105
        }
gauthier's avatar
gauthier committed
106
107
108
109
110
111
112
        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);
113
        }
gauthier's avatar
gauthier committed
114
115
116
117
118
119
120
        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);
121
        }
gauthier's avatar
gauthier committed
122
123
124
        pdu_pP->b1 = pdu_pP->b1 | 0x20;
        rlc_pP->c_pdu_without_poll     = 0;
        rlc_pP->c_byte_without_poll    = 0;
125

gauthier's avatar
gauthier committed
126
127
128
        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);
129
        //optimisation } else {
gauthier's avatar
gauthier committed
130
        //optimisation     rlc_pP->t_poll_retransmit.frame_time_out = frameP + rlc_pP->t_poll_retransmit.time_out;
131
132
        //optimisation }
    } else {
gauthier's avatar
gauthier committed
133
        pdu_pP->b1 = pdu_pP->b1 & 0xDF;
134
135
136
    }
}
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
137
void rlc_am_segment_10 (rlc_am_entity_t *rlc_pP,frame_t frameP)
138
139
140
{
//-----------------------------------------------------------------------------
    list_t              pdus;
gauthier's avatar
gauthier committed
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
    signed int          pdu_remaining_size      = 0;
    signed int          test_pdu_remaining_size = 0;

    int                      nb_bytes_to_transmit = rlc_pP->nb_bytes_requested_by_mac;
    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;

    unsigned int       li_length_in_bytes         = 0;
    unsigned int       test_li_length_in_bytes    = 0;
    unsigned int       test_remaining_size_to_substract= 0;
    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;
    unsigned int       data_pdu_size                      = 0;

    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;
    unsigned int       max_li_overhead                     = 0;

    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) {
181
182
183
        return;
    }

gauthier's avatar
gauthier committed
184
    //msg ("[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT]\n", rlc_pP->module_id, rlc_pP->rb_id, frameP);
185
    list_init (&pdus, NULL);    // param string identifying the list is NULL
gauthier's avatar
gauthier committed
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
    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) {
201
202
                max_li_overhead = 0;
            } else {
gauthier's avatar
gauthier committed
203
                max_li_overhead = (((rlc_pP->nb_sdu_no_segmented - 1) * 3) / 2) + ((rlc_pP->nb_sdu_no_segmented - 1) % 2);
204
            }
gauthier's avatar
gauthier committed
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
            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);
221
222
            } else {
                data_pdu_size = nb_bytes_to_transmit;
gauthier's avatar
gauthier committed
223
224
225
226
227
228
229
               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);
230
            }
gauthier's avatar
gauthier committed
231
232
233
234
235
236
237
            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);
238
239
                return;
            }
gauthier's avatar
gauthier committed
240
241
242
243
244
245
246
            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);
247
            pdu_remaining_size = data_pdu_size - RLC_AM_HEADER_MIN_SIZE;
gauthier's avatar
gauthier committed
248
249
250
251
            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));
252

gauthier's avatar
gauthier committed
253
            memset (pdu_mem_p->data, 0, sizeof (rlc_am_pdu_sn_10_t)+sizeof(struct mac_tb_req));
254
255
256
257
258
259
260
261
            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
262
        sdu_buffer_index           = rlc_pP->current_sdu_index;
263
264
265
266
267
268
        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
269
270
        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];
271

gauthier's avatar
gauthier committed
272
            if (sdu_mngt_p->sdu_remaining_size > test_pdu_remaining_size) {
273
274
275
276
277
278
                // 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
279
            } else if (sdu_mngt_p->sdu_remaining_size == test_pdu_remaining_size) {
280
281
282
283
284
285
                // 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
286
            } else if ((sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3)) == test_pdu_remaining_size ) {
287
288
289
290
291
292
293
                // 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
294
295
            } 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)) {
296
297
298
299
300
301
302
303
304
                    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
305
                    test_pdu_remaining_size = test_pdu_remaining_size - (sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3));
306
307
308
309
310
                    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
311
312
313
314
315
316
317
318
319
                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);
320
321
322
323
324
325
326
327
                // 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
328
329
330
            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);
331
332
333
334
335
336
337
338
            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
339
        // Do the real filling of the pdu_p
340
        //----------------------------------------
gauthier's avatar
gauthier committed
341
342
343
344
345
346
347
348
349
350
351
        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);
352
353
354
355
356
357
        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
358
359
        if (rlc_pP->input_sdus[rlc_pP->current_sdu_index].sdu_remaining_size ==
            rlc_pP->input_sdus[rlc_pP->current_sdu_index].sdu_size) {
360
361
            fi_first_byte_pdu_is_first_byte_sdu = 1;
        }
gauthier's avatar
gauthier committed
362
363
364
365
366
367
368
369
370
371
372
        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);
373
            } else {
gauthier's avatar
gauthier committed
374
375
376
377
378
379
380
381
382
                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);
383
            }
gauthier's avatar
gauthier committed
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
            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;
400
401
                fi_last_byte_pdu_is_last_byte_sdu = 0;
                // no LI
gauthier's avatar
gauthier committed
402
                rlc_pP->sdu_buffer_occupancy -= pdu_remaining_size;
403
404
                continue_fill_pdu_with_sdu = 0;
                pdu_remaining_size = 0;
gauthier's avatar
gauthier committed
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
                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;
423
424

                // free SDU
gauthier's avatar
gauthier committed
425
426
427
428
429
430
                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;
431
432
433
434
435

                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
436
            } else if ((sdu_mngt_p->sdu_remaining_size + (li_length_in_bytes ^ 3)) < pdu_remaining_size ) {
437
                if (fill_num_li == (RLC_AM_MAX_SDU_IN_PDU - 1)) {
gauthier's avatar
gauthier committed
438
439
440
441
442
443
444
445
446
447
                    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;
448
                    // free SDU
gauthier's avatar
gauthier committed
449
450
451
452
453
                    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;
454
455
456
457
458

                    // 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
459
460
461
462
463
464
465
466
467
468
                    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];
469
470
471
472
                    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
473
474
                            //e_li_p->e1  = 0;
                            e_li_p->b1 = 0;
475
                        } else {
gauthier's avatar
gauthier committed
476
477
                            //e_li_p->e1  = 1;
                            e_li_p->b1 =  0x80;
478
                        }
gauthier's avatar
gauthier committed
479
480
481
482
483
484
485
486
487
488
489
490
491
                        //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);
492
493
                    } else {
                        if (fill_num_li != test_num_li) {
gauthier's avatar
gauthier committed
494
495
                            //e_li_p->e2  = 1;
                            e_li_p->b2  = e_li_p->b2 | 0x08;
496
                        }
gauthier's avatar
gauthier committed
497
498
499
500
501
502
503
504
505
506
507
508
509
510
                        //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++;
511
512
                    }

gauthier's avatar
gauthier committed
513
                    pdu_remaining_size = pdu_remaining_size - (sdu_mngt_p->sdu_remaining_size + li_length_in_bytes);
514
                    // free SDU
gauthier's avatar
gauthier committed
515
516
517
518
519
520
521
522
                    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;
523
524
                }
            } else {
gauthier's avatar
gauthier committed
525
526
527
528
529
530
531
532
                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);
533
534
535
#ifdef USER_MODE
                assert(1!=1);
#endif
gauthier's avatar
gauthier committed
536
537
538
                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;
539
                // free SDU
gauthier's avatar
gauthier committed
540
541
542
543
544
                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;
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560

                // 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
561
        pdu_p->b1 = pdu_p->b1 | (fi << 3);
562
563
564

        // set fist e bit
        if (fill_num_li > 0) {
gauthier's avatar
gauthier committed
565
            pdu_p->b1 = pdu_p->b1 | 0x04;
566
        }
gauthier's avatar
gauthier committed
567
568
569
570
571
572
573
        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,
574
             data_pdu_size - pdu_remaining_size,
gauthier's avatar
gauthier committed
575
             pdu_mngt_p->payload_size);
576

gauthier's avatar
gauthier committed
577
578
        rlc_pP->stat_tx_data_pdu   += 1;
        rlc_pP->stat_tx_data_bytes += (data_pdu_size - pdu_remaining_size);
579

gauthier's avatar
gauthier committed
580
581
582
583
584
        //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;
585

gauthier's avatar
gauthier committed
586
587
        pdu_tb_req_p->data_ptr        = (unsigned char*)pdu_p;
        pdu_tb_req_p->tb_size         = data_pdu_size - pdu_remaining_size;
588

gauthier's avatar
gauthier committed
589
590
        assert(pdu_tb_req_p->tb_size < 3000);
        rlc_am_pdu_polling(rlc_pP, frameP,pdu_p, pdu_mngt_p->payload_size);
591

gauthier's avatar
gauthier committed
592
593
594
595
596
        //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;
597

gauthier's avatar
gauthier committed
598
599
        rlc_pP->retrans_num_pdus  += 1;
        rlc_pP->retrans_num_bytes += pdu_mngt_p->header_and_payload_size;
600

gauthier's avatar
gauthier committed
601
602
        pdu_p = NULL;
        pdu_mem_p = NULL;
603
604
605
606

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

gauthier's avatar
gauthier committed
607
608
        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);
609
610
611

    }
}