Skip to content
Snippets Groups Projects
flexran_agent_ran_api.c 98.6 KiB
Newer Older
shahab's avatar
shahab committed
/*
 * 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.1  (the "License"); you may not use this file
shahab's avatar
shahab committed
 * 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
 */ 

/*! \file flexran_agent_ran_api.c
 * \brief FlexRAN RAN API abstraction 
Robert Schmidt's avatar
Robert Schmidt committed
 * \author N. Nikaein, X. Foukas, S. SHARIAT BAGHERI and R. Schmidt
shahab's avatar
shahab committed
 * \date 2017
 * \version 0.1
 */

shahab's avatar
shahab committed
#include "flexran_agent_ran_api.h"

static inline int phy_is_present(mid_t mod_id, uint8_t cc_id)
{
  return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id];
}
static inline int mac_is_present(mid_t mod_id)
{
  return RC.mac && RC.mac[mod_id];
}

static inline int rrc_is_present(mid_t mod_id)
{
  return RC.rrc && RC.rrc[mod_id];
Robert Schmidt's avatar
Robert Schmidt committed
uint32_t flexran_get_current_time_ms(mid_t mod_id, int subframe_flag)
  if (!mac_is_present(mod_id)) return 0;
Robert Schmidt's avatar
Robert Schmidt committed
  if (subframe_flag == 1)
    return RC.mac[mod_id]->frame*10 + RC.mac[mod_id]->subframe;
Robert Schmidt's avatar
Robert Schmidt committed
  else
Robert Schmidt's avatar
Robert Schmidt committed
frame_t flexran_get_current_frame(mid_t mod_id)
{
  if (!mac_is_present(mod_id)) return 0;
shahab's avatar
shahab committed
  //  #warning "SFN will not be in [0-1023] when oaisim is used"
Robert Schmidt's avatar
Robert Schmidt committed
frame_t flexran_get_current_system_frame_num(mid_t mod_id)
{
  return flexran_get_current_frame(mod_id) % 1024;
Robert Schmidt's avatar
Robert Schmidt committed
sub_frame_t flexran_get_current_subframe(mid_t mod_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->subframe;
Robert Schmidt's avatar
Robert Schmidt committed
/* Why uint16_t, frame_t and sub_frame_t are defined as uint32_t? */
uint16_t flexran_get_sfn_sf(mid_t mod_id)
{
  if (!mac_is_present(mod_id)) return 0;
Robert Schmidt's avatar
Robert Schmidt committed
  frame_t frame = flexran_get_current_system_frame_num(mod_id);
  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
shahab's avatar
shahab committed
  uint16_t sfn_sf, frame_mask, sf_mask;
Robert Schmidt's avatar
Robert Schmidt committed

  frame_mask = (1 << 12) - 1;
  sf_mask = (1 << 4) - 1;
shahab's avatar
shahab committed
  sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4);
Robert Schmidt's avatar
Robert Schmidt committed

shahab's avatar
shahab committed
  return sfn_sf;
}

Robert Schmidt's avatar
Robert Schmidt committed
uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time)
{
  if (!mac_is_present(mod_id)) return 0;
Robert Schmidt's avatar
Robert Schmidt committed
  frame_t frame = flexran_get_current_system_frame_num(mod_id);
  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
shahab's avatar
shahab committed
  uint16_t sfn_sf, frame_mask, sf_mask;
Robert Schmidt's avatar
Robert Schmidt committed
  int additional_frames;
Robert Schmidt's avatar
Robert Schmidt committed
  subframe = (subframe + ahead_of_time) % 10;

  if (subframe < flexran_get_current_subframe(mod_id))
shahab's avatar
shahab committed
    frame = (frame + 1) % 1024;
Robert Schmidt's avatar
Robert Schmidt committed

  additional_frames = ahead_of_time / 10;
shahab's avatar
shahab committed
  frame = (frame + additional_frames) % 1024;
Robert Schmidt's avatar
Robert Schmidt committed

  frame_mask = (1 << 12) - 1;
  sf_mask = (1 << 4) - 1;
shahab's avatar
shahab committed
  sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4);
Robert Schmidt's avatar
Robert Schmidt committed

shahab's avatar
shahab committed
  return sfn_sf;
}

int flexran_get_mac_num_ues(mid_t mod_id)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.num_UEs;
int flexran_get_num_ue_lcs(mid_t mod_id, mid_t ue_id)
{
  if (!mac_is_present(mod_id)) return 0;
  // Not sure whether this is needed: if (!rrc_is_present(mod_id)) return 0;
  const rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
  const int s = mac_eNB_get_rrc_status(mod_id, rnti);
  if (s < RRC_CONNECTED)
    return 0;
  else if (s == RRC_CONNECTED)
    return 1;
  else
    return 3;
}

int flexran_get_mac_ue_id_rnti(mid_t mod_id, rnti_t rnti)
{
  int n;
  if (!mac_is_present(mod_id)) return 0;
  /* get the (active) UE with RNTI i */
  for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
    if (RC.mac[mod_id]->UE_list.active[n] == TRUE
        && rnti == UE_RNTI(mod_id, n)) {
      return n;
    }
  }
  return 0;

}

int flexran_get_mac_ue_id(mid_t mod_id, int i)
{
  int n;
  if (!mac_is_present(mod_id)) return 0;
  /* get the (i+1)'th active UE */
  for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
    if (RC.mac[mod_id]->UE_list.active[n] == TRUE) {
      if (i == 0)
        return n;
      --i;
    }
  }
  return 0;
}

rnti_t flexran_get_mac_ue_crnti(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!mac_is_present(mod_id)) return 0;
Robert Schmidt's avatar
Robert Schmidt committed
  return UE_RNTI(mod_id, ue_id);
int flexran_get_ue_bsr_ul_buffer_info(mid_t mod_id, mid_t ue_id, lcid_t lcid)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].ul_buffer_info[lcid];
Robert Schmidt's avatar
Robert Schmidt committed
int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].phr_info;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].dl_cqi[0];
Robert Schmidt's avatar
Robert Schmidt committed
rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id)
{
  if (!mac_is_present(mod_id)) return 0;
  rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
Robert Schmidt's avatar
Robert Schmidt committed
  frame_t frame = flexran_get_current_frame(mod_id);
  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
shahab's avatar
shahab committed
  return rlc_status.bytes_in_buffer;
Robert Schmidt's avatar
Robert Schmidt committed
rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id)
{
  if (!mac_is_present(mod_id)) return 0;
  rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id);
Robert Schmidt's avatar
Robert Schmidt committed
  frame_t frame = flexran_get_current_frame(mod_id);
  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
  return rlc_status.pdus_in_buffer;
}

Robert Schmidt's avatar
Robert Schmidt committed
frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id)
{
  if (!mac_is_present(mod_id)) return 0;
  rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id);
Robert Schmidt's avatar
Robert Schmidt committed
  frame_t frame = flexran_get_current_frame(mod_id);
  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
shahab's avatar
shahab committed
  return rlc_status.head_sdu_creation_time;
}

Robert Schmidt's avatar
Robert Schmidt committed
int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  int32_t tau = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].timing_advance_update;
Robert Schmidt's avatar
Robert Schmidt committed
  switch (flexran_get_N_RB_DL(mod_id, cc_id)) {
shahab's avatar
shahab committed
  case 6:
Robert Schmidt's avatar
Robert Schmidt committed
    return tau;
shahab's avatar
shahab committed
  case 15:
Robert Schmidt's avatar
Robert Schmidt committed
    return tau / 2;
shahab's avatar
shahab committed
  case 25:
Robert Schmidt's avatar
Robert Schmidt committed
    return tau / 4;
shahab's avatar
shahab committed
  case 50:
Robert Schmidt's avatar
Robert Schmidt committed
    return tau / 8;
shahab's avatar
shahab committed
  case 75:
Robert Schmidt's avatar
Robert Schmidt committed
    return tau / 12;
shahab's avatar
shahab committed
  case 100:
Robert Schmidt's avatar
Robert Schmidt committed
    if (flexran_get_threequarter_fs(mod_id, cc_id) == 0)
      return tau / 16;
    else
      return tau / 12;
shahab's avatar
shahab committed
  default:
    return 0;
  }
}

uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_sdu_bytes;
}

uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  uint64_t bytes = 0;
  for (int i = 0; i < NB_RB_MAX; ++i) {
    bytes += RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].num_bytes_rx[i];
  }
  return bytes;
uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].TBS;
}

uint32_t flexran_get_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_TBS;
}

uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx;
uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx_rx;
}

uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used;
uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_rx;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].periodic_wideband_pmi[cc_id];
uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs1;
}

uint8_t flexran_get_mcs2_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs2;
}

uint8_t flexran_get_mcs1_ul(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs1;
}

uint8_t flexran_get_mcs2_ul(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs2;
}

uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used;
}

uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used_rx;
}

uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus;
}

uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus_rx;
}

uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_pdu_bytes;
}

uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_ulsch_TBS;
}

int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].harq_round;
}

uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].num_mac_sdu_tx;
unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].lcid_sdu[index];
}

uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].sdu_length_tx[lcid];
}


Robert Schmidt's avatar
Robert Schmidt committed
/* TODO needs to be revised */
void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
/*
shahab's avatar
shahab committed
  UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list;
  UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[ue_id];

  if (ue_sched_ctl->ta_timer == 0) {
    
    // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ...                                                                         
    //    LTE_eNB_UE_stats		*eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
    //ue_sched_ctl->ta_timer		      = 20;	// wait 20 subframes before taking TA measurement from PHY                                         
    ue_sched_ctl->ta_update = flexran_get_TA(mod_id, ue_id, CC_id);

    // clear the update in case PHY does not have a new measurement after timer expiry                                               
    //    eNB_UE_stats->timing_advance_update	      = 0;
  } else {
    ue_sched_ctl->ta_timer--;
    ue_sched_ctl->ta_update		      = 0;	// don't trigger a timing advance command      
  }
Robert Schmidt's avatar
Robert Schmidt committed
#warning "Implement flexran_update_TA() in RAN API"
Robert Schmidt's avatar
Robert Schmidt committed
/* TODO needs to be revised, looks suspicious: why do we need UE stats? */
int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
Robert Schmidt's avatar
Robert Schmidt committed
#warning "Implement flexran_get_MAC_CE_bitmap_TA() in RAN API"
  if (!phy_is_present(mod_id, cc_id)) return 0;
Robert Schmidt's avatar
Robert Schmidt committed
  /* UE_stats can not be null, they are an array in RC
shahab's avatar
shahab committed
  LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti);
  
  if (eNB_UE_stats == NULL) {
    return 0;
  }
Robert Schmidt's avatar
Robert Schmidt committed
  */
Robert Schmidt's avatar
Robert Schmidt committed
  if (flexran_get_TA(mod_id, ue_id, cc_id) != 0) {
shahab's avatar
shahab committed
    return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA;
  } else {
    return 0;
  }
}

Robert Schmidt's avatar
Robert Schmidt committed
int flexran_get_active_CC(mid_t mod_id, mid_t ue_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.numactiveCCs[ue_id];
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_current_RI(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].rank;
Robert Schmidt's avatar
Robert Schmidt committed
int flexran_get_tpc(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
Robert Schmidt's avatar
Robert Schmidt committed

  /* before: tested that UL_rssi != NULL and set parameter ([0]), but it is a
   * static array -> target_rx_power is useless in old ifs?! */
  int pCCid = UE_PCCID(mod_id,ue_id);
  int32_t target_rx_power = RC.eNB[mod_id][pCCid]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
  int32_t normalized_rx_power = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].UL_rssi[0];
Robert Schmidt's avatar
Robert Schmidt committed

  int tpc;
  if (normalized_rx_power > target_rx_power + 1)
    tpc = 0;	//-1
  else if (normalized_rx_power < target_rx_power - 1)
    tpc = 2;	//+1
  else
    tpc = 1;	//0
  return tpc;
}

int flexran_get_harq(mid_t       mod_id,
                     uint8_t     cc_id,
                     mid_t       ue_id,
                     frame_t     frame,
                     sub_frame_t subframe,
                     uint8_t    *pid,
                     uint8_t    *round,
                     uint8_t     harq_flag)
{
  /* TODO: Add int TB in function parameters to get the status of the second
   * TB. This can be done to by editing in get_ue_active_harq_pid function in
   * line 272 file: phy_procedures_lte_eNB.c to add DLSCH_ptr =
   * PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][1];*/
Robert Schmidt's avatar
Robert Schmidt committed
  /* TODO IMPLEMENT */
  /*
shahab's avatar
shahab committed
  uint8_t harq_pid;
  uint8_t harq_round;
  
  if (mac_xface_not_ready()) return 0 ;
  uint16_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id);
shahab's avatar
shahab committed
  if (harq_flag == openair_harq_DL){
shahab's avatar
shahab committed
      mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL);
shahab's avatar
shahab committed
   } else if (harq_flag == openair_harq_UL){

shahab's avatar
shahab committed
     mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,round,openair_harq_UL);    
shahab's avatar
shahab committed
   }
   else {

      LOG_W(FLEXRAN_AGENT,"harq_flag is not recongnized");
   }


  *pid = harq_pid;
Robert Schmidt's avatar
Robert Schmidt committed
  *round = harq_round;*/
shahab's avatar
shahab committed
  /* if (round > 0) { */
  /*   *status = 1; */
  /* } else { */
  /*   *status = 0; */
  /* } */
Robert Schmidt's avatar
Robert Schmidt committed
  /*return *round;*/
Robert Schmidt's avatar
Robert Schmidt committed
#warning "Implement flexran_get_harq() in RAN API"
Robert Schmidt's avatar
Robert Schmidt committed
  return 0;
Robert Schmidt's avatar
Robert Schmidt committed
int32_t flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_dBm;
Robert Schmidt's avatar
Robert Schmidt committed
int8_t flexran_get_p0_nominal_pucch(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
Robert Schmidt's avatar
Robert Schmidt committed
int32_t flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update;
Robert Schmidt's avatar
Robert Schmidt committed
int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update = 0;
shahab's avatar
shahab committed
  return 0;
}


/*
 * ************************************
 * Get Messages for eNB Configuration Reply
 * ************************************
 */
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.threequarter_fs;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.pusch_HoppingOffset;
Protocol__FlexHoppingMode flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return -1;
  switch (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode) {
  case interSubFrame:
    return PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTER;
  case intraAndInterSubFrame:
    return PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTERINTRA;
  }
  return -1;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.n_SB;
Protocol__FlexQam flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  if (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM == TRUE)
    return PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM;
  else
    return PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM;
Protocol__FlexPhichDuration flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!phy_is_present(mod_id, cc_id)) return -1;
  switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration) {
  case normal:
    return PROTOCOL__FLEX_PHICH_DURATION__FLPD_NORMAL;
  case extended:
    return PROTOCOL__FLEX_PHICH_DURATION__FLPD_EXTENDED;
  }
  return -1;
Protocol__FlexPhichResource flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!phy_is_present(mod_id, cc_id)) return -1;
  switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_resource) {
Robert Schmidt's avatar
Robert Schmidt committed
  case oneSixth:
    return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE_SIXTH;
Robert Schmidt's avatar
Robert Schmidt committed
  case half:
    return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_HALF;
Robert Schmidt's avatar
Robert Schmidt committed
  case one:
    return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE;
Robert Schmidt's avatar
Robert Schmidt committed
  case two:
    return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_TWO;
Robert Schmidt's avatar
Robert Schmidt committed
  }
Robert Schmidt's avatar
Robert Schmidt committed
uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.n1PUCCH_AN;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_nRB_CQI(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.nRB_CQI;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_deltaPUCCH_Shift(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.deltaPUCCH_Shift;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_prach_ConfigIndex(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.maxHARQ_Msg3Tx;
Protocol__FlexUlCyclicPrefixLength flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!phy_is_present(mod_id, cc_id)) return -1;
  switch (RC.eNB[mod_id][cc_id]->frame_parms.Ncp_UL) {
  case EXTENDED:
    return PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED;
  case NORMAL:
    return PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_NORMAL;
  }
  return -1;
Protocol__FlexDlCyclicPrefixLength flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!phy_is_present(mod_id, cc_id)) return -1;
  switch (RC.eNB[mod_id][cc_id]->frame_parms.Ncp) {
  case EXTENDED:
    return PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_EXTENDED;
  case NORMAL:
    return PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_NORMAL;
  }
  return -1;
Robert Schmidt's avatar
Robert Schmidt committed
uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.Nid_cell;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_srs_BandwidthConfig(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_srs_SubframeConfig(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_srs_MaxUpPts(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_MaxUpPts;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_N_RB_DL(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_DL;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_N_RB_UL(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_UL;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_N_RBG(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.N_RBG;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_subframe_assignment(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_special_subframe_assignment(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config_S;
Robert Schmidt's avatar
Robert Schmidt committed
long flexran_get_ra_ResponseWindowSize(mid_t mod_id, uint8_t cc_id)
{
  if (!rrc_is_present(mod_id)) return 0;
  return RC.rrc[mod_id]->configuration.radioresourceconfig[cc_id].rach_raResponseWindowSize;
Robert Schmidt's avatar
Robert Schmidt committed
long flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, uint8_t cc_id)
{
  if (!rrc_is_present(mod_id)) return 0;
  return RC.rrc[mod_id]->configuration.radioresourceconfig[cc_id].rach_macContentionResolutionTimer;
Robert Schmidt's avatar
Robert Schmidt committed
Protocol__FlexDuplexMode flexran_get_duplex_mode(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  switch (RC.eNB[mod_id][cc_id]->frame_parms.frame_type) {
Robert Schmidt's avatar
Robert Schmidt committed
  case TDD:
    return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD;
  case FDD:
    return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD;
  default:
    return -1;
  }
Robert Schmidt's avatar
Robert Schmidt committed
long flexran_get_si_window_length(mid_t mod_id, uint8_t cc_id)
{
  if (!rrc_is_present(mod_id) || !RC.rrc[mod_id]->carrier[cc_id].sib1) return 0;
  return RC.rrc[mod_id]->carrier[cc_id].sib1->si_WindowLength;
Robert Schmidt's avatar
Robert Schmidt committed
uint8_t flexran_get_sib1_length(mid_t mod_id, uint8_t cc_id)
{
  if (!rrc_is_present(mod_id)) return 0;
  return RC.rrc[mod_id]->carrier[cc_id].sizeof_SIB1;
uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id)
{
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->pdcch_vars[0].num_pdcch_symbols;
shahab's avatar
shahab committed
}



/*
 * ************************************
 * Get Messages for UE Configuration Reply
 * ************************************
 */
int flexran_get_rrc_num_ues(mid_t mod_id)
{
  if (!rrc_is_present(mod_id)) return 0;
  return RC.rrc[mod_id]->Nb_ue;
}
rnti_t flexran_get_rrc_rnti_nth_ue(mid_t mod_id, int index)
{
  if (!rrc_is_present(mod_id)) return 0;
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head) {
    if (index == 0) return ue_context_p->ue_context.rnti;
    --index;
  }
  return 0;
}

int flexran_get_rrc_rnti_list(mid_t mod_id, rnti_t *list, int max_list)
{
  if (!rrc_is_present(mod_id)) return 0;
  int n = 0;
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head) {
    if (n >= max_list) break;
    list[n] = ue_context_p->ue_context.rnti;
    ++n;
  }
  return n;
}
LTE_TimeAlignmentTimer_t  flexran_get_time_alignment_timer(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
Robert Schmidt's avatar
Robert Schmidt committed
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.mac_MainConfig) return -1;
  return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated;
Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
Robert Schmidt's avatar
Robert Schmidt committed
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.measGapConfig) return -1;
  if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1;
Robert Schmidt's avatar
Robert Schmidt committed
  switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) {
  case LTE_MeasGapConfig__setup__gapOffset_PR_gp0:
Robert Schmidt's avatar
Robert Schmidt committed
    return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1;
  case LTE_MeasGapConfig__setup__gapOffset_PR_gp1:
Robert Schmidt's avatar
Robert Schmidt committed
    return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2;
  default:
    return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF;
shahab's avatar
shahab committed

long flexran_get_meas_gap_config_offset(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
Robert Schmidt's avatar
Robert Schmidt committed
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.measGapConfig) return -1;
  if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1;
Robert Schmidt's avatar
Robert Schmidt committed
  switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) {
  case LTE_MeasGapConfig__setup__gapOffset_PR_gp0:
Robert Schmidt's avatar
Robert Schmidt committed
    return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0;
  case LTE_MeasGapConfig__setup__gapOffset_PR_gp1:
Robert Schmidt's avatar
Robert Schmidt committed
    return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp1;
  default:
    return -1;
  }
}
uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return 0;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
Robert Schmidt's avatar
Robert Schmidt committed
  if (!ue_context_p) return RRC_INACTIVE;
  return ue_context_p->ue_context.Status;
shahab's avatar
shahab committed
}

Robert Schmidt's avatar
Robert Schmidt committed
uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL;
Robert Schmidt's avatar
Robert Schmidt committed
uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id)
{
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL;
int flexran_get_half_duplex(mid_t mod_id, rnti_t rnti)
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.UE_Capability) return -1;
  LTE_SupportedBandListEUTRA_t *bands = &ue_context_p->ue_context.UE_Capability->rf_Parameters.supportedBandListEUTRA;
  for (int i = 0; i < bands->list.count; i++) {
    if (bands->list.array[i]->halfDuplex > 0) return 1;
  }
int flexran_get_intra_sf_hopping(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.UE_Capability) return -1;
  if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1;
  /* According to TS 36.331 Annex B.1, Intra SF Hopping is bit 1 (leftmost bit)
   * in this bitmap, i.e. the eighth bit (from right) in the first bye (from
   * left) */
  BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators;
  uint8_t buf = fgi->buf[0];
  return (buf >> 7) & 1;
int flexran_get_type2_sb_1(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.UE_Capability) return -1;
  if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1;
  /* According to TS 36.331 Annex B.1, Predefined intra- and inter-sf or
   * predfined inter-sf frequency hopping for PUSCH with N_sb>1 is bit 21 (bit
   * 1 is leftmost bit) in this bitmap, i.e. the fourth bit (from right) in the
   * third byte (from left) */
  BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators;
  uint8_t buf = fgi->buf[2];
  return (buf >> 3) & 1;
long flexran_get_ue_category(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.UE_Capability) return -1;
  return ue_context_p->ue_context.UE_Capability->ue_Category;
int flexran_get_res_alloc_type1(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.UE_Capability) return -1;
  if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1;
  /* According to TS 36.331 Annex B.1, Resource allocation type 1 for PDSCH is
   * bit 2 (bit 1 is leftmost bit) in this bitmap, i.e. the seventh bit (from
   * right) in the first byte (from left) */
  BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators;
  uint8_t buf = fgi->buf[0];
  return (buf >> 6) & 1;
long flexran_get_ue_transmission_mode(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
Robert Schmidt's avatar
Robert Schmidt committed
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1;
  return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode;
BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
Robert Schmidt's avatar
Robert Schmidt committed
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.mac_MainConfig) return -1;
  if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1;
  return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling;
long flexran_get_maxHARQ_TX(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
Robert Schmidt's avatar
Robert Schmidt committed
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.mac_MainConfig) return -1;
  if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1;
  return *(ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx);
long flexran_get_beta_offset_ack_index(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
Robert Schmidt's avatar
Robert Schmidt committed
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1;
  return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index;
long flexran_get_beta_offset_ri_index(mid_t mod_id, rnti_t rnti)
Robert Schmidt's avatar
Robert Schmidt committed
{
  if (!rrc_is_present(mod_id)) return -1;
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
Robert Schmidt's avatar
Robert Schmidt committed
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1;
  return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index;