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

    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.


    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.

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

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

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
#define RLC_AM_MODULE 1
#define RLC_AM_INIT_C 1
31
32
33
34
35
36
37
38
#ifdef USER_MODE
#include <string.h>
#endif
//-----------------------------------------------------------------------------
#include "rlc_am.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
//-----------------------------------------------------------------------------
39
40
void
rlc_am_init(
41
42
  const protocol_ctxt_t* const  ctxt_pP,
  rlc_am_entity_t *const        rlc_pP)
43
{
44
  if (rlc_pP->initialized == TRUE) {
45
46
    LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] INITIALIZATION ALREADY DONE, DOING NOTHING\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
47
  } else {
48
49
    LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] INITIALIZATION: STATE VARIABLES, BUFFERS, LISTS\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
50
51
52
53
54
55
56
57
58
59
    memset(rlc_pP, 0, sizeof(rlc_am_entity_t));

    list2_init(&rlc_pP->receiver_buffer,      "RX BUFFER");
    list_init(&rlc_pP->pdus_to_mac_layer,     "PDUS TO MAC");
    list_init(&rlc_pP->control_pdu_list,      "CONTROL PDU LIST");
    list_init(&rlc_pP->segmentation_pdu_list, "SEGMENTATION PDU LIST");
    //LOG_D(RLC,"RLC_AM_SDU_CONTROL_BUFFER_SIZE %d sizeof(rlc_am_tx_sdu_management_t) %d \n",  RLC_AM_SDU_CONTROL_BUFFER_SIZE, sizeof(rlc_am_tx_sdu_management_t));

    pthread_mutex_init(&rlc_pP->lock_input_sdus, NULL);
    rlc_pP->input_sdus               = calloc(1, RLC_AM_SDU_CONTROL_BUFFER_SIZE*sizeof(rlc_am_tx_sdu_management_t));
60
#warning "cast the rlc retrans buffer to uint32"
61
    //        rlc_pP->pdu_retrans_buffer       = calloc(1, (uint16_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof(rlc_am_tx_data_pdu_management_t)));
62
63
64
65
    rlc_pP->pdu_retrans_buffer       = calloc(1, (uint32_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof(
                                         rlc_am_tx_data_pdu_management_t)));
    LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] input_sdus[] = %p  element size=%d\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
66
67
          rlc_pP->input_sdus,
          sizeof(rlc_am_tx_sdu_management_t));
68
69
    LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] pdu_retrans_buffer[] = %p element size=%d\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
          rlc_pP->pdu_retrans_buffer,
          sizeof(rlc_am_tx_data_pdu_management_t));

    // TX state variables
    //rlc_pP->vt_a    = 0;
    rlc_pP->vt_ms   = rlc_pP->vt_a + RLC_AM_WINDOW_SIZE;
    //rlc_pP->vt_s    = 0;
    //rlc_pP->poll_sn = 0;
    // TX counters
    //rlc_pP->c_pdu_without_poll  = 0;
    //rlc_pP->c_byte_without_poll = 0;
    // RX state variables
    //rlc_pP->vr_r    = 0;
    rlc_pP->vr_mr   = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE;
    //rlc_pP->vr_x    = 0;
    //rlc_pP->vr_ms   = 0;
    //rlc_pP->vr_h    = 0;

    rlc_pP->last_frame_status_indication = 123456; // any value > 1
    rlc_pP->first_retrans_pdu_sn         = -1;

    rlc_pP->initialized                  = TRUE;
  }
93
}
94
//-----------------------------------------------------------------------------
95
96
void
rlc_am_reestablish(
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
  /*
   * RLC re-establishment is performed upon request by RRC, and the function
   * is applicable for AM, UM and TM RLC entities.
   * When RRC indicates that an RLC entity should be re-established, the RLC entity shall:
   * - if it is an AM RLC entity:
   *    - when possible, reassemble RLC SDUs from any byte segments of AMD PDUs with SN < VR(MR) in the
   *       receiving side, remove RLC headers when doing so and deliver all reassembled RLC SDUs to upper layer in
   *        ascending order of the RLC SN, if not delivered before;
   *    - discard the remaining AMD PDUs and byte segments of AMD PDUs in the receiving side;
   *    - discard all RLC SDUs and AMD PDUs in the transmitting side;
   *    - discard all RLC control PDUs.
   *    - stop and reset all timers;
   *    - reset all state variables to their initial values.
   */
114
115
  LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM REESTABLISH] RE-INIT STATE VARIABLES, BUFFERS, LISTS\n",
        PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
116
117

#warning TODO when possible reassemble RLC SDUs from any byte segments of AMD PDUs with SN inf VR(MR)
118
  list2_free(&rlc_pP->receiver_buffer);
119

120
121
122
  list_free(&rlc_pP->pdus_to_mac_layer);
  list_free(&rlc_pP->control_pdu_list);
  list_free(&rlc_pP->segmentation_pdu_list);
123
124


125
126
127
128
129
  // TX state variables
  rlc_pP->vt_a    = 0;
  rlc_pP->vt_ms   = rlc_pP->vt_a + RLC_AM_WINDOW_SIZE;
  rlc_pP->vt_s    = 0;
  rlc_pP->poll_sn = 0;
130

131
132
133
  // TX counters
  rlc_pP->c_pdu_without_poll  = 0;
  rlc_pP->c_byte_without_poll = 0;
134

135
136
137
138
139
140
  // RX state variables
  rlc_pP->vr_r    = 0;
  rlc_pP->vr_mr   = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE;
  rlc_pP->vr_x    = 0;
  rlc_pP->vr_ms   = 0;
  rlc_pP->vr_h    = 0;
141

142
143
  rlc_pP->last_frame_status_indication = 123456; // any value > 1
  rlc_pP->first_retrans_pdu_sn         = -1;
144

145
  rlc_pP->initialized                  = TRUE;
146
147
148

}

149
//-----------------------------------------------------------------------------
150
151
void
rlc_am_cleanup(
152
153
  rlc_am_entity_t* const        rlc_pP
)
154
{
155
156
157
158
  list2_free(&rlc_pP->receiver_buffer);
  list_free(&rlc_pP->pdus_to_mac_layer);
  list_free(&rlc_pP->control_pdu_list);
  list_free(&rlc_pP->segmentation_pdu_list);
gauthier's avatar
gauthier committed
159
160


161
162
163
164
165
166
167
168
169
170
171
172
173
  if (rlc_pP->output_sdu_in_construction != NULL) {
    free_mem_block(rlc_pP->output_sdu_in_construction);
    rlc_pP->output_sdu_in_construction = NULL;
  }

  unsigned int i;

  if (rlc_pP->input_sdus != NULL) {
    for (i=0; i < RLC_AM_SDU_CONTROL_BUFFER_SIZE; i++) {
      if (rlc_pP->input_sdus[i].mem_block != NULL) {
        free_mem_block(rlc_pP->input_sdus[i].mem_block);
        rlc_pP->input_sdus[i].mem_block = NULL;
      }
174
    }
175
176
177
178
179
180
181
182
183
184
185
186
187

    free(rlc_pP->input_sdus);
    rlc_pP->input_sdus       = NULL;
  }

  pthread_mutex_destroy(&rlc_pP->lock_input_sdus);

  if (rlc_pP->pdu_retrans_buffer != NULL) {
    for (i=0; i < RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE; i++) {
      if (rlc_pP->pdu_retrans_buffer[i].mem_block != NULL) {
        free_mem_block(rlc_pP->pdu_retrans_buffer[i].mem_block);
        rlc_pP->pdu_retrans_buffer[i].mem_block = NULL;
      }
188
    }
189
190
191
192
193
194

    free(rlc_pP->pdu_retrans_buffer);
    rlc_pP->pdu_retrans_buffer       = NULL;
  }

  memset(rlc_pP, 0, sizeof(rlc_am_entity_t));
195
196
}
//-----------------------------------------------------------------------------
197
198
void
rlc_am_configure(
199
200
201
202
203
204
205
206
  const protocol_ctxt_t* const  ctxt_pP,
  rlc_am_entity_t *const        rlc_pP,
  const uint16_t                max_retx_thresholdP,
  const uint16_t                poll_pduP,
  const uint16_t                poll_byteP,
  const uint32_t                t_poll_retransmitP,
  const uint32_t                t_reorderingP,
  const uint32_t                t_status_prohibitP)
207
{
208
  if (rlc_pP->configured == TRUE) {
209
210
    LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RECONFIGURE] max_retx_threshold %d poll_pdu %d poll_byte %d t_poll_retransmit %d t_reordering %d t_status_prohibit %d\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
gauthier's avatar
gauthier committed
211
212
213
214
215
216
217
          max_retx_thresholdP,
          poll_pduP,
          poll_byteP,
          t_poll_retransmitP,
          t_reorderingP,
          t_status_prohibitP);

218
219
220
221
    rlc_pP->max_retx_threshold = max_retx_thresholdP;
    rlc_pP->poll_pdu           = poll_pduP;
    rlc_pP->poll_byte          = poll_byteP;
    rlc_pP->protocol_state     = RLC_DATA_TRANSFER_READY_STATE;
222
223
224
    rlc_pP->t_poll_retransmit.ms_duration   = t_poll_retransmitP;
    rlc_pP->t_reordering.ms_duration        = t_reorderingP;
    rlc_pP->t_status_prohibit.ms_duration   = t_status_prohibitP;
225
226

  } else {
227
228
    LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[CONFIGURE] max_retx_threshold %d poll_pdu %d poll_byte %d t_poll_retransmit %d t_reordering %d t_status_prohibit %d\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
          max_retx_thresholdP,
          poll_pduP,
          poll_byteP,
          t_poll_retransmitP,
          t_reorderingP,
          t_status_prohibitP);

    rlc_pP->max_retx_threshold = max_retx_thresholdP;
    rlc_pP->poll_pdu           = poll_pduP;
    rlc_pP->poll_byte          = poll_byteP;
    rlc_pP->protocol_state     = RLC_DATA_TRANSFER_READY_STATE;


    rlc_am_init_timer_poll_retransmit(ctxt_pP, rlc_pP, t_poll_retransmitP);
    rlc_am_init_timer_reordering     (ctxt_pP, rlc_pP, t_reorderingP);
    rlc_am_init_timer_status_prohibit(ctxt_pP, rlc_pP, t_status_prohibitP);

    rlc_pP->configured = TRUE;
247
  }
gauthier's avatar
gauthier committed
248

249
250
}
//-----------------------------------------------------------------------------
251
252
void
rlc_am_set_debug_infos(
253
254
255
256
  const protocol_ctxt_t* const  ctxt_pP,
  rlc_am_entity_t *const        rlc_pP,
  const srb_flag_t              srb_flagP,
  const rb_id_t                 rb_idP)
257
{
258

259
260
261
262
263
264
265
266
  rlc_pP->rb_id         = rb_idP;

  if (srb_flagP) {
    rlc_pP->is_data_plane = 0;
  } else {
    rlc_pP->is_data_plane = 1;
  }

267
268
  LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SET DEBUG INFOS]\n",
        PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
269

270
}