rlc_am_in_sdu.c 5.77 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * 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
 */

22 23 24 25 26 27 28
/***************************************************************************
                          rlc_am_in_sdu.c  -
                             -------------------
  AUTHOR  : Lionel GAUTHIER
  COMPANY : EURECOM
  EMAIL   : Lionel.Gauthier@eurecom.fr
 ***************************************************************************/
29 30
#define RLC_AM_MODULE 1
#define RLC_AM_IN_SDU_C 1
31 32 33 34 35
//-----------------------------------------------------------------------------
#include "rlc_am.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"

36
#define TRACE_RLC_AM_FREE_SDU 0
37
//-----------------------------------------------------------------------------
38
void rlc_am_free_in_sdu(
39 40 41
  const protocol_ctxt_t* const  ctxt_pP,
  rlc_am_entity_t *const        rlcP,
  const unsigned int            index_in_bufferP)
42
{
43
  if (index_in_bufferP <= RLC_AM_SDU_CONTROL_BUFFER_SIZE) {
44 45 46 47
	/* BugFix:  SDU shall have been already freed during initial PDU segmentation or concatenation !! */
	  AssertFatal(rlcP->input_sdus[index_in_bufferP].mem_block == NULL, "RLC AM Tx SDU Conf: Data Part is not empty index=%d LcId=%d\n",
				index_in_bufferP,rlcP->channel_id);
	/*
48
    if (rlcP->input_sdus[index_in_bufferP].mem_block != NULL) {
49
      free_mem_block(rlcP->input_sdus[index_in_bufferP].mem_block, __func__);
50 51 52 53
      rlcP->input_sdus[index_in_bufferP].mem_block = NULL;
      rlcP->nb_sdu_no_segmented -= 1;
      rlcP->input_sdus[index_in_bufferP].sdu_remaining_size = 0;
    }
54
    */
55 56 57 58 59

    rlcP->nb_sdu -= 1;
    memset(&rlcP->input_sdus[index_in_bufferP], 0, sizeof(rlc_am_tx_sdu_management_t));
    rlcP->input_sdus[index_in_bufferP].flags.transmitted_successfully = 1;

hbilel's avatar
hbilel committed
60
    // case when either one SDU needs to be removed from segmentation or SDU buffer is full
61 62 63
    if (rlcP->current_sdu_index == index_in_bufferP) {
      rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE;
    }
64

hbilel's avatar
hbilel committed
65
    // wrapping and reset current_sdu_index to next_sdu_index when all transmitted SDUs have been acknowledged
66 67 68
    while ((rlcP->current_sdu_index != rlcP->next_sdu_index) &&
           (rlcP->input_sdus[rlcP->current_sdu_index].flags.transmitted_successfully == 1)) {
      rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE;
69
    }
70 71
  }

72
#if TRACE_RLC_AM_FREE_SDU
73 74
  LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[FREE SDU] SDU INDEX %03u current_sdu_index=%u next_sdu_index=%u nb_sdu_no_segmented=%u\n",
        PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlcP),
75 76 77 78
        index_in_bufferP,
        rlcP->current_sdu_index,
        rlcP->next_sdu_index,
        rlcP->nb_sdu_no_segmented);
79 80 81 82
#endif
}
// called when segmentation is done
//-----------------------------------------------------------------------------
83 84
void
rlc_am_free_in_sdu_data(
85 86 87
  const protocol_ctxt_t* const ctxt_pP,
  rlc_am_entity_t* const       rlcP,
  const unsigned int           index_in_bufferP)
88
{
89 90
  if (index_in_bufferP <= RLC_AM_SDU_CONTROL_BUFFER_SIZE) {
    if (rlcP->input_sdus[index_in_bufferP].mem_block != NULL) {
91
      free_mem_block(rlcP->input_sdus[index_in_bufferP].mem_block, __func__);
92 93 94
      rlcP->input_sdus[index_in_bufferP].mem_block = NULL;
      rlcP->input_sdus[index_in_bufferP].sdu_remaining_size = 0;
      rlcP->nb_sdu_no_segmented -= 1;
95
    }
96
  }
97 98
}
//-----------------------------------------------------------------------------
99 100
signed int
rlc_am_in_sdu_is_empty(
101 102
  const protocol_ctxt_t* const ctxt_pP,
  rlc_am_entity_t       *const rlcP)
103
{
104 105 106 107 108
  if (rlcP->nb_sdu == 0) {
    return 1;
  }

  return 0;
109
}
110 111 112 113 114 115 116 117 118 119 120 121

// called when PDU is ACKED
//-----------------------------------------------------------------------------
void
rlc_am_pdu_sdu_data_cnf(
  const protocol_ctxt_t* const ctxt_pP,
  rlc_am_entity_t* const       rlc_pP,
  const rlc_sn_t           snP)
{
	  int          pdu_sdu_index;
	  int          sdu_index;

122 123
      for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].nb_sdus; pdu_sdu_index++) {
        sdu_index = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].sdus_index[pdu_sdu_index];
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
        assert(sdu_index >= 0);
        assert(sdu_index < RLC_AM_SDU_CONTROL_BUFFER_SIZE);
        rlc_pP->input_sdus[sdu_index].nb_pdus_ack += 1;

        if ((rlc_pP->input_sdus[sdu_index].nb_pdus_ack == rlc_pP->input_sdus[sdu_index].nb_pdus) &&
            (rlc_pP->input_sdus[sdu_index].sdu_remaining_size == 0)) {
  #if TEST_RLC_AM
          rlc_am_v9_3_0_test_data_conf (
            rlc_pP->module_id,
            rlc_pP->rb_id,
            rlc_pP->input_sdus[sdu_index].mui,
            RLC_SDU_CONFIRM_YES);
  #else
          rlc_data_conf(
            ctxt_pP,
            rlc_pP->rb_id,
            rlc_pP->input_sdus[sdu_index].mui,
            RLC_SDU_CONFIRM_YES,
            rlc_pP->is_data_plane);
  #endif
          rlc_am_free_in_sdu(ctxt_pP, rlc_pP, sdu_index);
        }
      }
}