flexran_agent_ran_api.c 64.3 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * 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
24
 * \author N. Nikaein, X. Foukas, S. SHARIAT BAGHERI and R. Schmidt
25 26 27 28 29 30
 * \date 2017
 * \version 0.1
 */

#include "flexran_agent_ran_api.h"

31 32 33 34
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];
}
35

36 37 38 39 40 41 42 43
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];
44
}
45

Robert Schmidt's avatar
Robert Schmidt committed
46
uint32_t flexran_get_current_time_ms(mid_t mod_id, int subframe_flag)
47
{
48
  if (!mac_is_present(mod_id)) return 0;
Robert Schmidt's avatar
Robert Schmidt committed
49
  if (subframe_flag == 1)
50
    return RC.mac[mod_id]->frame*10 + RC.mac[mod_id]->subframe;
Robert Schmidt's avatar
Robert Schmidt committed
51
  else
52
    return RC.mac[mod_id]->frame*10;
53 54
}

Robert Schmidt's avatar
Robert Schmidt committed
55 56
frame_t flexran_get_current_frame(mid_t mod_id)
{
57
  if (!mac_is_present(mod_id)) return 0;
58
  //  #warning "SFN will not be in [0-1023] when oaisim is used"
59
  return RC.mac[mod_id]->frame;
60 61
}

Robert Schmidt's avatar
Robert Schmidt committed
62 63 64
frame_t flexran_get_current_system_frame_num(mid_t mod_id)
{
  return flexran_get_current_frame(mod_id) % 1024;
65 66
}

Robert Schmidt's avatar
Robert Schmidt committed
67 68
sub_frame_t flexran_get_current_subframe(mid_t mod_id)
{
69 70
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->subframe;
71 72
}

Robert Schmidt's avatar
Robert Schmidt committed
73 74 75 76 77
/* Why uint16_t, frame_t and sub_frame_t are defined as uint32_t? */
uint16_t flexran_get_sfn_sf(mid_t mod_id)
{
  frame_t frame = flexran_get_current_system_frame_num(mod_id);
  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
78
  uint16_t sfn_sf, frame_mask, sf_mask;
Robert Schmidt's avatar
Robert Schmidt committed
79 80 81

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

84 85 86
  return sfn_sf;
}

Robert Schmidt's avatar
Robert Schmidt committed
87 88 89 90
uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time)
{
  frame_t frame = flexran_get_current_system_frame_num(mod_id);
  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
91
  uint16_t sfn_sf, frame_mask, sf_mask;
Robert Schmidt's avatar
Robert Schmidt committed
92
  int additional_frames;
93

Robert Schmidt's avatar
Robert Schmidt committed
94 95 96
  subframe = (subframe + ahead_of_time) % 10;

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

  additional_frames = ahead_of_time / 10;
100
  frame = (frame + additional_frames) % 1024;
Robert Schmidt's avatar
Robert Schmidt committed
101 102 103

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

106 107 108
  return sfn_sf;
}

Robert Schmidt's avatar
Robert Schmidt committed
109 110
int flexran_get_num_ues(mid_t mod_id)
{
111 112
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.num_UEs;
113 114
}

Robert Schmidt's avatar
Robert Schmidt committed
115 116 117
rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id)
{
  return UE_RNTI(mod_id, ue_id);
118 119
}

120
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
121
{
122 123
  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];
124 125
}

Robert Schmidt's avatar
Robert Schmidt committed
126 127
int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id)
{
128 129
  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;
130 131
}

Robert Schmidt's avatar
Robert Schmidt committed
132 133
uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id)
{
134
  if (!mac_is_present(mod_id)) return 0;
135
  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].dl_cqi[0];
136 137
}

Robert Schmidt's avatar
Robert Schmidt committed
138 139 140 141 142
rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id)
{
  rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id);
  frame_t frame = flexran_get_current_frame(mod_id);
  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
143
  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
144
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
145 146 147
                                                    ,0, 0
#endif
                                                    );
148
  return rlc_status.bytes_in_buffer;
149 150
}

Robert Schmidt's avatar
Robert Schmidt committed
151 152
rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id)
{
153
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
Robert Schmidt's avatar
Robert Schmidt committed
154 155
  frame_t frame = flexran_get_current_frame(mod_id);
  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
156
  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
157
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
158 159 160
                                                    ,0, 0
#endif
                                                    );
161 162 163
  return rlc_status.pdus_in_buffer;
}

Robert Schmidt's avatar
Robert Schmidt committed
164 165
frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id)
{
166
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
Robert Schmidt's avatar
Robert Schmidt committed
167 168
  frame_t frame = flexran_get_current_frame(mod_id);
  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
169
  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
170
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
171 172 173
                                                    ,0, 0
#endif
                                                    );
174 175 176
  return rlc_status.head_sdu_creation_time;
}

Robert Schmidt's avatar
Robert Schmidt committed
177 178
int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
179
  if (!phy_is_present(mod_id, cc_id)) return 0;
180

181
  int32_t tau = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].timing_advance_update;
Robert Schmidt's avatar
Robert Schmidt committed
182
  switch (flexran_get_N_RB_DL(mod_id, cc_id)) {
183
  case 6:
Robert Schmidt's avatar
Robert Schmidt committed
184
    return tau;
185
  case 15:
Robert Schmidt's avatar
Robert Schmidt committed
186
    return tau / 2;
187
  case 25:
Robert Schmidt's avatar
Robert Schmidt committed
188
    return tau / 4;
189
  case 50:
Robert Schmidt's avatar
Robert Schmidt committed
190
    return tau / 8;
191
  case 75:
Robert Schmidt's avatar
Robert Schmidt committed
192
    return tau / 12;
193
  case 100:
Robert Schmidt's avatar
Robert Schmidt committed
194 195 196 197
    if (flexran_get_threequarter_fs(mod_id, cc_id) == 0)
      return tau / 16;
    else
      return tau / 12;
198 199 200 201 202
  default:
    return 0;
  }
}

203 204
uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id)
{
205 206 207 208
  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;
}

209 210 211
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;
212 213 214
  return RC.mac[mod_id]->eNB_stats[cc_id].total_ulsch_bytes_rx;
}

215 216
uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
217 218 219 220
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].TBS;
}

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

227 228 229 230
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;
231 232
}

233 234
uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, int cc_id)
{
235 236 237 238
  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;
}

239 240 241 242
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;
243 244
}

245 246 247 248
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;
249 250
}

Robert Schmidt's avatar
Robert Schmidt committed
251 252
uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
253 254
  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];
255 256
}

257 258
uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
259 260 261 262
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs1;
}

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

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

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

281 282
uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id)
{
283 284 285 286
  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;
}

287 288
uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id)
{
289 290 291 292
  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;
}

293 294
uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
295 296 297 298
  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;
}

299 300
uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id)
{
301 302 303 304
  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;
}

305 306
uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
307 308 309 310
  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;
}

311 312
uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id)
{
313 314 315 316
  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;
}

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

323 324 325 326
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;
327 328
}

329 330
unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index)
{
331 332 333 334
  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];
}

335 336
uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid)
{
337 338 339 340 341
  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
342 343 344 345
/* TODO needs to be revised */
void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
/*
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
  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
362 363
*/
#warning "Implement flexran_update_TA() in RAN API"
364 365
}

Robert Schmidt's avatar
Robert Schmidt committed
366 367 368 369
/* 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)
{
#warning "Implement flexran_get_MAC_CE_bitmap_TA() in RAN API"
370
  if (!phy_is_present(mod_id, cc_id)) return 0;
371

Robert Schmidt's avatar
Robert Schmidt committed
372
  /* UE_stats can not be null, they are an array in RC
373 374 375 376 377
  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
378
  */
379

Robert Schmidt's avatar
Robert Schmidt committed
380
  if (flexran_get_TA(mod_id, ue_id, cc_id) != 0) {
381 382 383 384 385 386
    return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA;
  } else {
    return 0;
  }
}

Robert Schmidt's avatar
Robert Schmidt committed
387 388
int flexran_get_active_CC(mid_t mod_id, mid_t ue_id)
{
389 390
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.numactiveCCs[ue_id];
391 392
}

Robert Schmidt's avatar
Robert Schmidt committed
393 394
uint8_t flexran_get_current_RI(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
395 396
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].rank;
397 398
}

Robert Schmidt's avatar
Robert Schmidt committed
399 400
int flexran_get_tpc(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
401
  if (!phy_is_present(mod_id, cc_id)) return 0;
Robert Schmidt's avatar
Robert Schmidt committed
402 403 404 405

  /* 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);
406 407
  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
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431

  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];*/
432

Robert Schmidt's avatar
Robert Schmidt committed
433 434
  /* TODO IMPLEMENT */
  /*
435 436 437
  uint8_t harq_pid;
  uint8_t harq_round;
  
438
  if (mac_xface_not_ready()) return 0 ;
439 440

  uint16_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
441
  if (harq_flag == openair_harq_DL){
442

shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
443
      mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL);
444

shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
445 446
   } else if (harq_flag == openair_harq_UL){

shahab SHARIAT BAGHERI's avatar
shahab SHARIAT BAGHERI committed
447
     mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,round,openair_harq_UL);    
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
448 449 450 451 452 453 454 455
   }
   else {

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


  *pid = harq_pid;
Robert Schmidt's avatar
Robert Schmidt committed
456
  *round = harq_round;*/
457 458 459 460 461
  /* if (round > 0) { */
  /*   *status = 1; */
  /* } else { */
  /*   *status = 0; */
  /* } */
Robert Schmidt's avatar
Robert Schmidt committed
462 463 464
  /*return *round;*/
#warning "Implement flexran_get_harq() in RAN API"
  return 0;
465 466
}

Robert Schmidt's avatar
Robert Schmidt committed
467 468
int32_t flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
469 470
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_dBm;
471 472
}

Robert Schmidt's avatar
Robert Schmidt committed
473 474
int8_t flexran_get_p0_nominal_pucch(mid_t mod_id, uint8_t cc_id)
{
475 476
  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;
477 478
}

Robert Schmidt's avatar
Robert Schmidt committed
479 480
int32_t flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
481 482
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update;
483 484
}

Robert Schmidt's avatar
Robert Schmidt committed
485 486
int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
487 488
  if (!phy_is_present(mod_id, cc_id)) return 0;
  RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update = 0;
489 490 491 492 493 494 495 496 497
  return 0;
}


/*
 * ************************************
 * Get Messages for eNB Configuration Reply
 * ************************************
 */
Robert Schmidt's avatar
Robert Schmidt committed
498 499
uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id)
{
500 501
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.threequarter_fs;
502 503
}

504

Robert Schmidt's avatar
Robert Schmidt committed
505 506
uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id)
{
507 508
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.pusch_HoppingOffset;
509 510
}

Robert Schmidt's avatar
Robert Schmidt committed
511 512
PUSCH_HOPPING_t flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id)
{
513 514
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode;
515 516
}

Robert Schmidt's avatar
Robert Schmidt committed
517 518
uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id)
{
519 520
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.n_SB;
521 522
}

Robert Schmidt's avatar
Robert Schmidt committed
523 524
uint8_t flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id)
{
525 526
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM;
527 528
}

Robert Schmidt's avatar
Robert Schmidt committed
529 530
PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id)
{
531 532
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration;
533 534
}

Robert Schmidt's avatar
Robert Schmidt committed
535 536
int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id)
{
537 538
  if (!phy_is_present(mod_id, cc_id)) return 0;
  switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_resource) {
Robert Schmidt's avatar
Robert Schmidt committed
539 540 541 542 543 544 545 546 547 548 549
  case oneSixth:
    return 0;
  case half:
    return 1;
  case one:
    return 2;
  case two:
    return 3;
  default:
    return -1;
  }
550 551
}

Robert Schmidt's avatar
Robert Schmidt committed
552 553
uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id)
{
554 555
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.n1PUCCH_AN;
556 557
}

Robert Schmidt's avatar
Robert Schmidt committed
558 559
uint8_t flexran_get_nRB_CQI(mid_t mod_id, uint8_t cc_id)
{
560 561
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.nRB_CQI;
562 563
}

Robert Schmidt's avatar
Robert Schmidt committed
564 565
uint8_t flexran_get_deltaPUCCH_Shift(mid_t mod_id, uint8_t cc_id)
{
566 567
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.deltaPUCCH_Shift;
568 569
}

Robert Schmidt's avatar
Robert Schmidt committed
570 571
uint8_t flexran_get_prach_ConfigIndex(mid_t mod_id, uint8_t cc_id)
{
572 573
  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;
574 575
}

Robert Schmidt's avatar
Robert Schmidt committed
576 577
uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id)
{
578 579
  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;
580 581
}

Robert Schmidt's avatar
Robert Schmidt committed
582 583
uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id)
{
584 585
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.maxHARQ_Msg3Tx;
586 587
}

Robert Schmidt's avatar
Robert Schmidt committed
588 589
lte_prefix_type_t flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id)
{
590 591
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.Ncp_UL;
592 593
}

Robert Schmidt's avatar
Robert Schmidt committed
594 595
lte_prefix_type_t flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id)
{
596 597
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.Ncp;
598 599
}

Robert Schmidt's avatar
Robert Schmidt committed
600 601
uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id)
{
602 603
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.Nid_cell;
604 605
}

Robert Schmidt's avatar
Robert Schmidt committed
606 607
uint8_t flexran_get_srs_BandwidthConfig(mid_t mod_id, uint8_t cc_id)
{
608 609
  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;
610 611
}

Robert Schmidt's avatar
Robert Schmidt committed
612 613
uint8_t flexran_get_srs_SubframeConfig(mid_t mod_id, uint8_t cc_id)
{
614 615
  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;
616 617
}

Robert Schmidt's avatar
Robert Schmidt committed
618 619
uint8_t flexran_get_srs_MaxUpPts(mid_t mod_id, uint8_t cc_id)
{
620 621
  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;
622 623
}

Robert Schmidt's avatar
Robert Schmidt committed
624 625
uint8_t flexran_get_N_RB_DL(mid_t mod_id, uint8_t cc_id)
{
626 627
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_DL;
628 629
}

Robert Schmidt's avatar
Robert Schmidt committed
630 631
uint8_t flexran_get_N_RB_UL(mid_t mod_id, uint8_t cc_id)
{
632 633
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_UL;
634 635
}

Robert Schmidt's avatar
Robert Schmidt committed
636 637
uint8_t flexran_get_N_RBG(mid_t mod_id, uint8_t cc_id)
{
638 639
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.N_RBG;
640 641
}

Robert Schmidt's avatar
Robert Schmidt committed
642 643
uint8_t flexran_get_subframe_assignment(mid_t mod_id, uint8_t cc_id)
{
644 645
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config;
646 647
}

Robert Schmidt's avatar
Robert Schmidt committed
648 649
uint8_t flexran_get_special_subframe_assignment(mid_t mod_id, uint8_t cc_id)
{
650 651
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config_S;
652 653
}

Robert Schmidt's avatar
Robert Schmidt committed
654 655
long flexran_get_ra_ResponseWindowSize(mid_t mod_id, uint8_t cc_id)
{
656 657
  if (!rrc_is_present(mod_id)) return 0;
  return RC.rrc[mod_id]->configuration.rach_raResponseWindowSize[cc_id];
658 659
}

Robert Schmidt's avatar
Robert Schmidt committed
660 661
long flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, uint8_t cc_id)
{
662 663
  if (!rrc_is_present(mod_id)) return 0;
  return RC.rrc[mod_id]->configuration.rach_macContentionResolutionTimer[cc_id];
664 665
}

Robert Schmidt's avatar
Robert Schmidt committed
666 667
Protocol__FlexDuplexMode flexran_get_duplex_mode(mid_t mod_id, uint8_t cc_id)
{
668 669
  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
670 671 672 673 674 675 676
  case TDD:
    return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD;
  case FDD:
    return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD;
  default:
    return -1;
  }
677 678
}

Robert Schmidt's avatar
Robert Schmidt committed
679 680
long flexran_get_si_window_length(mid_t mod_id, uint8_t cc_id)
{
681 682
  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;
683 684
}

Robert Schmidt's avatar
Robert Schmidt committed
685 686
uint8_t flexran_get_sib1_length(mid_t mod_id, uint8_t cc_id)
{
687 688
  if (!rrc_is_present(mod_id)) return 0;
  return RC.rrc[mod_id]->carrier[cc_id].sizeof_SIB1;
689 690
}

691 692
uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id)
{
693 694
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->pdcch_vars[0].num_pdcch_symbols;
695 696 697 698 699 700 701 702 703 704 705
}



/*
 * ************************************
 * Get Messages for UE Configuration Reply
 * ************************************
 */


Robert Schmidt's avatar
Robert Schmidt committed
706 707
TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id)
{
708
  if (!rrc_is_present(mod_id)) return -1;
709

Robert Schmidt's avatar
Robert Schmidt committed
710
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
711
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
712

Robert Schmidt's avatar
Robert Schmidt committed
713 714 715
  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;
716 717
}

Robert Schmidt's avatar
Robert Schmidt committed
718 719
Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id)
{
720
  if (!rrc_is_present(mod_id)) return -1;
721

Robert Schmidt's avatar
Robert Schmidt committed
722
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
723
  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
724 725 726 727 728 729 730 731 732 733 734

  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.measGapConfig) return -1;
  if (ue_context_p->ue_context.measGapConfig->present != MeasGapConfig_PR_setup) return -1;
  switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) {
  case MeasGapConfig__setup__gapOffset_PR_gp0:
    return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1;
  case MeasGapConfig__setup__gapOffset_PR_gp1:
    return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2;
  default:
    return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF;
735 736 737
  }
}

shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
738

Robert Schmidt's avatar
Robert Schmidt committed
739 740
long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id)
{
741
  if (!rrc_is_present(mod_id)) return -1;
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
742

Robert Schmidt's avatar
Robert Schmidt committed
743
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
744
  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
745 746 747 748 749 750 751 752 753 754 755 756 757

  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.measGapConfig) return -1;
  if (ue_context_p->ue_context.measGapConfig->present != MeasGapConfig_PR_setup) return -1;
  switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) {
  case MeasGapConfig__setup__gapOffset_PR_gp0:
    return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0;
  case MeasGapConfig__setup__gapOffset_PR_gp1:
    return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp1;
  default:
    return -1;
  }
}
758

759
uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
760
{
761
  if (!rrc_is_present(mod_id)) return 0;
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
762

763
  rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id);
764
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
765

Robert Schmidt's avatar
Robert Schmidt committed
766 767
  if (!ue_context_p) return RRC_INACTIVE;
  return ue_context_p->ue_context.Status;
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
768 769
}

Robert Schmidt's avatar
Robert Schmidt committed
770 771
uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id)
{
772 773
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL;
774 775
}

Robert Schmidt's avatar
Robert Schmidt committed
776 777
uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id)
{
778 779
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL;
780 781
}

782 783 784 785 786 787 788 789 790 791 792 793 794
int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id)
{
  if (!rrc_is_present(mod_id)) return -1;

  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
  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;
  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;
  }
795 796 797
  return 0;
}

798
int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
799
{
800 801 802 803 804 805 806 807 808 809 810 811 812 813
  if (!rrc_is_present(mod_id)) return -1;

  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
  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;
814 815
}

816
int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
817
{
818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
  if (!rrc_is_present(mod_id)) return -1;

  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
  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;
833 834
}

835
long flexran_get_ue_category(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
836
{
837 838 839 840 841 842 843 844
  if (!rrc_is_present(mod_id)) return -1;

  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
  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;
845 846
}

847
int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
848
{
849 850 851 852 853 854 855 856 857 858 859 860 861 862
  if (!rrc_is_present(mod_id)) return -1;

  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
  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;
863 864
}

Robert Schmidt's avatar
Robert Schmidt committed
865 866
long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id)
{
867
  if (!rrc_is_present(mod_id)) return -1;
868

Robert Schmidt's avatar
Robert Schmidt committed
869
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
870
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
871

Robert Schmidt's avatar
Robert Schmidt committed
872 873 874 875
  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;
876 877
}

Robert Schmidt's avatar
Robert Schmidt committed
878 879
BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id)
{
880
  if (!rrc_is_present(mod_id)) return -1;
881

Robert Schmidt's avatar
Robert Schmidt committed
882
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
883
  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
884 885 886 887
  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;
888 889
}

Robert Schmidt's avatar
Robert Schmidt committed
890 891
long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id)
{
892
  if (!rrc_is_present(mod_id)) return -1;
893

Robert Schmidt's avatar
Robert Schmidt committed
894
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
895
  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
896 897 898 899 900

  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);
901 902
}

Robert Schmidt's avatar
Robert Schmidt committed
903 904
long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id)
{
905
  if (!rrc_is_present(mod_id)) return -1;
906

Robert Schmidt's avatar
Robert Schmidt committed
907
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
908
  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
909 910 911 912 913

  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;
914 915
}

Robert Schmidt's avatar
Robert Schmidt committed
916 917
long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id)
{
918
  if (!rrc_is_present(mod_id)) return -1;
919

Robert Schmidt's avatar
Robert Schmidt committed
920
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
921
  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
922 923 924 925 926

  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;
927 928
}

Robert Schmidt's avatar
Robert Schmidt committed
929 930
long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id)
{
931
  if (!rrc_is_present(mod_id)) return -1;
Robert Schmidt's avatar
Robert Schmidt committed
932 933

  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
934
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
935

Robert Schmidt's avatar
Robert Schmidt committed
936 937 938 939
  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_CQI_Index;
940 941
}

Robert Schmidt's avatar
Robert Schmidt committed
942 943
BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id)
{
944
  if (!rrc_is_present(mod_id)) return -1;
945

Robert Schmidt's avatar
Robert Schmidt committed
946
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
947
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
948

Robert Schmidt's avatar
Robert Schmidt committed
949 950 951 952 953
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) return -1;
  return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI;
954 955
}

Robert Schmidt's avatar
Robert Schmidt committed
956 957
BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
958 959 960
  if (!rrc_is_present(mod_id)) return -1;
  if (!RC.rrc[mod_id]->carrier[cc_id].sib2) return -1;
  return RC.rrc[mod_id]->carrier[cc_id].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission;
Robert Schmidt's avatar
Robert Schmidt committed
961
}
962

Robert Schmidt's avatar
Robert Schmidt committed
963 964
CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id)
{
965
  if (!rrc_is_present(mod_id)) return -1;
966

Robert Schmidt's avatar
Robert Schmidt committed
967
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
968
  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
969 970 971 972 973

  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1;
  return *ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic;
974 975
}

Robert Schmidt's avatar
Robert Schmidt committed
976 977
long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id)
{
978
  if (!rrc_is_present(mod_id)) return -1;
979

Robert Schmidt's avatar
Robert Schmidt committed
980
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
981
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
982

Robert Schmidt's avatar
Robert Schmidt committed
983 984 985 986 987
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode) return -1;
  return *(ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode);
988 989
}

Robert Schmidt's avatar
Robert Schmidt committed
990 991
long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id)
{
992
  if (!rrc_is_present(mod_id)) return -1;
993

Robert Schmidt's avatar
Robert Schmidt committed
994
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
995
  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
996 997 998 999 1000

  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
  if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1;
  return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor;
1001 1002
}

Robert Schmidt's avatar
Robert Schmidt committed
1003 1004
long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id)
{
1005
  if (!rrc_is_present(mod_id)) return -1;
1006

Robert Schmidt's avatar
Robert Schmidt committed
1007
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
1008
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
1009

Robert Schmidt's avatar
Robert Schmidt committed
1010 1011 1012 1013 1014
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.mac_MainConfig) return -1;
  if (!ue_context_p->ue_context.mac_MainConfig->ext2) return -1;
  if (!ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020) return -1;
  return *(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10);
1015 1016
}

Robert Schmidt's avatar
Robert Schmidt committed
1017 1018
int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id)
{
1019
  if (!rrc_is_present(mod_id)) return -1;
1020

Robert Schmidt's avatar
Robert Schmidt committed
1021
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
1022
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
1023

Robert Schmidt's avatar
Robert Schmidt committed
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
  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;
  switch (ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup) {
  case AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop:
    return 2;
  case AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop:
    return 1;
  default:
    return 0;
1034 1035 1036
  }
}

1037 1038
uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id)
{
1039
  uint64_t imsi;
1040
  if (!rrc_is_present(mod_id)) return 0;
1041 1042 1043 1044

  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);

1045
  if (!ue_context_p) return 0;
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062

  imsi  = ue_context_p->ue_context.imsi.digit15;
  imsi += ue_context_p->ue_context.imsi.digit14 * 10;              // pow(10, 1)
  imsi += ue_context_p->ue_context.imsi.digit13 * 100;             // pow(10, 2)
  imsi += ue_context_p->ue_context.imsi.digit12 * 1000;            // pow(10, 3)
  imsi += ue_context_p->ue_context.imsi.digit11 * 10000;           // pow(10, 4)
  imsi += ue_context_p->ue_context.imsi.digit10 * 100000;          // pow(10, 5)
  imsi += ue_context_p->ue_context.imsi.digit9  * 1000000;         // pow(10, 6)
  imsi += ue_context_p->ue_context.imsi.digit8  * 10000000;        // pow(10, 7)
  imsi += ue_context_p->ue_context.imsi.digit7  * 100000000;       // pow(10, 8)
  imsi += ue_context_p->ue_context.imsi.digit6  * 1000000000;      // pow(10, 9)
  imsi += ue_context_p->ue_context.imsi.digit5  * 10000000000;     // pow(10, 10)
  imsi += ue_context_p->ue_context.imsi.digit4  * 100000000000;    // pow(10, 11)
  imsi += ue_context_p->ue_context.imsi.digit3  * 1000000000000;   // pow(10, 12)
  imsi += ue_context_p->ue_context.imsi.digit2  * 10000000000000;  // pow(10, 13)
  imsi += ue_context_p->ue_context.imsi.digit1  * 100000000000000; // pow(10, 14)
  return imsi;
1063 1064
}

1065
long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id)
Robert Schmidt's avatar
Robert Schmidt committed
1066
{
1067 1068
  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].lcgidmap[lc_id];
1069 1070
}

Robert Schmidt's avatar
Robert Schmidt committed
1071
/* TODO Navid: needs to be revised */
Robert Schmidt's avatar
Robert Schmidt committed
1072 1073 1074 1075 1076
int flexran_get_direction(mid_t ue_id, mid_t lc_id)
{
  switch (lc_id) {
  case DCCH:
  case DCCH1:
1077
    return 2;
Robert Schmidt's avatar
Robert Schmidt committed
1078
  case DTCH:
1079
    return 1;
Robert Schmidt's avatar
Robert Schmidt committed
1080
  default:
1081 1082 1083 1084
    return -1;
  }
}

Robert Schmidt's avatar
Robert Schmidt committed
1085 1086
uint8_t flexran_get_antenna_ports(mid_t mod_id, uint8_t cc_id)
{
1087 1088
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.nb_antenna_ports_eNB;
1089
}
1090

Robert Schmidt's avatar
Robert Schmidt committed
1091 1092
uint32_t flexran_agent_get_operating_dl_freq(mid_t mod_id, uint8_t cc_id)
{
1093 1094
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq / 1000000;
1095 1096
}

Robert Schmidt's avatar
Robert Schmidt committed
1097 1098
uint32_t flexran_agent_get_operating_ul_freq(mid_t mod_id, uint8_t cc_id)
{
1099 1100
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.ul_CarrierFreq / 1000000;
1101 1102
}

Robert Schmidt's avatar
Robert Schmidt committed
1103 1104
uint8_t flexran_agent_get_operating_eutra_band(mid_t mod_id, uint8_t cc_id)
{
1105 1106
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.eutra_band;
1107
}
Robert Schmidt's avatar
Robert Schmidt committed
1108 1109 1110

int8_t flexran_agent_get_operating_pdsch_refpower(mid_t mod_id, uint8_t cc_id)
{
1111 1112
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pdsch_config_common.referenceSignalPower;
1113 1114
}

Robert Schmidt's avatar
Robert Schmidt committed
1115 1116
long flexran_agent_get_operating_pusch_p0(mid_t mod_id, uint8_t cc_id)
{
1117 1118
  if (!rrc_is_present(mod_id)) return 0;
  return RC.rrc[mod_id]->configuration.pusch_p0_Nominal[cc_id];
Robert Schmidt's avatar
Robert Schmidt committed
1119
}
1120

Robert Schmidt's avatar
Robert Schmidt committed
1121 1122
void flexran_agent_set_operating_dl_freq(mid_t mod_id, uint8_t cc_id, uint32_t dl_freq_mhz)
{
1123 1124 1125 1126
  if (phy_is_present(mod_id, cc_id)) {
    RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq = dl_freq_mhz * 1000000;
  } else {
    LOG_E(FLEXRAN_AGENT, "can not set dl_CarrierFreq to %d MHz in PHY: PHY is not present\n", dl_freq_mhz);
Robert Schmidt's avatar
Robert Schmidt committed
1127
  }
1128 1129 1130 1131
  if (rrc_is_present(mod_id)) {
    RC.rrc[mod_id]->configuration.downlink_frequency[cc_id] = dl_freq_mhz * 1000000;
  } else {
    LOG_E(FLEXRAN_AGENT, "can not set downlink_frequency to %d MHz in RRC: RRC is not present\n", dl_freq_mhz);
Robert Schmidt's avatar
Robert Schmidt committed
1132
  }
1133 1134
}

Robert Schmidt's avatar
Robert Schmidt committed
1135 1136
void flexran_agent_set_operating_ul_freq(mid_t mod_id, uint8_t cc_id, int32_t ul_freq_mhz_offset)
{
1137
  if (phy_is_present(mod_id, cc_id)) {
Robert Schmidt's avatar
Robert Schmidt committed
1138
    uint32_t new_ul_freq_mhz = flexran_agent_get_operating_dl_freq(mod_id, cc_id) + ul_freq_mhz_offset;
1139 1140 1141
    RC.eNB[mod_id][cc_id]->frame_parms.ul_CarrierFreq = new_ul_freq_mhz * 1000000;
  } else {
    LOG_E(FLEXRAN_AGENT, "can not set ul_CarrierFreq using offset %d MHz in PHY: PHY is not present\n", ul_freq_mhz_offset);
Robert Schmidt's avatar
Robert Schmidt committed
1142
  }
1143 1144 1145 1146
  if (rrc_is_present(mod_id)) {
    RC.rrc[mod_id]->configuration.uplink_frequency_offset[cc_id] = ul_freq_mhz_offset;
  } else {
    LOG_E(FLEXRAN_AGENT, "can not set uplink_frequency_offset to %d MHz in RRC: RRC is not present\n", ul_freq_mhz_offset);
Robert Schmidt's avatar
Robert Schmidt committed
1147
  }
1148
}
Robert Schmidt's avatar
Robert Schmidt committed
1149 1150 1151

void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t eutra_band)
{
1152 1153 1154 1155
  if (phy_is_present(mod_id, cc_id)) {
    RC.eNB[mod_id][cc_id]->frame_parms.eutra_band = eutra_band;
  } else {
    LOG_E(FLEXRAN_AGENT, "can not set eutra_band to %d in PHY: PHY is not present\n", eutra_band);
Robert Schmidt's avatar
Robert Schmidt committed
1156
  }
1157 1158 1159 1160
  if (rrc_is_present(mod_id)) {
    RC.rrc[mod_id]->configuration.eutra_band[cc_id] = eutra_band;
  } else {
    LOG_E(FLEXRAN_AGENT, "can not set eutra_band to %d in RRC: RRC is not present\n", eutra_band);
Robert Schmidt's avatar
Robert Schmidt committed
1161
  }
1162 1163
}

Robert Schmidt's avatar
Robert Schmidt committed
1164 1165 1166
/* Sets both DL/UL */
void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB)
{
1167 1168 1169 1170 1171
  if (phy_is_present(mod_id, cc_id)) {
    RC.eNB[mod_id][cc_id]->frame_parms.N_RB_DL = N_RB;
    RC.eNB[mod_id][cc_id]->frame_parms.N_RB_UL = N_RB;
  } else {
    LOG_E(FLEXRAN_AGENT, "can not set N_RB_DL and N_RB_UL to %d in PHY: PHY is not present\n", N_RB);
Robert Schmidt's avatar
Robert Schmidt committed
1172
  }
1173 1174 1175 1176
  if (rrc_is_present(mod_id)) {
    RC.rrc[mod_id]->configuration.N_RB_DL[cc_id] = N_RB;
  } else {
    LOG_E(FLEXRAN_AGENT, "can not set N_RB_DL to %d in RRC: RRC is not present\n", N_RB);
Robert Schmidt's avatar
Robert Schmidt committed
1177
  }
1178 1179
}

Robert Schmidt's avatar
Robert Schmidt committed
1180 1181
void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type)
{
1182 1183 1184 1185
  if (phy_is_present(mod_id, cc_id)) {
    RC.eNB[mod_id][cc_id]->frame_parms.frame_type = frame_type;
  } else {
    LOG_E(FLEXRAN_AGENT, "can not set frame_type to %d in PHY: PHY is not present\n", frame_type);
Robert Schmidt's avatar
Robert Schmidt committed
1186
  }
1187 1188 1189 1190
  if (rrc_is_present(mod_id)) {
    RC.rrc[mod_id]->configuration.frame_type[cc_id] = frame_type;
  } else {
    LOG_E(FLEXRAN_AGENT, "can not set frame_type to %d in RRC: RRC is not present\n", frame_type);
Robert Schmidt's avatar
Robert Schmidt committed
1191
  }
1192 1193
}

1194
/*********** PDCP  *************/
1195
/*PDCP super frame counter flexRAN*/
1196
uint32_t flexran_get_pdcp_sfn(const mid_t mod_id){
1197
  return pdcp_enb[mod_id].sfn;
1198
}
1199

1200
/*PDCP super frame counter flexRAN*/
1201 1202
void flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){
  if (obs_window > 0 ){
1203
    Pdcp_stats_tx_window_ms[mod_id][ue_id]=obs_window;
1204 1205
  }
  else{
1206
    Pdcp_stats_tx_window_ms[mod_id][ue_id]=1000;
1207
  }
1208 1209 1210
}

/*PDCP super frame counter flexRAN*/
1211 1212
void flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){
  if (obs_window > 0 ){
1213
    Pdcp_stats_rx_window_ms[mod_id][ue_id]=obs_window;
1214 1215
  }
  else{
1216
    Pdcp_stats_rx_window_ms[mod_id][ue_id]=1000;
1217
  }
1218 1219
}

1220 1221
/*PDCP num tx pdu status flexRAN*/
uint32_t flexran_get_pdcp_tx(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
1222
  if (mod_id <0 || mod_id> MAX_NUM_CCs || ue_id<0 || ue_id> MAX_MOBILES_PER_ENB || lcid<0 || lcid>NB_RB_MAX)
1223 1224 1225 1226 1227 1228 1229 1230 1231 1232
    return -1;
  return Pdcp_stats_tx[mod_id][ue_id][lcid];
}

/*PDCP num tx bytes status flexRAN*/
uint32_t flexran_get_pdcp_tx_bytes(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_tx_bytes[mod_id][ue_id][lcid];
}

/*PDCP number of transmit packet / second status flexRAN*/
1233 1234
uint32_t flexran_get_pdcp_tx_w(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_tx_w[mod_id][ue_id][lcid];
1235 1236 1237
}

/*PDCP throughput (bit/s) status flexRAN*/
1238 1239
uint32_t flexran_get_pdcp_tx_bytes_w(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_tx_bytes_w[mod_id][ue_id][lcid];
1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252
}

/*PDCP tx sequence number flexRAN*/
uint32_t flexran_get_pdcp_tx_sn(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_tx_sn[mod_id][ue_id][lcid];
}

/*PDCP tx aggregated packet arrival  flexRAN*/
uint32_t flexran_get_pdcp_tx_aiat(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_tx_aiat[mod_id][ue_id][lcid];
}

/*PDCP tx aggregated packet arrival  flexRAN*/
1253 1254
uint32_t flexran_get_pdcp_tx_aiat_w(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_tx_aiat_w[mod_id][ue_id][lcid];
1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268
}


/*PDCP num rx pdu status flexRAN*/
uint32_t flexran_get_pdcp_rx(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_rx[mod_id][ue_id][lcid];
}

/*PDCP num rx bytes status flexRAN*/
uint32_t flexran_get_pdcp_rx_bytes(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_rx_bytes[mod_id][ue_id][lcid];
}

/*PDCP number of received packet / second  flexRAN*/
1269 1270
uint32_t flexran_get_pdcp_rx_w(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_rx_w[mod_id][ue_id][lcid];
1271 1272 1273
}

/*PDCP gootput (bit/s) status flexRAN*/
1274 1275
uint32_t flexran_get_pdcp_rx_bytes_w(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_rx_bytes_w[mod_id][ue_id][lcid];
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288
}

/*PDCP rx sequence number flexRAN*/
uint32_t flexran_get_pdcp_rx_sn(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_rx_sn[mod_id][ue_id][lcid];
}

/*PDCP rx aggregated packet arrival  flexRAN*/
uint32_t flexran_get_pdcp_rx_aiat(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_rx_aiat[mod_id][ue_id][lcid];
}

/*PDCP rx aggregated packet arrival  flexRAN*/
1289 1290
uint32_t flexran_get_pdcp_rx_aiat_w(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_rx_aiat_w[mod_id][ue_id][lcid];
1291 1292 1293 1294 1295 1296
}

/*PDCP num of received outoforder pdu status flexRAN*/
uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id,  const mid_t ue_id, const lcid_t lcid){
  return Pdcp_stats_rx_outoforder[mod_id][ue_id][lcid];
}
1297

1298
/******************** RRC *****************************/
1299

Robert Schmidt's avatar
Robert Schmidt committed
1300 1301
MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id)
{
1302
  if (!rrc_is_present(mod_id)) return -1;
1303

Robert Schmidt's avatar
Robert Schmidt committed
1304
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
1305
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
1306

Robert Schmidt's avatar
Robert Schmidt committed
1307 1308 1309
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.measResults) return -1;
  return ue_context_p->ue_context.measResults->measId;
1310
}
1311

Robert Schmidt's avatar
Robert Schmidt committed
1312 1313
float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id)
{
1314
  if (!rrc_is_present(mod_id)) return -1;
1315

Robert Schmidt's avatar
Robert Schmidt committed
1316
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
1317
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
1318

Robert Schmidt's avatar
Robert Schmidt committed
1319 1320 1321
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.measResults) return -1;
  return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult];
1322 1323
}

Robert Schmidt's avatar
Robert Schmidt committed
1324 1325
float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id)
{
1326
  if (!rrc_is_present(mod_id)) return -1;
1327

Robert Schmidt's avatar
Robert Schmidt committed
1328
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
1329
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
1330

Robert Schmidt's avatar
Robert Schmidt committed
1331 1332 1333
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.measResults) return -1;
  return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult];
1334 1335
}

Robert Schmidt's avatar
Robert Schmidt committed
1336 1337 1338
/*Number of neighbouring cells for specific UE*/
int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id)
{
1339
  if (!rrc_is_present(mod_id)) return 0;
1340

Robert Schmidt's avatar
Robert Schmidt committed
1341
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
1342
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
1343

Robert Schmidt's avatar
Robert Schmidt committed
1344 1345 1346 1347 1348 1349
  if (!ue_context_p) return 0;
  if (!ue_context_p->ue_context.measResults) return 0;
  if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0;
  if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0;
  return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count;
}
1350

Robert Schmidt's avatar
Robert Schmidt committed
1351 1352
PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id)
{
1353
  if (!rrc_is_present(mod_id)) return -1;
1354

Robert Schmidt's avatar
Robert Schmidt committed
1355
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
1356
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
1357

Robert Schmidt's avatar
Robert Schmidt committed
1358 1359 1360 1361 1362 1363 1364
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.measResults) return -1;
  if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
  if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
  if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1;
  return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId;
}
1365

Robert Schmidt's avatar
Robert Schmidt committed
1366 1367
float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id)
{
1368
  if (!rrc_is_present(mod_id)) return -1;
1369

Robert Schmidt's avatar
Robert Schmidt committed
1370
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
1371
  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
1372

Robert Schmidt's avatar
Robert Schmidt committed
1373 1374 1375 1376 1377 1378 1379
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.measResults) return -1;
  if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
  if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
  if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1;
  if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult) return 0;
  return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)];
1380 1381
}

Robert Schmidt's avatar
Robert Schmidt committed
1382 1383
float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id)
{
1384
  if (!rrc_is_present(mod_id)) return -1;
1385

Robert Schmidt's avatar
Robert Schmidt committed
1386
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
1387
  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
1388 1389 1390 1391 1392 1393 1394

  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.measResults) return -1;
  if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
  if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
  if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return 0;
  return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)];
1395
}
1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843

int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id)
{
  if (!mac_is_present(mod_id)) return -1;
  int slice_idx = RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[ue_id];
  if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl)
    return RC.mac[mod_id]->slice_info.dl[slice_idx].id;
  return 0;
}

void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return;
  if (flexran_get_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return;
  if (!flexran_dl_slice_exists(mod_id, slice_idx)) return;
  RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[ue_id] = slice_idx;
}

int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id)
{
  if (!mac_is_present(mod_id)) return -1;
  int slice_idx = RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[ue_id];
  if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul)
    return RC.mac[mod_id]->slice_info.ul[slice_idx].id;
  return 0;
}

void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return;
  if (flexran_get_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return;
  if (!flexran_ul_slice_exists(mod_id, slice_idx)) return;
  RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[ue_id] = slice_idx;
}

int flexran_dl_slice_exists(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl;
}

int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id, int slice_default_values_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  if (!flexran_dl_slice_exists(mod_id, slice_default_values_idx)) return -1;
  int newidx = RC.mac[mod_id]->slice_info.n_dl;
  if (newidx >= MAX_NUM_SLICES) return -1;

  ++RC.mac[mod_id]->slice_info.n_dl;
  flexran_set_dl_slice_id(mod_id, newidx, slice_id);
  flexran_set_dl_slice_percentage(mod_id, newidx,
      flexran_get_dl_slice_percentage(mod_id, slice_default_values_idx));
  flexran_set_dl_slice_isolation(mod_id, newidx,
      flexran_get_dl_slice_isolation(mod_id, slice_default_values_idx));
  flexran_set_dl_slice_priority(mod_id, newidx,
      flexran_get_dl_slice_priority(mod_id, slice_default_values_idx));
  flexran_set_dl_slice_position_low(mod_id, newidx,
      flexran_get_dl_slice_position_low(mod_id, slice_default_values_idx));
  flexran_set_dl_slice_position_high(mod_id, newidx,
      flexran_get_dl_slice_position_high(mod_id, slice_default_values_idx));
  flexran_set_dl_slice_maxmcs(mod_id, newidx,
      flexran_get_dl_slice_maxmcs(mod_id, slice_default_values_idx));
  Protocol__FlexDlSorting *sorting = NULL;
  int n = flexran_get_dl_slice_sorting(mod_id, slice_default_values_idx, &sorting);
  flexran_set_dl_slice_sorting(mod_id, newidx, sorting, n);
  free(sorting);
  flexran_set_dl_slice_accounting_policy(mod_id, newidx,
      flexran_get_dl_slice_accounting_policy(mod_id, slice_default_values_idx));
  flexran_set_dl_slice_scheduler_name(mod_id, newidx,
      flexran_get_dl_slice_scheduler_name(mod_id, slice_default_values_idx));
  return newidx;
}

int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id)
{
  if (!mac_is_present(mod_id)) return -1;
  slice_info_t *sli = &RC.mac[mod_id]->slice_info;
  int n = sli->n_dl;
  for (int i = 0; i < n; i++) {
    if (sli->dl[i].id == slice_id) return i;
  }
  return -1;
}

int flexran_remove_dl_slice(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  slice_info_t *sli = &RC.mac[mod_id]->slice_info;
  if (sli->n_dl <= 1) return -1;

  --sli->n_dl;
  /* move last element to the position of the removed one */
  if (slice_idx != sli->n_dl)
    memcpy(&sli->dl[slice_idx], &sli->dl[sli->n_dl], sizeof(sli->dl[sli->n_dl]));

  /* all UEs that have been in the old slice are put into slice index 0 */
  int *assoc_list = RC.mac[mod_id]->UE_list.assoc_dl_slice_idx;
  for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) {
    if (assoc_list[i] == slice_idx)
      assoc_list[i] = 0;
  }
  return sli->n_dl;
}

int flexran_get_num_dl_slices(mid_t mod_id)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.n_dl;
}

int flexran_get_intraslice_sharing_active(mid_t mod_id)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.intraslice_share_active;
}
void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.intraslice_share_active = intraslice_active;
}

int flexran_get_interslice_sharing_active(mid_t mod_id)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.interslice_share_active;
}
void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.interslice_share_active = interslice_active;
}

slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.dl[slice_idx].id;
}
void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.dl[slice_idx].id = slice_id;
}

int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.dl[slice_idx].pct * 100.0f;
}
void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.dl[slice_idx].pct = percentage / 100.0f;
}

int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.dl[slice_idx].isol;
}
void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.dl[slice_idx].isol = is_isolated;
}

int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.dl[slice_idx].prio;
}
void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.dl[slice_idx].prio = priority;
}

int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low;
}
void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low = poslow;
}

int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high;
}
void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high = poshigh;
}

int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs;
}
void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs = maxmcs;
}

int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list)
{
  if (!mac_is_present(mod_id)) return -1;
  if (!(*sorting_list)) {
    *sorting_list = calloc(CR_NUM, sizeof(Protocol__FlexDlSorting));
    if (!(*sorting_list)) return -1;
  }
  uint32_t policy = RC.mac[mod_id]->slice_info.dl[slice_idx].sorting;
  for (int i = 0; i < CR_NUM; i++) {
    switch (policy >> 4 * (CR_NUM - 1 - i) & 0xF) {
    case CR_ROUND:
      (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND;
      break;
    case CR_SRB12:
      (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_SRB12;
      break;
    case CR_HOL:
      (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_HOL;
      break;
    case CR_LC:
      (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LC;
      break;
    case CR_CQI:
      (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_CQI;
      break;
    case CR_LCP:
      (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LCP;
      break;
    default:
      /* this should not happen, but a "default" */
      (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND;
      break;
    }
  }
  return CR_NUM;
}
void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n)
{
  if (!mac_is_present(mod_id)) return;
  uint32_t policy = 0;
  for (int i = 0; i < n && i < CR_NUM; i++) {
    switch (sorting_list[i]) {
    case PROTOCOL__FLEX_DL_SORTING__CR_ROUND:
      policy = policy << 4 | CR_ROUND;
      break;
    case PROTOCOL__FLEX_DL_SORTING__CR_SRB12:
      policy = policy << 4 | CR_SRB12;
      break;
    case PROTOCOL__FLEX_DL_SORTING__CR_HOL:
      policy = policy << 4 | CR_HOL;
      break;
    case PROTOCOL__FLEX_DL_SORTING__CR_LC:
      policy = policy << 4 | CR_LC;
      break;
    case PROTOCOL__FLEX_DL_SORTING__CR_CQI:
      policy = policy << 4 | CR_CQI;
      break;
    case PROTOCOL__FLEX_DL_SORTING__CR_LCP:
      policy = policy << 4 | CR_LCP;
      break;
    default: /* suppresses warnings */
      policy = policy << 4 | CR_ROUND;
      break;
    }
  }
  /* fill up with 0 == CR_ROUND */
  if (CR_NUM > n) policy = policy << 4 * (CR_NUM - n);
  RC.mac[mod_id]->slice_info.dl[slice_idx].sorting = policy;
}

Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR;
  switch (RC.mac[mod_id]->slice_info.dl[slice_idx].accounting) {
  case POL_FAIR:
    return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR;
  case POL_GREEDY:
    return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY;
  default:
    return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR;
  }
}
void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting)
{
  if (!mac_is_present(mod_id)) return;
  switch (accounting) {
  case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR:
    RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR;
    return;
  case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY:
    RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_GREEDY;
    return;
  default:
    RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR;
    return;
  }
}

char *flexran_get_dl_slice_scheduler_name(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return NULL;
  return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name;
}
void flexran_set_dl_slice_scheduler_name(mid_t mod_id, int slice_idx, char *name)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name = name;
  RC.mac[mod_id]->slice_info.dl[slice_idx].update_sched = 1;
}

int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id, int slice_default_values_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  if (!flexran_ul_slice_exists(mod_id, slice_default_values_idx)) return -1;
  int newidx = RC.mac[mod_id]->slice_info.n_ul;
  if (newidx >= MAX_NUM_SLICES) return -1;

  ++RC.mac[mod_id]->slice_info.n_ul;
  flexran_set_ul_slice_id(mod_id, newidx, slice_id);
  flexran_set_ul_slice_percentage(mod_id, newidx,
      flexran_get_ul_slice_percentage(mod_id, slice_default_values_idx));
  /*flexran_set_ul_slice_isolation(mod_id, newidx,
      flexran_get_ul_slice_isolation(mod_id, slice_default_values_idx));
  flexran_set_ul_slice_priority(mod_id, newidx,
      flexran_get_ul_slice_priority(mod_id, slice_default_values_idx));*/
  flexran_set_ul_slice_first_rb(mod_id, newidx,
      flexran_get_ul_slice_first_rb(mod_id, slice_default_values_idx));
  flexran_set_ul_slice_maxmcs(mod_id, newidx,
      flexran_get_ul_slice_maxmcs(mod_id, slice_default_values_idx));
  /*Protocol__FlexUlSorting *sorting = NULL;
  int n = flexran_get_ul_slice_sorting(mod_id, slice_default_values_idx, &sorting);
  flexran_set_ul_slice_sorting(mod_id, newidx, sorting, n);
  free(sorting);*/
  /*flexran_set_ul_slice_accounting_policy(mod_id, newidx,
      flexran_get_ul_slice_accounting_policy(mod_id, slice_default_values_idx));*/
  flexran_set_ul_slice_scheduler_name(mod_id, newidx,
      flexran_get_ul_slice_scheduler_name(mod_id, slice_default_values_idx));
  return newidx;
}

int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id)
{
  if (!mac_is_present(mod_id)) return -1;
  slice_info_t *sli = &RC.mac[mod_id]->slice_info;
  int n = sli->n_ul;
  for (int i = 0; i < n; i++) {
    if (sli->ul[i].id == slice_id) return i;
  }
  return -1;
}

int flexran_remove_ul_slice(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  slice_info_t *sli = &RC.mac[mod_id]->slice_info;
  if (sli->n_ul <= 1) return -1;

  --sli->n_ul;
  /* move last element to the position of the removed one */
  if (slice_idx != sli->n_ul)
    memcpy(&sli->ul[slice_idx], &sli->ul[sli->n_ul], sizeof(sli->ul[sli->n_ul]));

  /* all UEs that have been in the old slice are put into slice index 0 */
  int *assoc_list = RC.mac[mod_id]->UE_list.assoc_ul_slice_idx;
  for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) {
    if (assoc_list[i] == slice_idx)
      assoc_list[i] = 0;
  }
  return sli->n_ul;
}

int flexran_get_num_ul_slices(mid_t mod_id)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.n_ul;
}

int flexran_ul_slice_exists(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul;
}

slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.ul[slice_idx].id;
}
void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.ul[slice_idx].id = slice_id;
}

int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.ul[slice_idx].pct * 100.0f;
}
void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.ul[slice_idx].pct = percentage / 100.0f;
}

int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb;
}

void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb = first_rb;
}

int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return -1;
  return RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs;
}
void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs = maxmcs;
}

char *flexran_get_ul_slice_scheduler_name(mid_t mod_id, int slice_idx)
{
  if (!mac_is_present(mod_id)) return NULL;
  return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name;
}
void flexran_set_ul_slice_scheduler_name(mid_t mod_id, int slice_idx, char *name)
{
  if (!mac_is_present(mod_id)) return;
  RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name = name;
  RC.mac[mod_id]->slice_info.ul[slice_idx].update_sched = 1;
}