rlc_am_segment.c 23.4 KB
Newer Older
1
2
#define RLC_AM_MODULE 1
#define RLC_AM_SEGMENT_C 1
3
//-----------------------------------------------------------------------------
4
#if USER_MODE
5
6
7
8
9
#include <assert.h>
#endif
//-----------------------------------------------------------------------------
#include "platform_types.h"
//-----------------------------------------------------------------------------
knopp's avatar
mutexes    
knopp committed
10
#include "msc.h"
11
12
13
14
15
16
#include "list.h"
#include "rlc_am.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"

//-----------------------------------------------------------------------------
17
void rlc_am_pdu_polling (
18
19
20
21
  const protocol_ctxt_t* const  ctxt_pP,
  rlc_am_entity_t *const rlc_pP,
  rlc_am_pdu_sn_10_t *const pdu_pP,
  const int16_t payload_sizeP)
22
{
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  // 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;
  rlc_pP->c_pdu_without_poll     += 1;
  rlc_pP->c_byte_without_poll    += payload_sizeP;

  if (
    (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)) ||
57
58
    (rlc_pP->vt_s == rlc_pP->vt_ms) ||
    (rlc_pP->force_poll == TRUE)
59
  ) {
60
	rlc_pP->force_poll = FALSE;
61
62

    if (rlc_pP->c_pdu_without_poll >= rlc_pP->poll_pdu) {
63
64
      LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[POLL] SET POLL BECAUSE TX NUM PDU THRESHOLD %d  HAS BEEN REACHED\n",
            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
65
            rlc_pP->poll_pdu);
66
    } else
67
    if (rlc_pP->c_byte_without_poll >= rlc_pP->poll_byte) {
68
69
      LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[POLL] SET POLL BECAUSE TX NUM BYTES THRESHOLD %d  HAS BEEN REACHED\n",
            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
70
            rlc_pP->poll_byte);
71
    } else
72
    if ((rlc_pP->sdu_buffer_occupancy == 0) && (rlc_pP->retrans_num_bytes_to_retransmit == 0)) {
73
74
      LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[POLL] SET POLL BECAUSE TX BUFFERS ARE EMPTY\n",
            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
75
    } else
76
    if (rlc_pP->vt_s == rlc_pP->vt_ms) {
77
78
      LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[POLL] SET POLL BECAUSE OF WINDOW STALLING\n",
            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
79
    }
80
81
82
83
84
85
86
87
88
89
90
91
92
93

    pdu_pP->b1 = pdu_pP->b1 | 0x20;
    rlc_pP->c_pdu_without_poll     = 0;
    rlc_pP->c_byte_without_poll    = 0;

    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(ctxt_pP, rlc_pP);
    //optimisation } else {
    //optimisation     rlc_pP->t_poll_retransmit.frame_time_out = ctxt_pP->frame + rlc_pP->t_poll_retransmit.time_out;
    //optimisation }
  } else {
    pdu_pP->b1 = pdu_pP->b1 & 0xDF;
  }
94
95
}
//-----------------------------------------------------------------------------
96
void rlc_am_segment_10 (
97
98
  const protocol_ctxt_t* const  ctxt_pP,
  rlc_am_entity_t *const rlc_pP)
99
{
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  list_t              pdus;
  sdu_size_t          pdu_remaining_size      = 0;
  sdu_size_t          test_pdu_remaining_size = 0;

  sdu_size_t                       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;

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

  LOG_T(RLC,
131
132
        PROTOCOL_RLC_AM_CTXT_FMT"[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",
        PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
133
134
135
136
137
138
139
140
141
142
143
144
145
146
        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) {
    return;
  }

  //msg ("[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT]\n", rlc_pP->module_id, rlc_pP->rb_id, ctxt_pP->frame);
  list_init (&pdus, NULL);    // param string identifying the list is NULL
  pdu_mem_p = NULL;


knopp's avatar
mutexes    
knopp committed
147
  RLC_AM_MUTEX_LOCK(&rlc_pP->lock_input_sdus, ctxt_pP, rlc_pP);
148
149

  while ((rlc_pP->input_sdus[rlc_pP->current_sdu_index].mem_block) && (nb_bytes_to_transmit > 0) ) {
150
151
    LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] nb_bytes_to_transmit %d BO %d\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
152
          nb_bytes_to_transmit,
gauthier's avatar
gauthier committed
153
          rlc_pP->sdu_buffer_occupancy);
154
155
156
157
158
159
160
161
162

    // pdu_p management
    if (!pdu_mem_p) {
      if (rlc_pP->nb_sdu_no_segmented <= 1) {
        max_li_overhead = 0;
      } else {
        max_li_overhead = (((rlc_pP->nb_sdu_no_segmented - 1) * 3) / 2) + ((rlc_pP->nb_sdu_no_segmented - 1) % 2);
      }

163
164
      LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] max_li_overhead %d\n",
            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
165
166
167
168
            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;
169
170
        LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] alloc PDU size %d bytes to contain not all bytes requested by MAC but all BO of RLC@1\n",
              PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
171
172
173
              data_pdu_size);
      } else {
        data_pdu_size = nb_bytes_to_transmit;
174
175
        LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] alloc PDU size %d bytes to contain all bytes requested by MAC@1\n",
              PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
176
177
178
179
              data_pdu_size);
      }

      if (!(pdu_mem_p = get_free_mem_block (data_pdu_size + sizeof(struct mac_tb_req)))) {
180
181
        LOG_C(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] ERROR COULD NOT GET NEW PDU, EXIT\n",
              PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
knopp's avatar
mutexes    
knopp committed
182
        RLC_AM_MUTEX_UNLOCK(&rlc_pP->lock_input_sdus);
183
        return;
184
185
      }

186
187
      LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] get new PDU %d bytes\n",
            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
188
189
190
191
192
193
194
195
196
            data_pdu_size);
      pdu_remaining_size = data_pdu_size - RLC_AM_HEADER_MIN_SIZE;
      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));

      memset (pdu_mem_p->data, 0, sizeof (rlc_am_pdu_sn_10_t)+sizeof(struct mac_tb_req));
      li_length_in_bytes = 1;
197
198
    }

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
    //----------------------------------------
    // compute how many SDUS can fill the PDU
    //----------------------------------------
    continue_fill_pdu_with_sdu = 1;
    num_fill_sdu               = 0;
    test_num_li                = 0;
    sdu_buffer_index           = rlc_pP->current_sdu_index;
    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;


    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];

      if (sdu_mngt_p->sdu_remaining_size > test_pdu_remaining_size) {
        // 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;
      } else if (sdu_mngt_p->sdu_remaining_size == test_pdu_remaining_size) {
        // 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;
      } else if ((sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3)) == test_pdu_remaining_size ) {
        // 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);
      } 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)) {
          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;
          test_pdu_remaining_size = test_pdu_remaining_size - (sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3));
          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 {
254
255
        LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] sdu_mngt_p->sdu_remaining_size=%d test_pdu_remaining_size=%d test_li_length_in_bytes=%d\n",
              PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
              sdu_mngt_p->sdu_remaining_size,
              test_pdu_remaining_size,
              test_li_length_in_bytes ^ 3);
        // 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;
      }

      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);
      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;
    }

    //----------------------------------------
    // Do the real filling of the pdu_p
    //----------------------------------------
283
284
    LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT" data shift %d Bytes num_li %d\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
          ((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);
    continue_fill_pdu_with_sdu          = 1;
    li_length_in_bytes                  = 1;
    fill_num_li                         = 0;
    fi_first_byte_pdu_is_first_byte_sdu = 0;
    fi_last_byte_pdu_is_last_byte_sdu   = 0;

    if (rlc_pP->input_sdus[rlc_pP->current_sdu_index].sdu_remaining_size ==
        rlc_pP->input_sdus[rlc_pP->current_sdu_index].sdu_size) {
      fi_first_byte_pdu_is_first_byte_sdu = 1;
    }
gauthier's avatar
gauthier committed
300

301
302
    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];
gauthier's avatar
gauthier committed
303

304
      if (sdu_mngt_p->sdu_segmented_size == 0) {
305
306
        LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] GET NEW SDU %p AVAILABLE SIZE %d Bytes\n",
              PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
307
308
309
              sdu_mngt_p,
              sdu_mngt_p->sdu_remaining_size);
      } else {
310
311
        LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] GET AGAIN SDU %p REMAINING AVAILABLE SIZE %d Bytes / %d Bytes LENGTH \n",
              PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
312
313
314
315
316
317
318
319
              sdu_mngt_p,
              sdu_mngt_p->sdu_remaining_size,
              sdu_mngt_p->sdu_size);
      }

      data_sdu_p = &sdu_mngt_p->first_byte[sdu_mngt_p->sdu_segmented_size];

      if (sdu_mngt_p->sdu_remaining_size > pdu_remaining_size) {
320
321
        LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] Filling all remaining PDU with %d bytes\n",
              PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
322
323
324
325
326
327
328
329
330
331
332
333
              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, ctxt_pP->frame, 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;
        fi_last_byte_pdu_is_last_byte_sdu = 0;
        // no LI
        rlc_pP->sdu_buffer_occupancy -= pdu_remaining_size;
        continue_fill_pdu_with_sdu = 0;
        pdu_remaining_size = 0;
334
335
        LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] sdu_remaining_size %d bytes sdu_segmented_size %d bytes\n",
              PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
336
337
338
              sdu_mngt_p->sdu_remaining_size,
              sdu_mngt_p->sdu_segmented_size);
      } else if (sdu_mngt_p->sdu_remaining_size == pdu_remaining_size) {
339
340
        LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] Exactly Filling remaining PDU with %d remaining bytes of SDU\n",
              PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
              pdu_remaining_size);
        memcpy(data, data_sdu_p, pdu_remaining_size);
        pdu_mngt_p->payload_size += pdu_remaining_size;

        // free SDU
        rlc_pP->sdu_buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
        rlc_am_free_in_sdu_data(ctxt_pP, 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;

        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;
      } else if ((sdu_mngt_p->sdu_remaining_size + (li_length_in_bytes ^ 3)) < pdu_remaining_size ) {
        if (fill_num_li == (RLC_AM_MAX_SDU_IN_PDU - 1)) {
359
360
          LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] [SIZE %d] REACHING RLC_AM_MAX_SDU_IN_PDU LIs -> STOP SEGMENTATION FOR THIS PDU SDU\n",
                PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
                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;
          // free SDU
          rlc_pP->sdu_buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
          rlc_am_free_in_sdu_data(ctxt_pP, 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;

          // reduce the size of the PDU
          continue_fill_pdu_with_sdu = 0;
          fi_last_byte_pdu_is_last_byte_sdu = 1;
        } else {
376
377
          LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] Filling  PDU with %d all remaining bytes of SDU\n",
                PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
378
379
380
381
382
383
384
385
386
387
388
                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];
          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) {
              //e_li_p->e1  = 0;
              e_li_p->b1 = 0;
389
            } else {
390
391
              //e_li_p->e1  = 1;
              e_li_p->b1 =  0x80;
392
            }
393
394
395
396

            //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;
397
398
            LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] set e_li_p->b1=0x%02X set e_li_p->b2=0x%02X fill_num_li=%d test_num_li=%d\n",
                  PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
399
400
401
402
403
404
405
406
                  e_li_p->b1,
                  e_li_p->b2,
                  fill_num_li,
                  test_num_li);
          } else {
            if (fill_num_li != test_num_li) {
              //e_li_p->e2  = 1;
              e_li_p->b2  = e_li_p->b2 | 0x08;
407
            }
408
409
410
411

            //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;
412
413
            LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] set e_li_p->b2=0x%02X set e_li_p->b3=0x%02X fill_num_li=%d test_num_li=%d\n",
                  PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
                  e_li_p->b2,
                  e_li_p->b3,
                  fill_num_li,
                  test_num_li);
            e_li_p++;
          }

          pdu_remaining_size = pdu_remaining_size - (sdu_mngt_p->sdu_remaining_size + li_length_in_bytes);
          // free SDU
          rlc_pP->sdu_buffer_occupancy  -= sdu_mngt_p->sdu_remaining_size;
          sdu_mngt_p->sdu_remaining_size = 0;

          rlc_am_free_in_sdu_data(ctxt_pP, 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
      } else {
433
434
        LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] Filling  PDU with %d all remaining bytes of SDU and reduce TB size by %d bytes\n",
              PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
435
436
              sdu_mngt_p->sdu_remaining_size,
              pdu_remaining_size - sdu_mngt_p->sdu_remaining_size);
437
#if USER_MODE
438
        assert(1!=1);
439
#endif
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
        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;
        // free SDU
        rlc_pP->sdu_buffer_occupancy -= sdu_mngt_p->sdu_remaining_size;
        rlc_am_free_in_sdu_data(ctxt_pP, 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;

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

456
457
458
459
460
461
    // set framing info
    if (fi_first_byte_pdu_is_first_byte_sdu) {
      fi = 0;
    } else {
      fi = 2;
    }
462

463
464
465
466
467
468
469
470
471
472
473
    if (!fi_last_byte_pdu_is_last_byte_sdu) {
      fi = fi + 1;
    }

    pdu_p->b1 = pdu_p->b1 | (fi << 3);

    // set fist e bit
    if (fill_num_li > 0) {
      pdu_p->b1 = pdu_p->b1 | 0x04;
    }

474
475
    LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] SEND PDU SN %04d  SIZE %d BYTES PAYLOAD SIZE %d BYTES\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
          rlc_pP->vt_s,
          data_pdu_size - pdu_remaining_size,
          pdu_mngt_p->payload_size);

    rlc_pP->stat_tx_data_pdu   += 1;
    rlc_pP->stat_tx_data_bytes += (data_pdu_size - pdu_remaining_size);

    //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;

    pdu_tb_req_p->data_ptr        = (unsigned char*)pdu_p;
    pdu_tb_req_p->tb_size         = data_pdu_size - pdu_remaining_size;
491
//#warning "why 3000: changed to RLC_SDU_MAX_SIZE "
492
493
494
495
496
497
498
499
    assert(pdu_tb_req_p->tb_size < RLC_SDU_MAX_SIZE );
    rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_p, pdu_mngt_p->payload_size);

    //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;
500

501
502
    rlc_pP->retrans_num_pdus  += 1;
    rlc_pP->retrans_num_bytes += pdu_mngt_p->header_and_payload_size;
503

504
505
    pdu_p = NULL;
    pdu_mem_p = NULL;
506

507
508
    //nb_bytes_to_transmit = nb_bytes_to_transmit - data_pdu_size;
    nb_bytes_to_transmit = 0; // 1 PDU only
509

510
511
    mem_block_t* copy = rlc_am_retransmit_get_copy (ctxt_pP, rlc_pP, (rlc_pP->vt_s-1) & RLC_AM_SN_MASK);
    list_add_tail_eurecom (copy, &rlc_pP->segmentation_pdu_list);
512

513
  }
514

knopp's avatar
mutexes    
knopp committed
515
  RLC_AM_MUTEX_UNLOCK(&rlc_pP->lock_input_sdus);
516
}