flexran_agent_ran_api.c 64.7 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
}

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

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

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

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

Robert Schmidt's avatar
Robert Schmidt committed
139 140 141 142 143
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);
144
  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
145
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
146 147 148
                                                    ,0, 0
#endif
                                                    );
149
  return rlc_status.bytes_in_buffer;
150 151
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Robert Schmidt's avatar
Robert Schmidt committed
367 368 369 370
/* 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"
371
  if (!phy_is_present(mod_id, cc_id)) return 0;
372

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

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

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

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

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

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

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

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

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

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

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

shahab SHARIAT BAGHERI's avatar
shahab SHARIAT BAGHERI committed
448
     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
449 450 451 452 453 454 455 456
   }
   else {

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


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

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

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

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

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


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

505

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

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

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

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

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

Robert Schmidt's avatar
Robert Schmidt committed
536 537
int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id)
{
538 539
  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
540 541 542 543 544 545 546 547 548 549 550
  case oneSixth:
    return 0;
  case half:
    return 1;
  case one:
    return 2;
  case two:
    return 3;
  default:
    return -1;
  }
551 552
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



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


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

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

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

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

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

  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;
736 737 738
  }
}

shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
739

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

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

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

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

764
  rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id);
765
  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
766

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

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

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

783 784 785 786 787 788 789 790 791 792 793 794 795
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;
  }
796 797 798
  return 0;
}

799
int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
800
{
801 802 803 804 805 806 807 808 809 810 811 812 813 814
  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;
815 816
}

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

836
long flexran_get_ue_category(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
837
{
838 839 840 841 842 843 844 845
  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;
846 847
}

848
int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id)
Robert Schmidt's avatar
Robert Schmidt committed
849
{
850 851 852 853 854 855 856 857 858 859 860 861 862 863
  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;
864 865
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Robert Schmidt's avatar
Robert Schmidt committed
957 958
BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
{
959 960 961
  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
962
}
963

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

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

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

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

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

Robert Schmidt's avatar
Robert Schmidt committed
984 985 986 987 988
  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);
989 990
}

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

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

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

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

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

Robert Schmidt's avatar
Robert Schmidt committed
1011 1012 1013 1014 1015
  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);
1016 1017
}

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

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

Robert Schmidt's avatar
Robert Schmidt committed
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
  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;
1035 1036 1037
  }
}

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

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

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

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

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

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

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

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

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

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

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

Robert Schmidt's avatar
Robert Schmidt committed
1116 1117
long flexran_agent_get_operating_pusch_p0(mid_t mod_id, uint8_t cc_id)
{
1118 1119
  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
1120
}
1121

Robert Schmidt's avatar
Robert Schmidt committed
1122 1123
void flexran_agent_set_operating_dl_freq(mid_t mod_id, uint8_t cc_id, uint32_t dl_freq_mhz)
{
1124 1125 1126 1127
  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
1128
  }
1129 1130 1131 1132
  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
1133
  }
1134 1135
}

Robert Schmidt's avatar
Robert Schmidt committed
1136 1137
void flexran_agent_set_operating_ul_freq(mid_t mod_id, uint8_t cc_id, int32_t ul_freq_mhz_offset)
{
1138
  if (phy_is_present(mod_id, cc_id)) {
Robert Schmidt's avatar
Robert Schmidt committed
1139
    uint32_t new_ul_freq_mhz = flexran_agent_get_operating_dl_freq(mod_id, cc_id) + ul_freq_mhz_offset;
1140 1141 1142
    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
1143
  }
1144 1145 1146 1147
  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
1148
  }
1149
}
Robert Schmidt's avatar
Robert Schmidt committed
1150 1151 1152

void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t eutra_band)
{
1153 1154 1155 1156
  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
1157
  }
1158 1159 1160 1161
  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
1162
  }
1163 1164
}

Robert Schmidt's avatar
Robert Schmidt committed
1165 1166 1167
/* Sets both DL/UL */
void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB)
{
1168 1169 1170 1171 1172
  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
1173
  }
1174 1175 1176 1177
  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
1178
  }
1179 1180
}

Robert Schmidt's avatar
Robert Schmidt committed
1181 1182
void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type)
{
1183 1184 1185 1186
  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
1187
  }
1188 1189 1190 1191
  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
1192
  }
1193 1194
}

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

1201
/*PDCP super frame counter flexRAN*/
1202 1203
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 ){
1204
    Pdcp_stats_tx_window_ms[mod_id][ue_id]=obs_window;
1205 1206
  }
  else{
1207
    Pdcp_stats_tx_window_ms[mod_id][ue_id]=1000;
1208
  }
1209 1210 1211
}

/*PDCP super frame counter flexRAN*/
1212 1213
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 ){
1214
    Pdcp_stats_rx_window_ms[mod_id][ue_id]=obs_window;
1215 1216
  }
  else{
1217
    Pdcp_stats_rx_window_ms[mod_id][ue_id]=1000;
1218
  }
1219 1220
}

1221 1222
/*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){
1223
  if (mod_id <0 || mod_id> MAX_NUM_CCs || ue_id<0 || ue_id> MAX_MOBILES_PER_ENB || lcid<0 || lcid>NB_RB_MAX)
1224 1225 1226 1227 1228 1229 1230 1231 1232 1233
    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*/
1234 1235
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];
1236 1237 1238
}

/*PDCP throughput (bit/s) status flexRAN*/
1239 1240
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];
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253
}

/*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*/
1254 1255
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];
1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269
}


/*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*/
1270 1271
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];
1272 1273 1274
}

/*PDCP gootput (bit/s) status flexRAN*/
1275 1276
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];
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289
}

/*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*/
1290 1291
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];
1292 1293 1294 1295 1296 1297
}

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

1299
/******************** RRC *****************************/
1300

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

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

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

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

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

Robert Schmidt's avatar
Robert Schmidt committed
1320 1321 1322
  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];
1323 1324
}

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

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

Robert Schmidt's avatar
Robert Schmidt committed
1332 1333 1334
  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];
1335 1336
}

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

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

Robert Schmidt's avatar
Robert Schmidt committed
1345 1346 1347 1348 1349 1350
  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;
}
1351

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

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

Robert Schmidt's avatar
Robert Schmidt committed
1359 1360 1361 1362 1363 1364 1365
  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;
}
1366

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

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

Robert Schmidt's avatar
Robert Schmidt committed
1374 1375 1376 1377 1378 1379 1380
  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)];
1381 1382
}

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

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

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

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;

1487
  if (sli->dl[slice_idx].sched_name) free(sli->dl[slice_idx].sched_name);
1488 1489 1490 1491
  --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]));
1492
  memset(&sli->dl[sli->n_dl], 0, sizeof(sli->dl[sli->n_dl]));
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

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

1706
char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx)
1707 1708 1709 1710
{
  if (!mac_is_present(mod_id)) return NULL;
  return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name;
}
1711
int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name)
1712
{
1713 1714 1715 1716
  if (!mac_is_present(mod_id)) return 0;
  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;
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
}

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;

1766
  if (sli->dl[slice_idx].sched_name) free(sli->dl[slice_idx].sched_name);
1767 1768 1769 1770
  --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]));
1771
  memset(&sli->ul[sli->n_ul], 0, sizeof(sli->ul[sli->n_ul]));
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

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

1839
char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx)
1840 1841 1842 1843
{
  if (!mac_is_present(mod_id)) return NULL;
  return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name;
}
1844
int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name)
1845
{
1846 1847 1848 1849
  if (!mac_is_present(mod_id)) return 0;
  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;
1850
}