rlc_am_init.c 11.4 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"
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
39
void rlc_am_init(rlc_am_entity_t *rlc_pP, frame_t frameP)
40
41
//-----------------------------------------------------------------------------
{
42
    if (rlc_pP->initialized == TRUE) {
43
        LOG_D(RLC, "[FRAME %5u][RLC_AM][MOD XX][RB XX][INIT] INITIALIZATION ALREADY DONE, DOING NOTHING\n", frameP);
44
    } else {
45
        LOG_D(RLC, "[FRAME %5u][RLC_AM][MOD XX][RB XX][INIT] INITIALIZATION: STATE VARIABLES, BUFFERS, LISTS\n", frameP);
46
        memset(rlc_pP, 0, sizeof(rlc_am_entity_t));
gauthier's avatar
gauthier committed
47

48
49
50
51
52
        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));
53

gauthier's avatar
gauthier committed
54
        pthread_mutex_init(&rlc_pP->lock_input_sdus, NULL);
55
        rlc_pP->input_sdus               = calloc(1, RLC_AM_SDU_CONTROL_BUFFER_SIZE*sizeof(rlc_am_tx_sdu_management_t));
56
57
58
#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)));
59
60
        LOG_D(RLC, "[FRAME %5u][RLC_AM][MOD XX][RB XX][INIT] input_sdus[] = %p  element size=%d\n", frameP, 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", frameP, rlc_pP->pdu_retrans_buffer,sizeof(rlc_am_tx_data_pdu_management_t));
gauthier's avatar
gauthier committed
61

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

80
81
        rlc_pP->initialized                  = TRUE;
    }
82
}
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
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
131
132
133
134
//-----------------------------------------------------------------------------
void rlc_am_reestablish(rlc_am_entity_t *rlc_pP, frame_t frameP)
//-----------------------------------------------------------------------------
{
    /*
     * 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.
     */
    LOG_D(RLC, "[FRAME %5u][RLC_AM][MOD XX][RB XX][REESTABLISH] RE-INIT STATE VARIABLES, BUFFERS, LISTS\n", frameP);

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

}

135
//-----------------------------------------------------------------------------
136
void rlc_am_cleanup(rlc_am_entity_t *rlc_pP)
137
138
//-----------------------------------------------------------------------------
{
139
    LOG_I(RLC, "[FRAME ?????][%s][RLC_AM][MOD %u/%u][RB %u][CLEANUP]\n",
gauthier's avatar
gauthier committed
140
141
142
143
144
145
146
147
148
149
150
151
152
153
          (rlc_pP->is_enb) ? "eNB" : "UE",
          rlc_pP->enb_module_id,
          rlc_pP->ue_module_id,
          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;
154
155
    }
    unsigned int i;
156
    if (rlc_pP->input_sdus != NULL) {
157
        for (i=0; i < RLC_AM_SDU_CONTROL_BUFFER_SIZE; i++) {
gauthier's avatar
gauthier committed
158
159
160
            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;
161
162
            }
        }
163
        free(rlc_pP->input_sdus);
gauthier's avatar
gauthier committed
164
        rlc_pP->input_sdus       = NULL;
165
    }
gauthier's avatar
gauthier committed
166
    pthread_mutex_destroy(&rlc_pP->lock_input_sdus);
167
    if (rlc_pP->pdu_retrans_buffer != NULL) {
168
        for (i=0; i < RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE; i++) {
gauthier's avatar
gauthier committed
169
170
171
            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;
172
173
            }
        }
174
        free(rlc_pP->pdu_retrans_buffer);
gauthier's avatar
gauthier committed
175
        rlc_pP->pdu_retrans_buffer       = NULL;
176
    }
gauthier's avatar
gauthier committed
177
    memset(rlc_pP, 0, sizeof(rlc_am_entity_t));
178
179
}
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
180
181
void rlc_am_configure(rlc_am_entity_t *rlc_pP,
		      frame_t          frameP,
gauthier's avatar
gauthier committed
182
183
184
185
186
187
                      uint16_t            max_retx_thresholdP,
                      uint16_t            poll_pduP,
                      uint16_t            poll_byteP,
                      uint32_t            t_poll_retransmitP,
                      uint32_t            t_reorderingP,
                      uint32_t            t_status_prohibitP)
188
189
//-----------------------------------------------------------------------------
{
190
191
  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",
gauthier's avatar
gauthier committed
192
193
194
195
196
197
198
199
200
201
202
203
          frameP,
          (rlc_pP->is_enb) ? "eNB" : "UE",
          rlc_pP->enb_module_id,
          rlc_pP->ue_module_id,
          rlc_pP->rb_id,
          max_retx_thresholdP,
          poll_pduP,
          poll_byteP,
          t_poll_retransmitP,
          t_reorderingP,
          t_status_prohibitP);

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
      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",
          frameP,
          (rlc_pP->is_enb) ? "eNB" : "UE",
          rlc_pP->enb_module_id,
          rlc_pP->ue_module_id,
          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;


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

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

239
240
}
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
241
242
243
void rlc_am_set_debug_infos(rlc_am_entity_t *rlc_pP,
                            frame_t          frameP,
                            eNB_flag_t       eNB_flagP,
244
                            srb_flag_t       srb_flagP,
gauthier's avatar
gauthier committed
245
246
                            module_id_t      enb_module_idP,
                            module_id_t      ue_module_idP,
247
                            rb_id_t          rb_idP)
248
249
//-----------------------------------------------------------------------------
{
250
    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",
gauthier's avatar
gauthier committed
251
252
253
254
255
256
257
258
          frameP,
          (rlc_pP->is_enb) ? "eNB" : "UE",
          rlc_pP->enb_module_id,
          rlc_pP->ue_module_id,
          rb_idP,
          enb_module_idP,
          ue_module_idP,
          rb_idP,
259
          (srb_flagP) ? "TRUE" : "FALSE");
gauthier's avatar
gauthier committed
260
261
262
263

    rlc_pP->enb_module_id = enb_module_idP;
    rlc_pP->ue_module_id  = ue_module_idP;
    rlc_pP->rb_id         = rb_idP;
264
    if (srb_flagP) {
gauthier's avatar
gauthier committed
265
      rlc_pP->is_data_plane = 0;
266
267
    } else {
      rlc_pP->is_data_plane = 1;
268
    }
gauthier's avatar
gauthier committed
269
    rlc_pP->is_enb = eNB_flagP;
270
}