rlc_am_init.c 11.6 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
24
25
    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
  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
#define RLC_AM_MODULE
#define RLC_AM_INIT_C
#ifdef USER_MODE
#include <string.h>
#endif
//-----------------------------------------------------------------------------
#include "rlc_am.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
//-----------------------------------------------------------------------------
39
40
41
42
void
rlc_am_init(
                const protocol_ctxt_t* const  ctxt_pP,
                rlc_am_entity_t *const        rlc_pP)
43
44
//-----------------------------------------------------------------------------
{
45
    if (rlc_pP->initialized == TRUE) {
46
        LOG_D(RLC, "[FRAME %5u][RLC_AM][MOD XX][RB XX][INIT] INITIALIZATION ALREADY DONE, DOING NOTHING\n", ctxt_pP->frame);
47
    } else {
48
        LOG_D(RLC, "[FRAME %5u][RLC_AM][MOD XX][RB XX][INIT] INITIALIZATION: STATE VARIABLES, BUFFERS, LISTS\n", ctxt_pP->frame);
49
        memset(rlc_pP, 0, sizeof(rlc_am_entity_t));
gauthier's avatar
gauthier committed
50

51
52
53
54
55
        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));
56

gauthier's avatar
gauthier committed
57
        pthread_mutex_init(&rlc_pP->lock_input_sdus, NULL);
58
        rlc_pP->input_sdus               = calloc(1, RLC_AM_SDU_CONTROL_BUFFER_SIZE*sizeof(rlc_am_tx_sdu_management_t));
59
60
61
#warning "cast the rlc retrans buffer to uint32"
	//        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)));
        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)));
62
63
        LOG_D(RLC, "[FRAME %5u][RLC_AM][MOD XX][RB XX][INIT] input_sdus[] = %p  element size=%d\n", ctxt_pP->frame, rlc_pP->input_sdus,sizeof(rlc_am_tx_sdu_management_t));
        LOG_D(RLC, "[FRAME %5u][RLC_AM][MOD XX][RB XX][INIT] pdu_retrans_buffer[] = %p element size=%d\n", ctxt_pP->frame, rlc_pP->pdu_retrans_buffer,sizeof(rlc_am_tx_data_pdu_management_t));
gauthier's avatar
gauthier committed
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
        // 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;
82

83
84
        rlc_pP->initialized                  = TRUE;
    }
85
}
86
//-----------------------------------------------------------------------------
87
88
89
90
void
rlc_am_reestablish(
                const protocol_ctxt_t* const  ctxt_pP,
                rlc_am_entity_t* const        rlc_pP)
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//-----------------------------------------------------------------------------
{
    /*
     * 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.
     */
107
    LOG_D(RLC, "[FRAME %5u][RLC_AM][MOD XX][RB XX][REESTABLISH] RE-INIT STATE VARIABLES, BUFFERS, LISTS\n", ctxt_pP->frame);
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

#warning TODO when possible reassemble RLC SDUs from any byte segments of AMD PDUs with SN inf VR(MR)
    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);


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

}

141
//-----------------------------------------------------------------------------
142
143
144
145
void
rlc_am_cleanup(
                const protocol_ctxt_t* const  ctxt_pP,
                rlc_am_entity_t* const        rlc_pP)
146
147
//-----------------------------------------------------------------------------
{
148
    LOG_I(RLC, "[FRAME ?????][%s][RLC_AM][MOD %u/%u][RB %u][CLEANUP]\n",
149
150
151
          (ctxt_pP->enb_flag) ? "eNB" : "UE",
          ctxt_pP->enb_module_id,
          ctxt_pP->ue_module_id,
gauthier's avatar
gauthier committed
152
153
154
155
156
157
158
159
160
161
162
          rlc_pP->rb_id);

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


    if (rlc_pP->output_sdu_in_construction != NULL) {
        free_mem_block(rlc_pP->output_sdu_in_construction);
        rlc_pP->output_sdu_in_construction = NULL;
163
164
    }
    unsigned int i;
165
    if (rlc_pP->input_sdus != NULL) {
166
        for (i=0; i < RLC_AM_SDU_CONTROL_BUFFER_SIZE; i++) {
gauthier's avatar
gauthier committed
167
168
169
            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;
170
171
            }
        }
172
        free(rlc_pP->input_sdus);
gauthier's avatar
gauthier committed
173
        rlc_pP->input_sdus       = NULL;
174
    }
gauthier's avatar
gauthier committed
175
    pthread_mutex_destroy(&rlc_pP->lock_input_sdus);
176
    if (rlc_pP->pdu_retrans_buffer != NULL) {
177
        for (i=0; i < RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE; i++) {
gauthier's avatar
gauthier committed
178
179
180
            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;
181
182
            }
        }
183
        free(rlc_pP->pdu_retrans_buffer);
gauthier's avatar
gauthier committed
184
        rlc_pP->pdu_retrans_buffer       = NULL;
185
    }
gauthier's avatar
gauthier committed
186
    memset(rlc_pP, 0, sizeof(rlc_am_entity_t));
187
188
}
//-----------------------------------------------------------------------------
189
190
191
192
193
194
195
196
197
198
void
rlc_am_configure(
                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)
199
200
//-----------------------------------------------------------------------------
{
201
202
  if (rlc_pP->configured == TRUE) {
      LOG_I(RLC, "[FRAME %5u][%s][RLC_AM][MOD %u/%u][RB %u][RECONFIGURE] max_retx_threshold %d poll_pdu %d poll_byte %d t_poll_retransmit %d t_reordering %d t_status_prohibit %d\n",
203
204
205
206
          ctxt_pP->frame,
          (ctxt_pP->enb_flag) ? "eNB" : "UE",
          ctxt_pP->enb_module_id,
          ctxt_pP->ue_module_id,
gauthier's avatar
gauthier committed
207
208
209
210
211
212
213
214
          rlc_pP->rb_id,
          max_retx_thresholdP,
          poll_pduP,
          poll_byteP,
          t_poll_retransmitP,
          t_reorderingP,
          t_status_prohibitP);

215
216
217
218
219
220
221
222
223
224
      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_pP->t_poll_retransmit.time_out   = t_poll_retransmitP;
      rlc_pP->t_reordering.time_out        = t_reorderingP;
      rlc_pP->t_status_prohibit.time_out   = t_status_prohibitP;
  } else {
      LOG_I(RLC, "[FRAME %5u][%s][RLC_AM][MOD %u/%u][RB %u][CONFIGURE] max_retx_threshold %d poll_pdu %d poll_byte %d t_poll_retransmit %d t_reordering %d t_status_prohibit %d\n",
225
226
227
228
          ctxt_pP->frame,
          (ctxt_pP->enb_flag) ? "eNB" : "UE",
          ctxt_pP->enb_module_id,
          ctxt_pP->ue_module_id,
229
230
231
232
233
234
235
236
237
238
239
240
241
242
          rlc_pP->rb_id,
          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;


243
244
245
      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);
246
247
248

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

250
251
}
//-----------------------------------------------------------------------------
252
253
254
255
256
257
void
rlc_am_set_debug_infos(
                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)
258
259
//-----------------------------------------------------------------------------
{
260
    LOG_D(RLC, "[FRAME %5u][%s][RLC_AM][MOD %u/%u][RB %u][SET DEBUG INFOS] module_id %d rb_id %d is SRB %d\n",
261
262
263
264
          ctxt_pP->frame,
          (ctxt_pP->enb_flag) ? "eNB" : "UE",
          ctxt_pP->enb_module_id,
          ctxt_pP->ue_module_id,
gauthier's avatar
gauthier committed
265
          rb_idP,
266
267
          ctxt_pP->enb_module_id,
          ctxt_pP->ue_module_id,
gauthier's avatar
gauthier committed
268
          rb_idP,
269
          (srb_flagP) ? "TRUE" : "FALSE");
gauthier's avatar
gauthier committed
270

271

gauthier's avatar
gauthier committed
272
    rlc_pP->rb_id         = rb_idP;
273
    if (srb_flagP) {
gauthier's avatar
gauthier committed
274
      rlc_pP->is_data_plane = 0;
275
276
    } else {
      rlc_pP->is_data_plane = 1;
277
278
    }
}