flexran_agent_ran_api.c 63.9 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
 * \date 2017
 * \version 0.1
 */

29
#include <dlfcn.h>
30 31
#include "flexran_agent_ran_api.h"

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

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

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

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

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

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

Robert Schmidt's avatar
Robert Schmidt committed
74 75 76 77 78
/* 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);
79
  uint16_t sfn_sf, frame_mask, sf_mask;
Robert Schmidt's avatar
Robert Schmidt committed
80 81 82

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

85 86 87
  return sfn_sf;
}

Robert Schmidt's avatar
Robert Schmidt committed
88 89 90 91
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);
92
  uint16_t sfn_sf, frame_mask, sf_mask;
Robert Schmidt's avatar
Robert Schmidt committed
93
  int additional_frames;
94

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

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

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

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

107 108 109
  return sfn_sf;
}

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

116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
int flexran_get_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;
}

Robert Schmidt's avatar
Robert Schmidt committed
131 132 133
rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id)
{
  return UE_RNTI(mod_id, ue_id);
134 135
}

136
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
137
{
138 139
  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];
140 141
}

Robert Schmidt's avatar
Robert Schmidt committed
142 143
int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id)
{
144 145
  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;
146 147
}

Robert Schmidt's avatar
Robert Schmidt committed
148 149
uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id)
{
150
  if (!mac_is_present(mod_id)) return 0;
151
  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].dl_cqi[0];
152 153
}

Robert Schmidt's avatar
Robert Schmidt committed
154 155 156 157 158
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);
159
  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
160
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
161 162 163
                                                    ,0, 0
#endif
                                                    );
164
  return rlc_status.bytes_in_buffer;
165 166
}

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

Robert Schmidt's avatar
Robert Schmidt committed
180 181
frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id)
{
182
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
Robert Schmidt's avatar
Robert Schmidt committed
183 184
  frame_t frame = flexran_get_current_frame(mod_id);
  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
185
  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
186
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
187 188 189
                                                    ,0, 0
#endif
                                                    );
190 191 192
  return rlc_status.head_sdu_creation_time;
}

Robert Schmidt's avatar
Robert Schmidt committed
193 194
int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
195
  if (!phy_is_present(mod_id, cc_id)) return 0;
196

197
  int32_t tau = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].timing_advance_update;
Robert Schmidt's avatar
Robert Schmidt committed
198
  switch (flexran_get_N_RB_DL(mod_id, cc_id)) {
199
  case 6:
Robert Schmidt's avatar
Robert Schmidt committed
200
    return tau;
201
  case 15:
Robert Schmidt's avatar
Robert Schmidt committed
202
    return tau / 2;
203
  case 25:
Robert Schmidt's avatar
Robert Schmidt committed
204
    return tau / 4;
205
  case 50:
Robert Schmidt's avatar
Robert Schmidt committed
206
    return tau / 8;
207
  case 75:
Robert Schmidt's avatar
Robert Schmidt committed
208
    return tau / 12;
209
  case 100:
Robert Schmidt's avatar
Robert Schmidt committed
210 211 212 213
    if (flexran_get_threequarter_fs(mod_id, cc_id) == 0)
      return tau / 16;
    else
      return tau / 12;
214 215 216 217 218
  default:
    return 0;
  }
}

219 220
uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id)
{
221 222 223 224
  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;
}

225 226 227
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;
228 229 230
  return RC.mac[mod_id]->eNB_stats[cc_id].total_ulsch_bytes_rx;
}

231 232
uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
233 234 235 236
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].TBS;
}

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

243 244 245 246
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;
247 248
}

249 250
uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, int cc_id)
{
251 252 253 254
  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;
}

255 256 257 258
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;
259 260
}

261 262 263 264
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;
265 266
}

Robert Schmidt's avatar
Robert Schmidt committed
267 268
uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
269 270
  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];
271 272
}

273 274
uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
275 276 277 278
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs1;
}

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

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

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

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

303 304
uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id)
{
305 306 307 308
  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;
}

309 310
uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
311 312 313 314
  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;
}

315 316
uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id)
{
317 318 319 320
  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;
}

321 322
uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id)
{
323 324 325 326
  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;
}

327 328
uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id)
{
329 330 331 332
  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;
}

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

339 340 341 342
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;
343 344
}

345 346
unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index)
{
347 348 349 350
  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];
}

351 352
uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid)
{
353 354 355 356 357
  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
358 359 360 361
/* TODO needs to be revised */
void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
/*
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
  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
378 379
*/
#warning "Implement flexran_update_TA() in RAN API"
380 381
}

Robert Schmidt's avatar
Robert Schmidt committed
382 383 384 385
/* 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"
386
  if (!phy_is_present(mod_id, cc_id)) return 0;
387

Robert Schmidt's avatar
Robert Schmidt committed
388
  /* UE_stats can not be null, they are an array in RC
389 390 391 392 393
  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
394
  */
395

Robert Schmidt's avatar
Robert Schmidt committed
396
  if (flexran_get_TA(mod_id, ue_id, cc_id) != 0) {
397 398 399 400 401 402
    return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA;
  } else {
    return 0;
  }
}

Robert Schmidt's avatar
Robert Schmidt committed
403 404
int flexran_get_active_CC(mid_t mod_id, mid_t ue_id)
{
405 406
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.numactiveCCs[ue_id];
407 408
}

Robert Schmidt's avatar
Robert Schmidt committed
409 410
uint8_t flexran_get_current_RI(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
411 412
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].rank;
413 414
}

Robert Schmidt's avatar
Robert Schmidt committed
415 416
int flexran_get_tpc(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
417
  if (!phy_is_present(mod_id, cc_id)) return 0;
Robert Schmidt's avatar
Robert Schmidt committed
418 419 420 421

  /* 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);
422 423
  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
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447

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

Robert Schmidt's avatar
Robert Schmidt committed
449 450
  /* TODO IMPLEMENT */
  /*
451 452 453
  uint8_t harq_pid;
  uint8_t harq_round;
  
454
  if (mac_xface_not_ready()) return 0 ;
455 456

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

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

shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
461 462
   } else if (harq_flag == openair_harq_UL){

shahab SHARIAT BAGHERI's avatar
shahab SHARIAT BAGHERI committed
463
     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
464 465 466 467 468 469 470 471
   }
   else {

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


  *pid = harq_pid;
Robert Schmidt's avatar
Robert Schmidt committed
472
  *round = harq_round;*/
473 474 475 476 477
  /* if (round > 0) { */
  /*   *status = 1; */
  /* } else { */
  /*   *status = 0; */
  /* } */
Robert Schmidt's avatar
Robert Schmidt committed
478 479 480
  /*return *round;*/
#warning "Implement flexran_get_harq() in RAN API"
  return 0;
481 482
}

Robert Schmidt's avatar
Robert Schmidt committed
483 484
int32_t flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
485 486
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_dBm;
487 488
}

Robert Schmidt's avatar
Robert Schmidt committed
489 490
int8_t flexran_get_p0_nominal_pucch(mid_t mod_id, uint8_t cc_id)
{
491 492
  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;
493 494
}

Robert Schmidt's avatar
Robert Schmidt committed
495 496
int32_t flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
497 498
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update;
499 500
}

Robert Schmidt's avatar
Robert Schmidt committed
501 502
int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
503 504
  if (!phy_is_present(mod_id, cc_id)) return 0;
  RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update = 0;
505 506 507 508 509 510 511 512 513
  return 0;
}


/*
 * ************************************
 * Get Messages for eNB Configuration Reply
 * ************************************
 */
Robert Schmidt's avatar
Robert Schmidt committed
514 515
uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id)
{
516 517
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.threequarter_fs;
518 519
}

520

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

Robert Schmidt's avatar
Robert Schmidt committed
527 528
PUSCH_HOPPING_t flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id)
{
529 530
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode;
531 532
}

Robert Schmidt's avatar
Robert Schmidt committed
533 534
uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id)
{
535 536
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.n_SB;
537 538
}

Robert Schmidt's avatar
Robert Schmidt committed
539 540
uint8_t flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id)
{
541 542
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM;
543 544
}

Robert Schmidt's avatar
Robert Schmidt committed
545 546
PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id)
{
547 548
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration;
549 550
}

Robert Schmidt's avatar
Robert Schmidt committed
551 552
int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id)
{
553 554
  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
555 556 557 558 559 560 561 562 563 564 565
  case oneSixth:
    return 0;
  case half:
    return 1;
  case one:
    return 2;
  case two:
    return 3;
  default:
    return -1;
  }
566 567
}

Robert Schmidt's avatar
Robert Schmidt committed
568 569
uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id)
{
570 571
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.n1PUCCH_AN;
572 573
}

Robert Schmidt's avatar
Robert Schmidt committed
574 575
uint8_t flexran_get_nRB_CQI(mid_t mod_id, uint8_t cc_id)
{
576 577
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.nRB_CQI;
578 579
}

Robert Schmidt's avatar
Robert Schmidt committed
580 581
uint8_t flexran_get_deltaPUCCH_Shift(mid_t mod_id, uint8_t cc_id)
{
582 583
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.deltaPUCCH_Shift;
584 585
}

Robert Schmidt's avatar
Robert Schmidt committed
586 587
uint8_t flexran_get_prach_ConfigIndex(mid_t mod_id, uint8_t cc_id)
{
588 589
  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;
590 591
}

Robert Schmidt's avatar
Robert Schmidt committed
592 593
uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id)
{
594 595
  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;
596 597
}

Robert Schmidt's avatar
Robert Schmidt committed
598 599
uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id)
{
600 601
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.maxHARQ_Msg3Tx;
602 603
}

Robert Schmidt's avatar
Robert Schmidt committed
604 605
lte_prefix_type_t flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id)
{
606 607
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.Ncp_UL;
608 609
}

Robert Schmidt's avatar
Robert Schmidt committed
610 611
lte_prefix_type_t flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id)
{
612 613
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.Ncp;
614 615
}

Robert Schmidt's avatar
Robert Schmidt committed
616 617
uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id)
{
618 619
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.Nid_cell;
620 621
}

Robert Schmidt's avatar
Robert Schmidt committed
622 623
uint8_t flexran_get_srs_BandwidthConfig(mid_t mod_id, uint8_t cc_id)
{
624 625
  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;
626 627
}

Robert Schmidt's avatar
Robert Schmidt committed
628 629
uint8_t flexran_get_srs_SubframeConfig(mid_t mod_id, uint8_t cc_id)
{
630 631
  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;
632 633
}

Robert Schmidt's avatar
Robert Schmidt committed
634 635
uint8_t flexran_get_srs_MaxUpPts(mid_t mod_id, uint8_t cc_id)
{
636 637
  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;
638 639
}

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

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

Robert Schmidt's avatar
Robert Schmidt committed
652 653
uint8_t flexran_get_N_RBG(mid_t mod_id, uint8_t cc_id)
{
654 655
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.N_RBG;
656 657
}

Robert Schmidt's avatar
Robert Schmidt committed
658 659
uint8_t flexran_get_subframe_assignment(mid_t mod_id, uint8_t cc_id)
{
660 661
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config;
662 663
}

Robert Schmidt's avatar
Robert Schmidt committed
664 665
uint8_t flexran_get_special_subframe_assignment(mid_t mod_id, uint8_t cc_id)
{
666 667
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config_S;
668 669
}

Robert Schmidt's avatar
Robert Schmidt committed
670 671
long flexran_get_ra_ResponseWindowSize(mid_t mod_id, uint8_t cc_id)
{
672 673
  if (!rrc_is_present(mod_id)) return 0;
  return RC.rrc[mod_id]->configuration.rach_raResponseWindowSize[cc_id];
674 675
}

Robert Schmidt's avatar
Robert Schmidt committed
676 677
long flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, uint8_t cc_id)
{
678 679
  if (!rrc_is_present(mod_id)) return 0;
  return RC.rrc[mod_id]->configuration.rach_macContentionResolutionTimer[cc_id];
680 681
}

Robert Schmidt's avatar
Robert Schmidt committed
682 683
Protocol__FlexDuplexMode flexran_get_duplex_mode(mid_t mod_id, uint8_t cc_id)
{
684 685
  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
686 687 688 689 690 691 692
  case TDD:
    return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD;
  case FDD:
    return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD;
  default:
    return -1;
  }
693 694
}

Robert Schmidt's avatar
Robert Schmidt committed
695 696
long flexran_get_si_window_length(mid_t mod_id, uint8_t cc_id)
{
697 698
  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;
699 700
}

Robert Schmidt's avatar
Robert Schmidt committed
701 702
uint8_t flexran_get_sib1_length(mid_t mod_id, uint8_t cc_id)
{
703 704
  if (!rrc_is_present(mod_id)) return 0;
  return RC.rrc[mod_id]->carrier[cc_id].sizeof_SIB1;
705 706
}

707 708
uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id)
{
709 710
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->pdcch_vars[0].num_pdcch_symbols;
711 712 713 714 715 716 717 718 719 720 721
}



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


Robert Schmidt's avatar
Robert Schmidt committed
722 723
TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id)
{
724
  if (!rrc_is_present(mod_id)) return -1;
725

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

Robert Schmidt's avatar
Robert Schmidt committed
729 730 731
  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;
732 733
}

Robert Schmidt's avatar
Robert Schmidt committed
734 735
Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id)
{
736
  if (!rrc_is_present(mod_id)) return -1;
737

Robert Schmidt's avatar
Robert Schmidt committed
738
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
739
  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
740 741 742 743 744 745 746 747 748 749 750

  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;
751 752 753
  }
}

shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
754

Robert Schmidt's avatar
Robert Schmidt committed
755 756
long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id)
{
757
  if (!rrc_is_present(mod_id)) return -1;
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
758

Robert Schmidt's avatar
Robert Schmidt committed
759
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
760
  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
761 762 763 764 765 766 767 768 769 770 771 772 773

  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;
  }
}
774

775
uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
776
{
777
  if (!rrc_is_present(mod_id)) return 0;
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
778

779
  rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id);
780
  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
781

Robert Schmidt's avatar
Robert Schmidt committed
782 783
  if (!ue_context_p) return RRC_INACTIVE;
  return ue_context_p->ue_context.Status;
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
784 785
}

Robert Schmidt's avatar
Robert Schmidt committed
786 787
uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id)
{
788 789
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL;
790 791
}

Robert Schmidt's avatar
Robert Schmidt committed
792 793
uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id)
{
794 795
  if (!mac_is_present(mod_id)) return 0;
  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL;
796 797
}

798 799 800 801 802 803 804 805 806 807 808 809 810
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;
  }
811 812 813
  return 0;
}

814
int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
815
{
816 817 818 819 820 821 822 823 824 825 826 827 828 829
  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;
830 831
}

832
int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
833
{
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848
  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;
849 850
}

851
long flexran_get_ue_category(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
852
{
853 854 855 856 857 858 859 860
  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;
861 862
}

863
int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
864
{
865 866 867 868 869 870 871 872 873 874 875 876 877 878
  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;
879 880
}

Robert Schmidt's avatar
Robert Schmidt committed
881 882
long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id)
{
883
  if (!rrc_is_present(mod_id)) return -1;
884

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

Robert Schmidt's avatar
Robert Schmidt committed
888 889 890 891
  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;
892 893
}

Robert Schmidt's avatar
Robert Schmidt committed
894 895
BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id)
{
896
  if (!rrc_is_present(mod_id)) return -1;
897

Robert Schmidt's avatar
Robert Schmidt committed
898
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
899
  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
900 901 902 903
  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;
904 905
}

Robert Schmidt's avatar
Robert Schmidt committed
906 907
long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id)
{
908
  if (!rrc_is_present(mod_id)) return -1;
909

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

  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);
917 918
}

Robert Schmidt's avatar
Robert Schmidt committed
919 920
long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id)
{
921
  if (!rrc_is_present(mod_id)) return -1;
922

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

  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;
930 931
}

Robert Schmidt's avatar
Robert Schmidt committed
932 933
long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id)
{
934
  if (!rrc_is_present(mod_id)) return -1;
935

Robert Schmidt's avatar
Robert Schmidt committed
936
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
937
  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
938 939 940 941 942

  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;
943 944
}

Robert Schmidt's avatar
Robert Schmidt committed
945 946
long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id)
{
947
  if (!rrc_is_present(mod_id)) return -1;
Robert Schmidt's avatar
Robert Schmidt committed
948 949

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

Robert Schmidt's avatar
Robert Schmidt committed
952 953 954 955
  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;
956 957
}

Robert Schmidt's avatar
Robert Schmidt committed
958 959
BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id)
{
960
  if (!rrc_is_present(mod_id)) return -1;
961

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

Robert Schmidt's avatar
Robert Schmidt committed
965 966 967 968 969
  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;
970 971
}

Robert Schmidt's avatar
Robert Schmidt committed
972 973
BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
974 975 976
  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
977
}
978

Robert Schmidt's avatar
Robert Schmidt committed
979 980
CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id)
{
981
  if (!rrc_is_present(mod_id)) return -1;
982

Robert Schmidt's avatar
Robert Schmidt committed
983
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
984
  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
985 986 987 988 989

  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;
990 991
}

Robert Schmidt's avatar
Robert Schmidt committed
992 993
long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id)
{
994
  if (!rrc_is_present(mod_id)) return -1;
995

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

Robert Schmidt's avatar
Robert Schmidt committed
999 1000 1001 1002 1003
  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);
1004 1005
}

Robert Schmidt's avatar
Robert Schmidt committed
1006 1007
long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id)
{
1008
  if (!rrc_is_present(mod_id)) return -1;
1009

Robert Schmidt's avatar
Robert Schmidt committed
1010
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
1011
  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
1012 1013 1014 1015 1016

  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;
1017 1018
}

Robert Schmidt's avatar
Robert Schmidt committed
1019 1020
long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id)
{
1021
  if (!rrc_is_present(mod_id)) return -1;
1022

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

Robert Schmidt's avatar
Robert Schmidt committed
1026 1027 1028 1029 1030
  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);
1031 1032
}

Robert Schmidt's avatar
Robert Schmidt committed
1033 1034
int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id)
{
1035
  if (!rrc_is_present(mod_id)) return -1;
1036

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

Robert Schmidt's avatar
Robert Schmidt committed
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049
  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;
1050 1051 1052
  }
}

1053 1054
uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id)
{
1055
  uint64_t imsi;
1056
  if (!rrc_is_present(mod_id)) return 0;
1057 1058 1059 1060

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

1061
  if (!ue_context_p) return 0;
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078

  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;
1079 1080
}

1081
long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id)
Robert Schmidt's avatar
Robert Schmidt committed
1082
{
1083 1084
  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];
1085 1086
}

Robert Schmidt's avatar
Robert Schmidt committed
1087
/* TODO Navid: needs to be revised */
Robert Schmidt's avatar
Robert Schmidt committed
1088 1089 1090 1091 1092
int flexran_get_direction(mid_t ue_id, mid_t lc_id)
{
  switch (lc_id) {
  case DCCH:
  case DCCH1:
1093
    return 2;
Robert Schmidt's avatar
Robert Schmidt committed
1094
  case DTCH:
1095
    return 1;
Robert Schmidt's avatar
Robert Schmidt committed
1096
  default:
1097 1098 1099 1100
    return -1;
  }
}

Robert Schmidt's avatar
Robert Schmidt committed
1101 1102
uint8_t flexran_get_antenna_ports(mid_t mod_id, uint8_t cc_id)
{
1103 1104
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.nb_antenna_ports_eNB;
1105
}
1106

Robert Schmidt's avatar
Robert Schmidt committed
1107 1108
uint32_t flexran_agent_get_operating_dl_freq(mid_t mod_id, uint8_t cc_id)
{
1109 1110
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq / 1000000;
1111 1112
}

Robert Schmidt's avatar
Robert Schmidt committed
1113 1114
uint32_t flexran_agent_get_operating_ul_freq(mid_t mod_id, uint8_t cc_id)
{
1115 1116
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.ul_CarrierFreq / 1000000;
1117 1118
}

Robert Schmidt's avatar
Robert Schmidt committed
1119 1120
uint8_t flexran_agent_get_operating_eutra_band(mid_t mod_id, uint8_t cc_id)
{
1121 1122
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.eutra_band;
1123
}
Robert Schmidt's avatar
Robert Schmidt committed
1124 1125 1126

int8_t flexran_agent_get_operating_pdsch_refpower(mid_t mod_id, uint8_t cc_id)
{
1127 1128
  if (!phy_is_present(mod_id, cc_id)) return 0;
  return RC.eNB[mod_id][cc_id]->frame_parms.pdsch_config_common.referenceSignalPower;
1129 1130
}

Robert Schmidt's avatar
Robert Schmidt committed
1131 1132
long flexran_agent_get_operating_pusch_p0(mid_t mod_id, uint8_t cc_id)
{
1133 1134
  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
1135
}
1136

Robert Schmidt's avatar
Robert Schmidt committed
1137 1138
void flexran_agent_set_operating_dl_freq(mid_t mod_id, uint8_t cc_id, uint32_t dl_freq_mhz)
{
1139 1140 1141 1142
  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
1143
  }
1144 1145 1146 1147
  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
1148
  }
1149 1150
}

Robert Schmidt's avatar
Robert Schmidt committed
1151 1152
void flexran_agent_set_operating_ul_freq(mid_t mod_id, uint8_t cc_id, int32_t ul_freq_mhz_offset)
{
1153
  if (phy_is_present(mod_id, cc_id)) {
Robert Schmidt's avatar
Robert Schmidt committed
1154
    uint32_t new_ul_freq_mhz = flexran_agent_get_operating_dl_freq(mod_id, cc_id) + ul_freq_mhz_offset;
1155 1156 1157
    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
1158
  }
1159 1160 1161 1162
  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
1163
  }
1164
}
Robert Schmidt's avatar
Robert Schmidt committed
1165 1166 1167

void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t eutra_band)
{
1168 1169 1170 1171
  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
1172
  }
1173 1174 1175 1176
  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
1177
  }
1178 1179
}

Robert Schmidt's avatar
Robert Schmidt committed
1180 1181 1182
/* Sets both DL/UL */
void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB)
{
1183 1184 1185 1186 1187
  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
1188
  }
1189 1190 1191 1192
  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
1193
  }
1194 1195
}

Robert Schmidt's avatar
Robert Schmidt committed
1196 1197
void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type)
{
1198 1199 1200 1201
  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
1202
  }
1203 1204 1205 1206
  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
1207
  }
1208 1209
}

1210
/*********** PDCP  *************/
1211
/*PDCP super frame counter flexRAN*/
1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230

/* TODO the following is a hack. all the functions below should instead already
 * receive the PDCP's uid and operate on it and the caller has the obligation
 * to get the ID for this layer.
 */
static inline uint16_t flexran_get_pdcp_uid(mid_t mod_id, mid_t ue_id)
{
  rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id);
  if (rnti == NOT_A_RNTI) return 0;

  for (uint16_t pdcp_uid = 0; pdcp_uid < MAX_MOBILES_PER_ENB; ++pdcp_uid) {
    if (pdcp_enb[mod_id].rnti[pdcp_uid] == rnti)
      return pdcp_uid;
  }
  return 0;
}

uint32_t flexran_get_pdcp_sfn(mid_t mod_id)
{
1231
  return pdcp_enb[mod_id].sfn;
1232
}
1233

1234
/*PDCP super frame counter flexRAN*/
1235 1236 1237
void flexran_set_pdcp_tx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
1238
  if (obs_window > 0 ){
1239
    Pdcp_stats_tx_window_ms[mod_id][uid]=obs_window;
1240 1241
  }
  else{
1242
    Pdcp_stats_tx_window_ms[mod_id][uid]=1000;
1243
  }
1244 1245 1246
}

/*PDCP super frame counter flexRAN*/
1247 1248 1249
void flexran_set_pdcp_rx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
1250
  if (obs_window > 0 ){
1251
    Pdcp_stats_rx_window_ms[mod_id][uid]=obs_window;
1252 1253
  }
  else{
1254
    Pdcp_stats_rx_window_ms[mod_id][uid]=1000;
1255
  }
1256 1257
}

1258
/*PDCP num tx pdu status flexRAN*/
1259 1260 1261 1262
uint32_t flexran_get_pdcp_tx(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  if (mod_id < 0 || mod_id > MAX_NUM_CCs || ue_id < 0 || ue_id > MAX_MOBILES_PER_ENB
      || lcid < 0 || lcid > NB_RB_MAX)
1263
    return -1;
1264 1265
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_tx[mod_id][uid][lcid];
1266 1267 1268
}

/*PDCP num tx bytes status flexRAN*/
1269 1270 1271 1272
uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_tx_bytes[mod_id][uid][lcid];
1273 1274 1275
}

/*PDCP number of transmit packet / second status flexRAN*/
1276 1277 1278 1279
uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_tx_w[mod_id][uid][lcid];
1280 1281 1282
}

/*PDCP throughput (bit/s) status flexRAN*/
1283 1284 1285 1286
uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_tx_bytes_w[mod_id][uid][lcid];
1287 1288 1289
}

/*PDCP tx sequence number flexRAN*/
1290 1291 1292 1293
uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_tx_sn[mod_id][uid][lcid];
1294 1295 1296
}

/*PDCP tx aggregated packet arrival  flexRAN*/
1297 1298 1299 1300
uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_tx_aiat[mod_id][uid][lcid];
1301 1302 1303
}

/*PDCP tx aggregated packet arrival  flexRAN*/
1304 1305 1306 1307
uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_tx_aiat_w[mod_id][uid][lcid];
1308 1309 1310
}

/*PDCP num rx pdu status flexRAN*/
1311 1312 1313 1314
uint32_t flexran_get_pdcp_rx(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_rx[mod_id][uid][lcid];
1315 1316 1317
}

/*PDCP num rx bytes status flexRAN*/
1318 1319 1320 1321
uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_rx_bytes[mod_id][uid][lcid];
1322 1323 1324
}

/*PDCP number of received packet / second  flexRAN*/
1325 1326 1327 1328
uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_rx_w[mod_id][uid][lcid];
1329 1330 1331
}

/*PDCP gootput (bit/s) status flexRAN*/
1332 1333 1334 1335
uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_rx_bytes_w[mod_id][uid][lcid];
1336 1337 1338
}

/*PDCP rx sequence number flexRAN*/
1339 1340 1341 1342
uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_rx_sn[mod_id][uid][lcid];
1343 1344 1345
}

/*PDCP rx aggregated packet arrival  flexRAN*/
1346 1347 1348 1349
uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_rx_aiat[mod_id][uid][lcid];
1350 1351 1352
}

/*PDCP rx aggregated packet arrival  flexRAN*/
1353 1354 1355 1356
uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_rx_aiat_w[mod_id][uid][lcid];
1357 1358 1359
}

/*PDCP num of received outoforder pdu status flexRAN*/
1360 1361 1362 1363
uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, mid_t ue_id, lcid_t lcid)
{
  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
  return Pdcp_stats_rx_outoforder[mod_id][uid][lcid];
1364
}
1365

1366
/******************** RRC *****************************/
1367

Robert Schmidt's avatar
Robert Schmidt committed
1368 1369
MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id)
{
1370
  if (!rrc_is_present(mod_id)) return -1;
1371

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

Robert Schmidt's avatar
Robert Schmidt committed
1375 1376 1377
  if (!ue_context_p) return -1;
  if (!ue_context_p->ue_context.measResults) return -1;
  return ue_context_p->ue_context.measResults->measId;
1378
}
1379

Robert Schmidt's avatar
Robert Schmidt committed
1380 1381
float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id)
{
1382
  if (!rrc_is_present(mod_id)) return -1;
1383

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

Robert Schmidt's avatar
Robert Schmidt committed
1387 1388 1389
  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];
1390 1391
}

Robert Schmidt's avatar
Robert Schmidt committed
1392 1393
float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id)
{
1394
  if (!rrc_is_present(mod_id)) return -1;
1395

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

Robert Schmidt's avatar
Robert Schmidt committed
1399 1400 1401
  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];
1402 1403
}

Robert Schmidt's avatar
Robert Schmidt committed
1404 1405 1406
/*Number of neighbouring cells for specific UE*/
int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id)
{
1407
  if (!rrc_is_present(mod_id)) return 0;
1408

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

Robert Schmidt's avatar
Robert Schmidt committed
1412 1413 1414 1415 1416 1417
  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;
}
1418

Robert Schmidt's avatar
Robert Schmidt committed
1419 1420
PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id)
{
1421
  if (!rrc_is_present(mod_id)) return -1;
1422

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

Robert Schmidt's avatar
Robert Schmidt committed
1426 1427 1428 1429 1430 1431 1432
  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;
}
1433

Robert Schmidt's avatar
Robert Schmidt committed
1434 1435
float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id)
{
1436
  if (!rrc_is_present(mod_id)) return -1;
1437

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

Robert Schmidt's avatar
Robert Schmidt committed
1441 1442 1443 1444 1445 1446 1447
  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)];
1448 1449
}

Robert Schmidt's avatar
Robert Schmidt committed
1450 1451
float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id)
{
1452
  if (!rrc_is_present(mod_id)) return -1;
1453

Robert Schmidt's avatar
Robert Schmidt committed
1454
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
1455
  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
1456 1457 1458 1459 1460 1461 1462

  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)];
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

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

1505
int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id)
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
{
  if (!mac_is_present(mod_id)) 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);
  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;

1532
  if (sli->dl[slice_idx].sched_name) free(sli->dl[slice_idx].sched_name);
1533 1534 1535 1536
  --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]));
1537
  memset(&sli->dl[sli->n_dl], 0, sizeof(sli->dl[sli->n_dl]));
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

  /* 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;
  }
}

1751
char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx)
1752 1753 1754 1755
{
  if (!mac_is_present(mod_id)) return NULL;
  return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name;
}
1756
int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name)
1757
{
1758
  if (!mac_is_present(mod_id)) return 0;
1759 1760
  if (RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name)
    free(RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name);
1761 1762 1763
  RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name = strdup(name);
  RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb = dlsym(NULL, name);
  return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb != NULL;
1764 1765
}

1766
int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id)
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
{
  if (!mac_is_present(mod_id)) 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);
  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;

1793
  if (sli->ul[slice_idx].sched_name) free(sli->ul[slice_idx].sched_name);
1794 1795 1796 1797
  --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]));
1798
  memset(&sli->ul[sli->n_ul], 0, sizeof(sli->ul[sli->n_ul]));
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 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865

  /* 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;
}

1866
char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx)
1867 1868 1869 1870
{
  if (!mac_is_present(mod_id)) return NULL;
  return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name;
}
1871
int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name)
1872
{
1873
  if (!mac_is_present(mod_id)) return 0;
1874 1875
  if (RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name)
    free(RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name);
1876 1877 1878
  RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name = strdup(name);
  RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb = dlsym(NULL, name);
  return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb != NULL;
1879
}