flexran_agent_common.c 76.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */ 
21

22
/*! \file flexran_agent_common.c
23
 * \brief common primitives for all agents 
24
 * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein
25 26 27 28
 * \date 2016
 * \version 0.1
 */

29 30
#include<stdio.h>
#include <time.h>
31

32 33 34
#include "flexran_agent_common.h"
#include "flexran_agent_common_internal.h"
#include "flexran_agent_extern.h"
35
#include "flexran_agent_net_comm.h"
36
#include "PHY/extern.h"
37 38
#include "log.h"

39
#include "SCHED/defs.h"
40 41
#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
42
#include "rrc_eNB_UE_context.h"
43

44 45
void * enb[NUM_MAX_ENB];
void * enb_ue[NUM_MAX_ENB];
46
void * enb_rrc[NUM_MAX_ENB];
47

48 49 50 51
/*
 * message primitives
 */

52
int flexran_agent_serialize_message(Protocol__FlexranMessage *msg, void **buf, int *size) {
53

54
  *size = protocol__flexran_message__get_packed_size(msg);
55 56 57 58 59
  
  *buf = malloc(*size);
  if (buf == NULL)
    goto error;
  
60
  protocol__flexran_message__pack(msg, *buf);
61 62 63 64
  
  return 0;
  
 error:
65
  LOG_E(FLEXRAN_AGENT, "an error occured\n"); // change the com
66 67 68 69 70 71 72
  return -1;
}



/* We assume that the buffer size is equal to the message size.
   Should be chekced durint Tx/Rx */
73
int flexran_agent_deserialize_message(void *data, int size, Protocol__FlexranMessage **msg) {
74
  *msg = protocol__flexran_message__unpack(NULL, size, data);
75 76
  if (*msg == NULL)
    goto error;
77

78 79 80 81 82 83 84 85 86
  return 0;
  
 error:
  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}



87
int flexran_create_header(xid_t xid, Protocol__FlexType type,  Protocol__FlexHeader **header) {
88
  
89
  *header = malloc(sizeof(Protocol__FlexHeader));
90 91 92
  if(*header == NULL)
    goto error;
  
93 94
  protocol__flex_header__init(*header);
  (*header)->version = FLEXRAN_VERSION;
95 96 97 98 99 100 101 102 103
  (*header)->has_version = 1; 
  // check if the type is set
  (*header)->type = type;
  (*header)->has_type = 1;
  (*header)->xid = xid;
  (*header)->has_xid = 1;
  return 0;

 error:
104
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
105 106 107 108
  return -1;
}


109
int flexran_agent_hello(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
110
 
111
  Protocol__FlexHeader *header;
112 113
  /*TODO: Need to set random xid or xid from received hello message*/
  xid_t xid = 1;
114

115 116
  Protocol__FlexHello *hello_msg;
  hello_msg = malloc(sizeof(Protocol__FlexHello));
117 118
  if(hello_msg == NULL)
    goto error;
119
  protocol__flex_hello__init(hello_msg);
120 121 122 123

  if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_HELLO, &header) != 0)
    goto error;

124 125
  hello_msg->header = header;

126
  *msg = malloc(sizeof(Protocol__FlexranMessage));
127 128 129
  if(*msg == NULL)
    goto error;
  
130 131 132
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
133
  (*msg)->has_msg_dir = 1;
134 135 136 137 138 139 140 141 142 143
  (*msg)->hello_msg = hello_msg;
  return 0;
  
 error:
  if(header != NULL)
    free(header);
  if(hello_msg != NULL)
    free(hello_msg);
  if(*msg != NULL)
    free(*msg);
144
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
145 146 147 148
  return -1;
}


149
int flexran_agent_destroy_hello(Protocol__FlexranMessage *msg) {
150
  
151
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG)
152 153 154 155 156 157 158 159
    goto error;
  
  free(msg->hello_msg->header);
  free(msg->hello_msg);
  free(msg);
  return 0;

 error:
160
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
161 162 163 164
  return -1;
}


165
int flexran_agent_echo_request(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg) {
166
  Protocol__FlexHeader *header;
167 168
  /*TODO: Need to set a random xid*/
  xid_t xid = 1;
169

170
  Protocol__FlexEchoRequest *echo_request_msg = NULL;
171
  echo_request_msg = malloc(sizeof(Protocol__FlexEchoRequest));
172 173
  if(echo_request_msg == NULL)
    goto error;
174
  protocol__flex_echo_request__init(echo_request_msg);
175 176 177 178

  if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_ECHO_REQUEST, &header) != 0)
    goto error;

179 180
  echo_request_msg->header = header;

181
  *msg = malloc(sizeof(Protocol__FlexranMessage));
182 183
  if(*msg == NULL)
    goto error;
184 185 186
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
  (*msg)->echo_request_msg = echo_request_msg;
  return 0;

 error:
  if(header != NULL)
    free(header);
  if(echo_request_msg != NULL)
    free(echo_request_msg);
  if(*msg != NULL)
    free(*msg);
  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}


202
int flexran_agent_destroy_echo_request(Protocol__FlexranMessage *msg) {
203
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG)
204 205 206 207 208 209 210 211
    goto error;
  
  free(msg->echo_request_msg->header);
  free(msg->echo_request_msg);
  free(msg);
  return 0;
  
 error:
212
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
213 214 215 216 217
  return -1;
}



218
int flexran_agent_echo_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
219 220
  
  xid_t xid;
221 222
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexEchoRequest *echo_req = input->echo_request_msg;
223 224
  xid = (echo_req->header)->xid;

225
  Protocol__FlexEchoReply *echo_reply_msg = NULL;
226
  echo_reply_msg = malloc(sizeof(Protocol__FlexEchoReply));
227 228
  if(echo_reply_msg == NULL)
    goto error;
229
  protocol__flex_echo_reply__init(echo_reply_msg);
230 231 232 233 234

  Protocol__FlexHeader *header;
  if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_ECHO_REPLY, &header) != 0)
    goto error;

235 236
  echo_reply_msg->header = header;

237
  *msg = malloc(sizeof(Protocol__FlexranMessage));
238 239
  if(*msg == NULL)
    goto error;
240 241 242
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
243
  (*msg)->has_msg_dir = 1;
244 245 246 247 248 249 250 251 252 253
  (*msg)->echo_reply_msg = echo_reply_msg;
  return 0;

 error:
  if(header != NULL)
    free(header);
  if(echo_reply_msg != NULL)
    free(echo_reply_msg);
  if(*msg != NULL)
    free(*msg);
254
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
255 256 257 258
  return -1;
}


259
int flexran_agent_destroy_echo_reply(Protocol__FlexranMessage *msg) {
260
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG)
261 262 263 264 265 266 267 268
    goto error;
  
  free(msg->echo_reply_msg->header);
  free(msg->echo_reply_msg);
  free(msg);
  return 0;
  
 error:
269
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
270 271
  return -1;
}
272

273

274
int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
275
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG)
276 277 278
    goto error;
  free(msg->enb_config_reply_msg->header);
  int i, j;
279
  Protocol__FlexEnbConfigReply *reply = msg->enb_config_reply_msg;
280
  
281
  for(i = 0; i < reply->n_cell_config;i++) {
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
    free(reply->cell_config[i]->mbsfn_subframe_config_rfoffset);
    free(reply->cell_config[i]->mbsfn_subframe_config_rfperiod);
    free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc);
    if (reply->cell_config[i]->si_config != NULL) {
      for(j = 0; j < reply->cell_config[i]->si_config->n_si_message;j++){
	free(reply->cell_config[i]->si_config->si_message[j]);
      }
      free(reply->cell_config[i]->si_config->si_message);
      free(reply->cell_config[i]->si_config);
    }
    free(reply->cell_config[i]);
  }
  free(reply->cell_config);
  free(reply);
  free(msg);
  
  return 0;
 error:
300
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
301
  return -1;
302 303
}

304
int flexran_agent_destroy_ue_config_reply(Protocol__FlexranMessage *msg) {
305
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG)
306 307
    goto error;
  free(msg->ue_config_reply_msg->header);
308
  int i;
309
  Protocol__FlexUeConfigReply *reply = msg->ue_config_reply_msg;
310 311 312 313 314 315 316 317 318
  
  for(i = 0; i < reply->n_ue_config;i++){
    free(reply->ue_config[i]->capabilities);
    free(reply->ue_config[i]);
  }
  free(reply->ue_config);
  free(reply);
  free(msg);

319
  return 0;
320
 error:
321
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
322
  return -1;
323 324
}

325
int flexran_agent_destroy_lc_config_reply(Protocol__FlexranMessage *msg) {
326
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REPLY_MSG)
327 328 329 330 331 332 333 334 335 336 337 338 339 340
    goto error;

  int i, j;
  free(msg->lc_config_reply_msg->header);
  for (i = 0; i < msg->lc_config_reply_msg->n_lc_ue_config; i++) {
    for (j = 0; j < msg->lc_config_reply_msg->lc_ue_config[i]->n_lc_config; j++) {
      free(msg->lc_config_reply_msg->lc_ue_config[i]->lc_config[j]);
    }
    free(msg->lc_config_reply_msg->lc_ue_config[i]->lc_config);
    free(msg->lc_config_reply_msg->lc_ue_config[i]);
  }
  free(msg->lc_config_reply_msg->lc_ue_config);
  free(msg->lc_config_reply_msg);
  free(msg);
341
  return 0;
342
 error:
343
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
344
  return -1;
345 346
}

347
int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) {
348
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG)
349 350 351 352 353
    goto error;
  free(msg->ue_state_change_msg->header);
  //TODO: Free the contents of the UE config structure
  free(msg->ue_state_change_msg);
  free(msg);
354
  return 0;
355 356 357 358

 error:
  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
359 360
}

361
int flexran_agent_destroy_enb_config_request(Protocol__FlexranMessage *msg) {
362
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG)
363 364 365 366 367 368 369
    goto error;
  free(msg->enb_config_request_msg->header);
  free(msg->enb_config_request_msg);
  free(msg);
  return 0;
  
 error:
370
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
371
  return -1;
372 373
}

374
int flexran_agent_destroy_ue_config_request(Protocol__FlexranMessage *msg) {
375 376 377 378
  /* TODO: Deallocate memory for a dynamically allocated UE config message */
  return 0;
}

379
int flexran_agent_destroy_lc_config_request(Protocol__FlexranMessage *msg) {
380 381 382 383
  /* TODO: Deallocate memory for a dynamically allocated LC config message */
  return 0;
}

384
// call this function to start a nanosecond-resolution timer
385
struct timespec timer_start(void) {
386 387 388 389 390 391 392 393 394 395 396 397 398
    struct timespec start_time;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time);
    return start_time;
}

// call this function to end a timer, returning nanoseconds elapsed as a long
long timer_end(struct timespec start_time){
    struct timespec end_time;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time);
    long diffInNanos = end_time.tv_nsec - start_time.tv_nsec;
    return diffInNanos;
}

399
int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
400

401 402
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexControlDelegation *control_delegation_msg = input->control_delegation_msg;
403

404
  //  struct timespec vartime = timer_start();
405 406 407 408
  
  //Write the payload lib into a file in the cache and load the lib
  char lib_name[120];
  char target[512];
409
  snprintf(lib_name, sizeof(lib_name), "/%s.so", control_delegation_msg->name);
410 411 412 413 414 415 416 417
  strcpy(target, local_cache);
  strcat(target, lib_name);

  FILE *f;
  f = fopen(target, "wb");
  fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f);
  fclose(f);

418
  //  long time_elapsed_nanos = timer_end(vartime);
419 420 421 422 423
  *msg = NULL;
  return 0;

}

424
int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg) {
425
  /*TODO: Dealocate memory for a dynamically allocated control delegation message*/
426
  return 0;
427 428
}

429
int flexran_agent_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
430 431
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexAgentReconfiguration *agent_reconfiguration_msg = input->agent_reconfiguration_msg;
432 433 434 435 436 437 438

  apply_reconfiguration_policy(mod_id, agent_reconfiguration_msg->policy, strlen(agent_reconfiguration_msg->policy));

  *msg = NULL;
  return 0;
}

439
int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg) {
440
  /*TODO: Dealocate memory for a dynamically allocated agent reconfiguration message*/
441
  return 0;
442 443
}

444

445 446 447 448
/*
 * get generic info from RAN
 */

449
void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran){
450 451 452 453 454

  switch (ran){
  case RAN_LTE_OAI :
    enb[mod_id] =  (void *)&eNB_mac_inst[mod_id];
    enb_ue[mod_id] = (void *)&eNB_mac_inst[mod_id].UE_list;
455
    enb_rrc[mod_id] = (void *)&eNB_rrc_inst[mod_id];
456 457 458 459 460 461 462 463
    break;
  default :
    goto error;
  }

  return; 

 error:
464
  LOG_E(FLEXRAN_AGENT, "unknown RAN name %d\n", ran);
465 466
}

467
int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag){
468 469 470 471 472 473 474 475 476

  if (subframe_flag == 1){
    return ((eNB_MAC_INST *)enb[mod_id])->frame*10 + ((eNB_MAC_INST *)enb[mod_id])->subframe;
  }else {
    return ((eNB_MAC_INST *)enb[mod_id])->frame*10;
  }
   
}

477
unsigned int flexran_get_current_frame (mid_t mod_id) {
478

479
  //  #warning "SFN will not be in [0-1023] when oaisim is used"
480 481 482 483
  return ((eNB_MAC_INST *)enb[mod_id])->frame;
  
}

484 485
unsigned int flexran_get_current_system_frame_num(mid_t mod_id) {
  return (flexran_get_current_frame(mod_id) %1024);
486 487
}

488
unsigned int flexran_get_current_subframe (mid_t mod_id) {
489 490 491 492 493

  return ((eNB_MAC_INST *)enb[mod_id])->subframe;
  
}

494
uint16_t flexran_get_sfn_sf (mid_t mod_id) {
495
  
496 497 498 499
  frame_t frame;
  sub_frame_t subframe;
  uint16_t sfn_sf, frame_mask, sf_mask;
  
500 501
  frame = (frame_t) flexran_get_current_system_frame_num(mod_id);
  subframe = (sub_frame_t) flexran_get_current_subframe(mod_id);
502
  frame_mask = ((1<<12) - 1);
503
  sf_mask = ((1<<4) - 1);
504
  sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4);
505 506 507 508
  
  return sfn_sf;
}

509
uint16_t flexran_get_future_sfn_sf (mid_t mod_id, int ahead_of_time) {
510 511 512 513 514
  
  frame_t frame;
  sub_frame_t subframe;
  uint16_t sfn_sf, frame_mask, sf_mask;
  
515 516
  frame = (frame_t) flexran_get_current_system_frame_num(mod_id);
  subframe = (sub_frame_t) flexran_get_current_subframe(mod_id);
517 518 519

  subframe = ((subframe + ahead_of_time) % 10);
  
520
  if (subframe < flexran_get_current_subframe(mod_id)) {
521
    frame = (frame + 1) % 1024;
522
  }
523 524 525 526
  
  int additional_frames = ahead_of_time / 10;
  frame = (frame + additional_frames) % 1024;
  
527 528 529 530 531 532 533
  frame_mask = ((1<<12) - 1);
  sf_mask = ((1<<4) - 1);
  sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4);
  
  return sfn_sf;
}

534
int flexran_get_num_ues (mid_t mod_id){
535 536 537 538

  return  ((UE_list_t *)enb_ue[mod_id])->num_UEs;
}

539
int flexran_get_ue_crnti (mid_t mod_id, mid_t ue_id) {
540

541
  return  UE_RNTI(mod_id, ue_id);
542 543
}

544
int flexran_get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid) {
545 546 547 548

  return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].bsr_info[lcid];
}

549
int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id) {
550 551 552 553

  return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].phr_info;
}

554
int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) {
555 556 557 558 559
  LTE_eNB_UE_stats     *eNB_UE_stats     = NULL;
  eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, 0, UE_RNTI(mod_id, ue_id));
  return eNB_UE_stats->DL_cqi[0];

  //  return ((UE_list_t *)enb_ue[mod_id])->eNB_UE_stats[UE_PCCID(mod_id,ue_id)][ue_id].dl_cqi;
560
}
561 562

int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) {
563 564
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
  uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id);
565 566
  uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id);
  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,subframe,ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0);
567 568 569 570 571 572
  return rlc_status.bytes_in_buffer;
}

int flexran_get_hol_delay(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);
  uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id);
573 574
  uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id);
  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0);
575
  return rlc_status.head_sdu_creation_time;
576
}
577

578
short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id) {
579 580 581 582 583 584
  
  UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list;
  int rnti;

  rnti = flexran_get_ue_crnti(mod_id, ue_id);

585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
  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                                         
  switch (PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.N_RB_DL) {
  case 6:
    return eNB_UE_stats->timing_advance_update;
  case 15:
    return eNB_UE_stats->timing_advance_update/2;
  case 25:
    return eNB_UE_stats->timing_advance_update/4;
  case 50:
    return eNB_UE_stats->timing_advance_update/8;
  case 75:
    return eNB_UE_stats->timing_advance_update/12;
  case 100:
    if (PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.threequarter_fs == 0) {
      return eNB_UE_stats->timing_advance_update/16;
    } else {
      return eNB_UE_stats->timing_advance_update/12;
603
    }
604 605
  default:
    return 0;
606
  }
607 608 609 610 611 612
}

void flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id) {
  
  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];
613

614 615 616 617 618 619
  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);
620

621 622 623 624 625 626
    // 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      
  }
627
}
628

629 630 631
int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id,int CC_id) {
  
  UE_list_t			*UE_list      = &eNB_mac_inst[mod_id].UE_list;
632

633 634 635 636 637 638
  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
  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;
  }
639

640 641
  if (flexran_get_TA(mod_id, ue_id, CC_id) != 0) {
    return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA;
642 643 644
  } else {
    return 0;
  }
645

646
}
647

648
int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) {
649 650 651
	return ((UE_list_t *)enb_ue[mod_id])->numactiveCCs[ue_id];
}

652
int flexran_get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id) {
653
	LTE_eNB_UE_stats	*eNB_UE_stats = NULL;
654

655
	rnti_t			 rnti	      = flexran_get_ue_crnti(mod_id,ue_id);
656

657
	eNB_UE_stats			      = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti);
658 659 660 661 662
	
	if (eNB_UE_stats == NULL) {
	  return 0;
	}

663 664 665
	return eNB_UE_stats[CC_id].rank;
}

666
int flexran_get_tpc(mid_t mod_id, mid_t ue_id) {
667 668 669
	LTE_eNB_UE_stats	*eNB_UE_stats = NULL;
	int32_t			 normalized_rx_power, target_rx_power;
	int			 tpc	      = 1;
MKassem's avatar
MKassem committed
670

671 672
	int			 pCCid	      = UE_PCCID(mod_id,ue_id);
	rnti_t			 rnti	      = flexran_get_ue_crnti(mod_id,ue_id);
MKassem's avatar
MKassem committed
673

674
	eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, pCCid, rnti);
MKassem's avatar
MKassem committed
675 676 677

	target_rx_power = mac_xface->get_target_pusch_rx_power(mod_id,pCCid);

678 679 680 681 682 683 684 685
	if (eNB_UE_stats == NULL) {
	  normalized_rx_power = target_rx_power;
	} else if (eNB_UE_stats->UL_rssi != NULL) {
	  normalized_rx_power = eNB_UE_stats->UL_rssi[0];
	} else {
	  normalized_rx_power = target_rx_power;
	}

MKassem's avatar
MKassem committed
686
	if (normalized_rx_power>(target_rx_power+1)) {
687
		tpc = 0;	//-1
MKassem's avatar
MKassem committed
688
	} else if (normalized_rx_power<(target_rx_power-1)) {
689
		tpc = 2;	//+1
MKassem's avatar
MKassem committed
690
	} else {
691
		tpc = 1;	//0
MKassem's avatar
MKassem committed
692 693 694 695
	}
	return tpc;
}

696 697 698 699 700 701 702
int flexran_get_harq(const mid_t mod_id, 
		     const uint8_t CC_id, 
		     const mid_t ue_id, 
		     const int frame, 
		     const uint8_t subframe, 
		     uint8_t *id, 
		     uint8_t *round)	{ //flag_id_status = 0 then id, else status
MKassem's avatar
MKassem committed
703 704 705 706
	/*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];*/

707
  uint8_t harq_pid;
708
  uint8_t harq_round;
709
  
MKassem's avatar
MKassem committed
710

711
  uint16_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
MKassem's avatar
MKassem committed
712

713
  mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL);
MKassem's avatar
MKassem committed
714

715
  *id = harq_pid;
716 717 718 719 720 721
  *round = harq_round;
  /* if (round > 0) { */
  /*   *status = 1; */
  /* } else { */
  /*   *status = 0; */
  /* } */
722

723
  /* return 0; */
724
  return *round;
MKassem's avatar
MKassem committed
725 726
}

727
int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id) {
728 729 730 731 732 733 734 735 736 737 738 739 740 741
  LTE_eNB_UE_stats *eNB_UE_stats = NULL;
  uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
  
  eNB_UE_stats =  mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
  
  if (eNB_UE_stats == NULL) {
    return -1;
  }
  
  //	if(eNB_UE_stats->Po_PUCCH_update == 1) {
  return eNB_UE_stats->Po_PUCCH_dBm;
  //}
  //else
  //  return -1;
742 743
}

744
int flexran_get_p0_nominal_pucch(mid_t mod_id, int CC_id) {
745 746
  int32_t pucch_rx_received = mac_xface->get_target_pucch_rx_power(mod_id, CC_id);
  return pucch_rx_received;
747 748
}

749
int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id) {
750 751 752 753 754
  LTE_eNB_UE_stats *eNB_UE_stats = NULL;
  uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
  
  eNB_UE_stats =  mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
  return eNB_UE_stats->Po_PUCCH_update;
755 756 757
}

int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id) {
758 759 760 761 762 763 764
  LTE_eNB_UE_stats *eNB_UE_stats = NULL;
  uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
  
  eNB_UE_stats =  mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
  eNB_UE_stats->Po_PUCCH_update = 0;
  
  return 0;
765 766
}

767 768 769 770 771 772 773

/*
 * ************************************
 * Get Messages for eNB Configuration Reply
 * ************************************
 */

774
int flexran_get_hopping_offset(mid_t mod_id, int CC_id) {
775 776 777 778 779
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->pusch_config_common.pusch_HoppingOffset;
}
780

781
int flexran_get_hopping_mode(mid_t mod_id, int CC_id) {
782 783 784 785 786
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->pusch_config_common.hoppingMode;
}
787

788
int flexran_get_n_SB(mid_t mod_id, int CC_id) {
789 790 791 792 793
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->pusch_config_common.n_SB;
}
794

795
int flexran_get_enable64QAM(mid_t mod_id, int CC_id) {
796 797 798 799 800
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->pusch_config_common.enable64QAM;
}
801

802
int flexran_get_phich_duration(mid_t mod_id, int CC_id) {
803 804 805 806 807
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->phich_config_common.phich_duration;
}
808

809
int flexran_get_phich_resource(mid_t mod_id, int CC_id) {
810 811 812 813 814 815 816 817 818 819 820 821 822 823
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	if(frame_parms->phich_config_common.phich_resource == oneSixth)
		return 0;
	else if(frame_parms->phich_config_common.phich_resource == half)
		return 1;
	else if(frame_parms->phich_config_common.phich_resource == one)
		return 2;
	else if(frame_parms->phich_config_common.phich_resource == two)
		return 3;

	return -1;
}
824

825
int flexran_get_n1pucch_an(mid_t mod_id, int CC_id) {
826 827 828 829 830
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->pucch_config_common.n1PUCCH_AN;
}
831

832
int flexran_get_nRB_CQI(mid_t mod_id, int CC_id) {
833 834 835 836 837
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->pucch_config_common.nRB_CQI;
}
838

839
int flexran_get_deltaPUCCH_Shift(mid_t mod_id, int CC_id) {
840 841 842 843 844
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->pucch_config_common.deltaPUCCH_Shift;
}
845

846
int flexran_get_prach_ConfigIndex(mid_t mod_id, int CC_id) {
847 848 849 850 851
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
}
852

853
int flexran_get_prach_FreqOffset(mid_t mod_id, int CC_id) {
854 855 856 857 858
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset;
}
859

860
int flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id) {
861 862 863 864 865
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->maxHARQ_Msg3Tx;
}
866

867
int flexran_get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id) {
868 869 870 871 872
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->Ncp_UL;
}
873

874
int flexran_get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id) {
875 876 877 878 879
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->Ncp;
}
880

881
int flexran_get_cell_id(mid_t mod_id, int CC_id) {
882 883 884 885 886
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->Nid_cell;
}
887

888
int flexran_get_srs_BandwidthConfig(mid_t mod_id, int CC_id) {
889 890 891 892 893
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->soundingrs_ul_config_common.srs_BandwidthConfig;
}
894

895
int flexran_get_srs_SubframeConfig(mid_t mod_id, int CC_id) {
896 897 898 899 900
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->soundingrs_ul_config_common.srs_SubframeConfig;
}
901

902
int flexran_get_srs_MaxUpPts(mid_t mod_id, int CC_id) {
903 904 905 906 907
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->soundingrs_ul_config_common.srs_MaxUpPts;
}
908

909
int flexran_get_N_RB_DL(mid_t mod_id, int CC_id) {
910 911 912 913 914
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->N_RB_DL;
}
915

916
int flexran_get_N_RB_UL(mid_t mod_id, int CC_id) {
917 918 919 920 921
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->N_RB_UL;
}
922

923 924 925 926 927 928 929
int flexran_get_N_RBG(mid_t mod_id, int CC_id) {
  	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->N_RBG;
}

930
int flexran_get_subframe_assignment(mid_t mod_id, int CC_id) {
931 932 933 934 935
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->tdd_config;
}
936

937
int flexran_get_special_subframe_assignment(mid_t mod_id, int CC_id) {
938 939 940 941 942
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
	return frame_parms->tdd_config_S;
}
943

944
int flexran_get_ra_ResponseWindowSize(mid_t mod_id, int CC_id) {
945
  return enb_config_get()->properties[mod_id]->rach_raResponseWindowSize[CC_id];
946
}
947

948
int flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id) {
949
  return enb_config_get()->properties[mod_id]->rach_macContentionResolutionTimer[CC_id];
950
}
951

952
int flexran_get_duplex_mode(mid_t mod_id, int CC_id) {
953 954 955
	LTE_DL_FRAME_PARMS   *frame_parms;

	frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id);
956 957 958 959
	if(frame_parms->frame_type == TDD)
		return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD;
	else if (frame_parms->frame_type == FDD)
		return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD;
960 961 962

	return -1;
}
963

964
long flexran_get_si_window_length(mid_t mod_id, int CC_id) {
965 966
	return  ((eNB_RRC_INST *)enb_rrc[mod_id])->carrier[CC_id].sib1->si_WindowLength;
}
967

968
int flexran_get_sib1_length(mid_t mod_id, int CC_id) {
969 970
	return  ((eNB_RRC_INST *)enb_rrc[mod_id])->carrier[CC_id].sizeof_SIB1;
}
971

972
int flexran_get_num_pdcch_symb(mid_t mod_id, int CC_id) {
973 974 975
  /* TODO: This should return the number of PDCCH symbols initially used by the cell CC_id */
  return 0;
  //(PHY_vars_UE_g[mod_id][CC_id]->lte_ue_pdcch_vars[mod_id]->num_pdcch_symbols);
976 977
}

978 979


980
/*
981 982 983
 * ************************************
 * Get Messages for UE Configuration Reply
 * ************************************
984 985
 */

986

987
int flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) {
988 989 990 991 992 993 994 995 996 997 998 999 1000
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.mac_MainConfig != NULL) {
      return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated;
    } else {
      return -1;
    }
  } else {
    return -1;
  }
1001 1002
}

1003
int flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id) {
1004
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
1005
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
1006

1007 1008
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  if(ue_context_p != NULL) {
1009
    if(ue_context_p->ue_context.measGapConfig != NULL) {
1010 1011
      if(ue_context_p->ue_context.measGapConfig->present == MeasGapConfig_PR_setup) {
	if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) {
1012
	  return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1;
1013
	} else if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp1) {
1014
	  return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2;
1015
	} else {
1016
	  return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF;
1017
	}
1018 1019 1020 1021
      }
    }
  }
  return -1;
1022 1023
}

1024

1025
int flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) {
1026
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
1027
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.measGapConfig != NULL){
      if(ue_context_p->ue_context.measGapConfig->present == MeasGapConfig_PR_setup) {
	if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) {
	  return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0;
	} else if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp1) {
	  return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0;
	} 
      }
    }
  }
  return -1;
1043 1044
}

1045
int flexran_get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id) {
1046 1047 1048
	return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL;
}

1049
int flexran_get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id) {
1050 1051 1052
	return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL;
}

1053
int flexran_get_half_duplex(mid_t ue_id) {
1054
  // TODO
1055 1056 1057 1058 1059 1060 1061
	//int halfduplex = 0;
	//int bands_to_scan = ((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count;
	//for (int i =0; i < bands_to_scan; i++){
		//if(((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->halfDuplex > 0)
		//	halfduplex = 1;
	//}
	//return halfduplex;
1062
  return 0;
1063 1064
}

1065
int flexran_get_intra_sf_hopping(mid_t ue_id) {
1066 1067 1068
	//TODO:Get proper value
	//temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf);
	//return (0 & ( 1 << (31)));
1069
  return 0;
1070 1071
}

1072
int flexran_get_type2_sb_1(mid_t ue_id) {
1073 1074 1075 1076
	//TODO:Get proper value
	//uint8_t temp = 0;
	//temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf);
	//return (temp & ( 1 << (11)));
1077
  return 0;
1078 1079
}

1080
int flexran_get_ue_category(mid_t ue_id) {
1081 1082
	//TODO:Get proper value
	//return (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->ue_Category);
1083
  return 0;
1084 1085
}

1086
int flexran_get_res_alloc_type1(mid_t ue_id) {
1087 1088 1089 1090
	//TODO:Get proper value
	//uint8_t temp = 0;
	//temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf);
	//return (temp & ( 1 << (30)));
1091
  return 0;
1092 1093
}

1094
int flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) {
1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.physicalConfigDedicated != NULL){
      return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode;
    } else {
      return -1;
    }
  } else {
    return -1;
  }
1109 1110
}

1111
int flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) {
1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.mac_MainConfig != NULL){
      return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling;
    } else {
      return -1;
    }
  }
  else {
    return -1;
  }
1126 1127
}

1128
int flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) {
1129
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
1130
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
1131 1132 1133 1134 1135 1136 1137 1138
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.mac_MainConfig != NULL){
      return *ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx;
    }
  }
  return -1;
1139 1140
}

1141
int flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) {
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.physicalConfigDedicated != NULL){
      return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index;
    } else {
      return -1;
    } 
  } else {
    return -1;
  }
1155 1156
}

1157
int flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) {
1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.physicalConfigDedicated != NULL){
      return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index;
    } else {
      return -1;
    }
  } else {
    return -1;
  }
1171 1172
}

1173
int flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) {
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.physicalConfigDedicated != NULL){
      return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index;
    } else {
      return -1;
    }
  }
  else {
    return -1;
  }
1188 1189
}

1190
int flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) {
1191
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
1192
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
1193 1194 1195 1196 1197 1198 1199 1200 1201 1202
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.physicalConfigDedicated != NULL){
      if (ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic != NULL) {
	return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI;
      }
    }
  }
  return -1;
1203 1204
}

1205
int flexran_get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id) {
1206
	return (&eNB_rrc_inst[mod_id])->carrier[0].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission;
1207 1208
}

1209
int flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) {
1210
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
1211
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
1212 1213 1214 1215 1216 1217 1218 1219 1220
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.physicalConfigDedicated != NULL){
      return *ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic;
    }
  }
  return -1;
1221 1222
}

1223
int flexran_get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id) {
1224 1225
  // TODO: This needs fixing
  return -1;
1226

1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
  /* struct rrc_eNB_ue_context_s* ue_context_p = NULL; */
  /* uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); */
  
  /* ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); */
  
  /* if(ue_context_p != NULL) { */
  /*   if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ */
  /*     return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode; */
  /*   } else { */
  /*     return -1; */
  /*   } */
  /* } else { */
  /*   return -1; */
  /* } */
1241 1242
}

1243
int flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id) {
1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.physicalConfigDedicated != NULL){
      return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor;
    } else {
      return -1;
    }
  } else {
    return -1;
  }
1257 1258
}

1259
int flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) {
1260 1261
  //TODO: need to double check
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
1262
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
1263

1264 1265 1266 1267 1268 1269 1270
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.mac_MainConfig != NULL){
      if(ue_context_p->ue_context.mac_MainConfig->ext2 != NULL){
	long val = (*(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10));
	if (val > 0) {
	  return 1;
1271
	}
1272 1273 1274 1275
      }
    }
  }
  return -1;
1276 1277
}

1278
int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) {
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id);
  
  ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP);
  
  if(ue_context_p != NULL) {
    if(ue_context_p->ue_context.physicalConfigDedicated != NULL){
      if(ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup == AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop) {
	return 2;
      } else if(ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup == AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop) {
	return 1;
      } else {
	return 0;
      }
    } else {
      return -1;
    }
  } else {
    return -1;
  }
1299 1300
}

1301
int flexran_get_lcg(mid_t ue_id, mid_t lc_id) {
1302 1303 1304
  if (UE_mac_inst == NULL) {
    return -1;
  }
1305 1306