rlc_am_segment.c 30.9 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
38
39
40
41
42
43
44
#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"

//-----------------------------------------------------------------------------
45
46
47
48
49
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)
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
78
//-----------------------------------------------------------------------------
{
    // 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
79
80
    rlc_pP->c_pdu_without_poll     += 1;
    rlc_pP->c_byte_without_poll    += payload_sizeP;
81
82

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

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

gauthier's avatar
gauthier committed
127
128
129
        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);
130
        //optimisation } else {
gauthier's avatar
gauthier committed
131
        //optimisation     rlc_pP->t_poll_retransmit.frame_time_out = frameP + rlc_pP->t_poll_retransmit.time_out;
132
133
        //optimisation }
    } else {
gauthier's avatar
gauthier committed
134
        pdu_pP->b1 = pdu_pP->b1 & 0xDF;
135
136
137
    }
}
//-----------------------------------------------------------------------------
138
139
140
void rlc_am_segment_10 (
        rlc_am_entity_t *const rlc_pP,
        const frame_t frameP)
141
142
143
{
//-----------------------------------------------------------------------------
    list_t              pdus;
144
145
    sdu_size_t          pdu_remaining_size      = 0;
    sdu_size_t          test_pdu_remaining_size = 0;
gauthier's avatar
gauthier committed
146

147
    sdu_size_t                       nb_bytes_to_transmit = rlc_pP->nb_bytes_requested_by_mac;
gauthier's avatar
gauthier committed
148
149
150
151
152
153
154
155
156
    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;

157
158
159
    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
160
161
162
163
164
165
    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;
166
    sdu_size_t         data_pdu_size                      = 0;
gauthier's avatar
gauthier committed
167
168
169
170

    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;
171
    signed int         max_li_overhead                     = 0;
gauthier's avatar
gauthier committed
172
173
174
175
176
177
178
179
180
181
182
183

    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) {
184
185
186
        return;
    }

gauthier's avatar
gauthier committed
187
    //msg ("[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT]\n", rlc_pP->module_id, rlc_pP->rb_id, frameP);
188
    list_init (&pdus, NULL);    // param string identifying the list is NULL
gauthier's avatar
gauthier committed
189
190
191
    pdu_mem_p = NULL;


gauthier's avatar
gauthier committed
192
    pthread_mutex_lock(&rlc_pP->lock_input_sdus);
gauthier's avatar
gauthier committed
193
194
195
196
197
198
199
200
201
202
203
204
    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) {
205
206
                max_li_overhead = 0;
            } else {
gauthier's avatar
gauthier committed
207
                max_li_overhead = (((rlc_pP->nb_sdu_no_segmented - 1) * 3) / 2) + ((rlc_pP->nb_sdu_no_segmented - 1) % 2);
208
            }
gauthier's avatar
gauthier committed
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
            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);
225
226
            } else {
                data_pdu_size = nb_bytes_to_transmit;
gauthier's avatar
gauthier committed
227
228
229
230
231
232
233
               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);
234
            }
gauthier's avatar
gauthier committed
235
236
237
238
239
240
241
            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);
gauthier's avatar
gauthier committed
242
                pthread_mutex_unlock(&rlc_pP->lock_input_sdus);
243
244
                return;
            }
gauthier's avatar
gauthier committed
245
246
247
248
249
250
251
            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);
252
            pdu_remaining_size = data_pdu_size - RLC_AM_HEADER_MIN_SIZE;
gauthier's avatar
gauthier committed
253
254
255
256
            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));
257

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

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

                // free SDU
gauthier's avatar
gauthier committed
430
431
432
433
434
435
                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;
436
437
438
439
440

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

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

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

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

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

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

gauthier's avatar
gauthier committed
585
586
587
588
589
        //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;
590

gauthier's avatar
gauthier committed
591
592
        pdu_tb_req_p->data_ptr        = (unsigned char*)pdu_p;
        pdu_tb_req_p->tb_size         = data_pdu_size - pdu_remaining_size;
593
594
#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
595
        rlc_am_pdu_polling(rlc_pP, frameP,pdu_p, pdu_mngt_p->payload_size);
596

gauthier's avatar
gauthier committed
597
598
599
600
601
        //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;
602

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

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

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

gauthier's avatar
gauthier committed
612
613
        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);
614
615

    }
gauthier's avatar
gauthier committed
616
    pthread_mutex_unlock(&rlc_pP->lock_input_sdus);
617
}