rlc_am_init.c 10 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
gauthier's avatar
gauthier committed
21

22 23
#define RLC_AM_MODULE 1
#define RLC_AM_INIT_C 1
24 25 26 27 28 29 30 31
#ifdef USER_MODE
#include <string.h>
#endif
//-----------------------------------------------------------------------------
#include "rlc_am.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
//-----------------------------------------------------------------------------
32 33
void
rlc_am_init(
34 35
  const protocol_ctxt_t* const  ctxt_pP,
  rlc_am_entity_t *const        rlc_pP)
36
{
37
  if (rlc_pP->initialized == TRUE) {
38 39
    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));
40
  } else {
41 42
    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));
43 44 45 46 47 48 49 50 51 52
    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));
53
//#warning "cast the rlc retrans buffer to uint32"
54 55
    //        rlc_pP->tx_data_pdu_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->tx_data_pdu_buffer       = calloc(1, (uint32_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof(
56
                                         rlc_am_tx_data_pdu_management_t)));
Cedric Roux's avatar
Cedric Roux committed
57
    LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] input_sdus[] = %p  element size=%zu\n",
58
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
59 60
          rlc_pP->input_sdus,
          sizeof(rlc_am_tx_sdu_management_t));
61
    LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] tx_data_pdu_buffer[] = %p element size=%zu\n",
62
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
63
          rlc_pP->tx_data_pdu_buffer,
64 65 66 67 68 69 70 71 72 73 74 75 76
          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;
fnabet's avatar
fnabet committed
77
    rlc_pP->vr_x    = RLC_SN_UNDEFINED;
78 79
    //rlc_pP->vr_ms   = 0;
    //rlc_pP->vr_h    = 0;
fnabet's avatar
fnabet committed
80
    rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED;
81

82
    rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1
83 84 85

    rlc_pP->initialized                  = TRUE;
  }
86
}
87
//-----------------------------------------------------------------------------
88 89
void
rlc_am_reestablish(
90 91
  const protocol_ctxt_t* const  ctxt_pP,
  rlc_am_entity_t* const        rlc_pP)
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 108
  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));
109

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

113 114 115
  list_free(&rlc_pP->pdus_to_mac_layer);
  list_free(&rlc_pP->control_pdu_list);
  list_free(&rlc_pP->segmentation_pdu_list);
116 117


118 119 120 121 122
  // 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;
123

124 125 126
  // TX counters
  rlc_pP->c_pdu_without_poll  = 0;
  rlc_pP->c_byte_without_poll = 0;
127

128 129 130
  // RX state variables
  rlc_pP->vr_r    = 0;
  rlc_pP->vr_mr   = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE;
fnabet's avatar
fnabet committed
131
  rlc_pP->vr_x    = RLC_SN_UNDEFINED;
132 133
  rlc_pP->vr_ms   = 0;
  rlc_pP->vr_h    = 0;
fnabet's avatar
fnabet committed
134 135
  rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED;
  rlc_pP->status_requested	= RLC_AM_STATUS_NOT_TRIGGERED;
136

137
  rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1
138

139
  rlc_pP->initialized                  = TRUE;
140 141 142

}

143
//-----------------------------------------------------------------------------
144 145
void
rlc_am_cleanup(
146 147
  rlc_am_entity_t* const        rlc_pP
)
148
{
149 150 151 152
  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
153 154


155
  if (rlc_pP->output_sdu_in_construction != NULL) {
156
    free_mem_block(rlc_pP->output_sdu_in_construction, __func__);
157 158 159 160 161 162 163 164
    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) {
165
        free_mem_block(rlc_pP->input_sdus[i].mem_block, __func__);
166 167
        rlc_pP->input_sdus[i].mem_block = NULL;
      }
168
    }
169 170 171 172 173 174 175

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

  pthread_mutex_destroy(&rlc_pP->lock_input_sdus);

176
  if (rlc_pP->tx_data_pdu_buffer != NULL) {
177
    for (i=0; i < RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE; i++) {
178 179 180
      if (rlc_pP->tx_data_pdu_buffer[i].mem_block != NULL) {
        free_mem_block(rlc_pP->tx_data_pdu_buffer[i].mem_block, __func__);
        rlc_pP->tx_data_pdu_buffer[i].mem_block = NULL;
181
      }
182
    }
183

184 185
    free(rlc_pP->tx_data_pdu_buffer);
    rlc_pP->tx_data_pdu_buffer       = NULL;
186 187 188
  }

  memset(rlc_pP, 0, sizeof(rlc_am_entity_t));
189 190
}
//-----------------------------------------------------------------------------
191 192
void
rlc_am_configure(
193 194 195 196 197 198 199 200
  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)
201
{
202
  if (rlc_pP->configured == TRUE) {
203 204
    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
205 206 207 208 209 210 211
          max_retx_thresholdP,
          poll_pduP,
          poll_byteP,
          t_poll_retransmitP,
          t_reorderingP,
          t_status_prohibitP);

212 213 214 215
    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;
216 217 218
    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;
219 220

  } else {
221 222
    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),
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
          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;
241
  }
gauthier's avatar
gauthier committed
242

243 244
}
//-----------------------------------------------------------------------------
245 246
void
rlc_am_set_debug_infos(
247 248 249
  const protocol_ctxt_t* const  ctxt_pP,
  rlc_am_entity_t *const        rlc_pP,
  const srb_flag_t              srb_flagP,
250
  const rb_id_t                 rb_idP,
251
  const logical_chan_id_t       chan_idP) 
252
{
253
  rlc_pP->rb_id         = rb_idP;
254
  rlc_pP->channel_id    = chan_idP;
255 256 257 258 259 260 261

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

262 263
  LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SET DEBUG INFOS]\n",
        PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
264

265
}