rlc_am_init.c 11.1 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
47
        LOG_D(RLC, PROTOCOL_CTXT_FMT"[AM INIT] INITIALIZATION ALREADY DONE, DOING NOTHING\n",
              PROTOCOL_CTXT_ARGS(ctxt_pP));
48
    } else {
49
50
        LOG_D(RLC, PROTOCOL_CTXT_FMT"[AM INIT] INITIALIZATION: STATE VARIABLES, BUFFERS, LISTS\n",
              PROTOCOL_CTXT_ARGS(ctxt_pP));
51
        memset(rlc_pP, 0, sizeof(rlc_am_entity_t));
gauthier's avatar
gauthier committed
52

53
54
55
56
57
        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));
58

gauthier's avatar
gauthier committed
59
        pthread_mutex_init(&rlc_pP->lock_input_sdus, NULL);
60
        rlc_pP->input_sdus               = calloc(1, RLC_AM_SDU_CONTROL_BUFFER_SIZE*sizeof(rlc_am_tx_sdu_management_t));
61
62
63
#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)));
64
65
66
67
68
69
70
71
        LOG_D(RLC, PROTOCOL_CTXT_FMT"[AM INIT] input_sdus[] = %p  element size=%d\n",
              PROTOCOL_CTXT_ARGS(ctxt_pP),
              rlc_pP->input_sdus,
              sizeof(rlc_am_tx_sdu_management_t));
        LOG_D(RLC, PROTOCOL_CTXT_FMT"[AM INIT] pdu_retrans_buffer[] = %p element size=%d\n",
              PROTOCOL_CTXT_ARGS(ctxt_pP),
              rlc_pP->pdu_retrans_buffer,
              sizeof(rlc_am_tx_data_pdu_management_t));
gauthier's avatar
gauthier committed
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
        // 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;
90

91
92
        rlc_pP->initialized                  = TRUE;
    }
93
}
94
//-----------------------------------------------------------------------------
95
96
97
98
void
rlc_am_reestablish(
                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
//-----------------------------------------------------------------------------
{
    /*
     * 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.
     */
115
116
    LOG_D(RLC, PROTOCOL_CTXT_FMT"[AM REESTABLISH] RE-INIT STATE VARIABLES, BUFFERS, LISTS\n",
          PROTOCOL_CTXT_ARGS(ctxt_pP));
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

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

}

150
//-----------------------------------------------------------------------------
151
152
void
rlc_am_cleanup(
153
154
                rlc_am_entity_t* const        rlc_pP
                )
155
156
//-----------------------------------------------------------------------------
{
157
158
159
    LOG_I(RLC, RB_AM_FMT"[CLEANUP %p]\n",
          RB_AM_ARGS(rlc_pP),
          rlc_pP);
gauthier's avatar
gauthier committed
160
161
162
163
164
165
166
167
168
169

    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;
170
171
    }
    unsigned int i;
172
    if (rlc_pP->input_sdus != NULL) {
173
        for (i=0; i < RLC_AM_SDU_CONTROL_BUFFER_SIZE; i++) {
gauthier's avatar
gauthier committed
174
175
176
            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;
177
178
            }
        }
179
        free(rlc_pP->input_sdus);
gauthier's avatar
gauthier committed
180
        rlc_pP->input_sdus       = NULL;
181
    }
gauthier's avatar
gauthier committed
182
    pthread_mutex_destroy(&rlc_pP->lock_input_sdus);
183
    if (rlc_pP->pdu_retrans_buffer != NULL) {
184
        for (i=0; i < RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE; i++) {
gauthier's avatar
gauthier committed
185
186
187
            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
        free(rlc_pP->pdu_retrans_buffer);
gauthier's avatar
gauthier committed
191
        rlc_pP->pdu_retrans_buffer       = NULL;
192
    }
gauthier's avatar
gauthier committed
193
    memset(rlc_pP, 0, sizeof(rlc_am_entity_t));
194
195
}
//-----------------------------------------------------------------------------
196
197
198
199
200
201
202
203
204
205
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)
206
207
//-----------------------------------------------------------------------------
{
208
  if (rlc_pP->configured == TRUE) {
209
210
      LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB AM %u][RECONFIGURE] max_retx_threshold %d poll_pdu %d poll_byte %d t_poll_retransmit %d t_reordering %d t_status_prohibit %d\n",
          PROTOCOL_CTXT_ARGS(ctxt_pP),
gauthier's avatar
gauthier committed
211
212
213
214
215
216
217
218
          rlc_pP->rb_id,
          max_retx_thresholdP,
          poll_pduP,
          poll_byteP,
          t_poll_retransmitP,
          t_reorderingP,
          t_status_prohibitP);

219
220
221
222
223
224
225
226
227
      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 {
228
229
230
231
232
233
234
235
236
      LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB AM %u][CONFIGURE] max_retx_threshold %d poll_pdu %d poll_byte %d t_poll_retransmit %d t_reordering %d t_status_prohibit %d\n",
            PROTOCOL_CTXT_ARGS(ctxt_pP),
            rlc_pP->rb_id,
            max_retx_thresholdP,
            poll_pduP,
            poll_byteP,
            t_poll_retransmitP,
            t_reorderingP,
            t_status_prohibitP);
237
238
239
240
241
242
243

      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;


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

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

251
252
}
//-----------------------------------------------------------------------------
253
254
255
256
257
258
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)
259
260
//-----------------------------------------------------------------------------
{
261

gauthier's avatar
gauthier committed
262
    rlc_pP->rb_id         = rb_idP;
263
    if (srb_flagP) {
gauthier's avatar
gauthier committed
264
      rlc_pP->is_data_plane = 0;
265
266
    } else {
      rlc_pP->is_data_plane = 1;
267
    }
268
269
270
271
    LOG_D(RLC, PROTOCOL_CTXT_FMT RB_AM_FMT "[SET DEBUG INFOS]\n",
          PROTOCOL_CTXT_ARGS(ctxt_pP),
          RB_AM_ARGS(rlc_pP));

272
}