Files
openairinterface5g/openair2/ENB_APP/flexran_agent_common.c
T
Robert Schmidt 2623e3f298 Improve interface of FlexRAN RAN API: Return protobuf types
The functions of the RAN API should not return the types of OAI, but protobuf
types. Previously, they would return OAI types and the calling code "marshals"
this into Protobuf type. This commit changes the following functions and
modifies the calling code to directly store the protobuf type:
* flexran_get_hopping_mode()
* flexran_get_phich_resource()
* flexran_get_phich_duration()
* flexran_get_ul_cyclic_prefix_length()
* flexran_get_dl_cyclic_prefix_length()
* flexran_get_duplex_mode() usage
* flexran_get_enable64QAM()
2018-11-07 10:48:35 +01:00

1066 lines
36 KiB
C

/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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_common.c
* \brief common primitives for all agents
* \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein, shahab SHARIAT BAGHERI
* \date 2017
* \version 0.1
*/
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#include "flexran_agent_common.h"
#include "flexran_agent_common_internal.h"
#include "flexran_agent_extern.h"
#include "flexran_agent_net_comm.h"
#include "flexran_agent_ran_api.h"
//#include "PHY/extern.h"
#include "common/utils/LOG/log.h"
//#include "SCHED/defs.h"
#include "RRC/LTE/rrc_extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "rrc_eNB_UE_context.h"
/*
* message primitives
*/
int flexran_agent_serialize_message(Protocol__FlexranMessage *msg, void **buf, int *size) {
*size = protocol__flexran_message__get_packed_size(msg);
*buf = malloc(*size);
if (buf == NULL)
goto error;
protocol__flexran_message__pack(msg, *buf);
return 0;
error:
LOG_E(FLEXRAN_AGENT, "an error occured\n"); // change the com
return -1;
}
/* We assume that the buffer size is equal to the message size.
Should be chekced durint Tx/Rx */
int flexran_agent_deserialize_message(void *data, int size, Protocol__FlexranMessage **msg) {
*msg = protocol__flexran_message__unpack(NULL, size, data);
if (*msg == NULL)
goto error;
return 0;
error:
//LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_create_header(xid_t xid, Protocol__FlexType type, Protocol__FlexHeader **header) {
*header = malloc(sizeof(Protocol__FlexHeader));
if(*header == NULL)
goto error;
protocol__flex_header__init(*header);
(*header)->version = FLEXRAN_VERSION;
(*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:
LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_hello(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
Protocol__FlexHeader *header = NULL;
/*TODO: Need to set random xid or xid from received hello message*/
xid_t xid = 1;
Protocol__FlexHello *hello_msg;
hello_msg = malloc(sizeof(Protocol__FlexHello));
if(hello_msg == NULL)
goto error;
protocol__flex_hello__init(hello_msg);
if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_HELLO, &header) != 0)
goto error;
hello_msg->header = header;
hello_msg->bs_id = flexran_get_bs_id(mod_id);
hello_msg->has_bs_id = 1;
hello_msg->n_capabilities = flexran_get_capabilities(mod_id, &hello_msg->capabilities);
*msg = malloc(sizeof(Protocol__FlexranMessage));
if(*msg == NULL)
goto error;
protocol__flexran_message__init(*msg);
(*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG;
(*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
(*msg)->has_msg_dir = 1;
(*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);
LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_destroy_hello(Protocol__FlexranMessage *msg) {
if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG)
goto error;
free(msg->hello_msg->header);
free(msg->hello_msg->capabilities);
free(msg->hello_msg);
free(msg);
return 0;
error:
LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_echo_request(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg) {
Protocol__FlexHeader *header = NULL;
/*TODO: Need to set a random xid*/
xid_t xid = 1;
Protocol__FlexEchoRequest *echo_request_msg = NULL;
echo_request_msg = malloc(sizeof(Protocol__FlexEchoRequest));
if(echo_request_msg == NULL)
goto error;
protocol__flex_echo_request__init(echo_request_msg);
if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_ECHO_REQUEST, &header) != 0)
goto error;
echo_request_msg->header = header;
*msg = malloc(sizeof(Protocol__FlexranMessage));
if(*msg == NULL)
goto error;
protocol__flexran_message__init(*msg);
(*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG;
(*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
(*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;
}
int flexran_agent_destroy_echo_request(Protocol__FlexranMessage *msg) {
if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG)
goto error;
free(msg->echo_request_msg->header);
free(msg->echo_request_msg);
free(msg);
return 0;
error:
LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_echo_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
xid_t xid;
Protocol__FlexHeader *header = NULL;
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
Protocol__FlexEchoRequest *echo_req = input->echo_request_msg;
xid = (echo_req->header)->xid;
Protocol__FlexEchoReply *echo_reply_msg = NULL;
echo_reply_msg = malloc(sizeof(Protocol__FlexEchoReply));
if(echo_reply_msg == NULL)
goto error;
protocol__flex_echo_reply__init(echo_reply_msg);
if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_ECHO_REPLY, &header) != 0)
goto error;
echo_reply_msg->header = header;
*msg = malloc(sizeof(Protocol__FlexranMessage));
if(*msg == NULL)
goto error;
protocol__flexran_message__init(*msg);
(*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG;
(*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
(*msg)->has_msg_dir = 1;
(*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);
LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_destroy_echo_reply(Protocol__FlexranMessage *msg) {
if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG)
goto error;
free(msg->echo_reply_msg->header);
free(msg->echo_reply_msg);
free(msg);
return 0;
error:
LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG)
goto error;
free(msg->enb_config_reply_msg->header);
int i, j;
Protocol__FlexEnbConfigReply *reply = msg->enb_config_reply_msg;
for(i = 0; i < reply->n_cell_config;i++) {
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:
//LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_destroy_ue_config_reply(Protocol__FlexranMessage *msg) {
if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG)
goto error;
free(msg->ue_config_reply_msg->header);
int i;
Protocol__FlexUeConfigReply *reply = msg->ue_config_reply_msg;
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);
return 0;
error:
//LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_destroy_lc_config_reply(Protocol__FlexranMessage *msg) {
if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REPLY_MSG)
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);
return 0;
error:
//LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_destroy_enb_config_request(Protocol__FlexranMessage *msg) {
if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG)
goto error;
free(msg->enb_config_request_msg->header);
free(msg->enb_config_request_msg);
free(msg);
return 0;
error:
//LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_destroy_ue_config_request(Protocol__FlexranMessage *msg) {
/* TODO: Deallocate memory for a dynamically allocated UE config message */
return 0;
}
int flexran_agent_destroy_lc_config_request(Protocol__FlexranMessage *msg) {
/* TODO: Deallocate memory for a dynamically allocated LC config message */
return 0;
}
// call this function to start a nanosecond-resolution timer
struct timespec timer_start(void) {
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;
}
int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
Protocol__FlexControlDelegation *control_delegation_msg = input->control_delegation_msg;
// struct timespec vartime = timer_start();
//Write the payload lib into a file in the cache and load the lib
char lib_name[120];
char target[512];
snprintf(lib_name, sizeof(lib_name), "/%s.so", control_delegation_msg->name);
strcpy(target, RC.flexran[mod_id]->cache_name);
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);
// long time_elapsed_nanos = timer_end(vartime);
*msg = NULL;
return 0;
}
int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg) {
/*TODO: Dealocate memory for a dynamically allocated control delegation message*/
return 0;
}
int flexran_agent_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
Protocol__FlexAgentReconfiguration *agent_reconfiguration_msg = input->agent_reconfiguration_msg;
apply_reconfiguration_policy(mod_id, agent_reconfiguration_msg->policy, strlen(agent_reconfiguration_msg->policy));
*msg = NULL;
return 0;
}
int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg) {
/*TODO: Dealocate memory for a dynamically allocated agent reconfiguration message*/
return 0;
}
int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
xid_t xid;
Protocol__FlexHeader *header = NULL;
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
Protocol__FlexLcConfigRequest *lc_config_request_msg = input->lc_config_request_msg;
xid = (lc_config_request_msg->header)->xid;
int i, j;
Protocol__FlexLcConfigReply *lc_config_reply_msg;
lc_config_reply_msg = malloc(sizeof(Protocol__FlexLcConfigReply));
if(lc_config_reply_msg == NULL)
goto error;
protocol__flex_lc_config_reply__init(lc_config_reply_msg);
if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_LC_CONFIG_REPLY, &header) != 0)
goto error;
lc_config_reply_msg->header = header;
lc_config_reply_msg->n_lc_ue_config = flexran_get_num_ues(mod_id);
Protocol__FlexLcUeConfig **lc_ue_config;
if (lc_config_reply_msg->n_lc_ue_config > 0) {
lc_ue_config = malloc(sizeof(Protocol__FlexLcUeConfig *) * lc_config_reply_msg->n_lc_ue_config);
if (lc_ue_config == NULL) {
goto error;
}
// Fill the config for each UE
for (i = 0; i < lc_config_reply_msg->n_lc_ue_config; i++) {
lc_ue_config[i] = malloc(sizeof(Protocol__FlexLcUeConfig));
protocol__flex_lc_ue_config__init(lc_ue_config[i]);
lc_ue_config[i]->has_rnti = 1;
lc_ue_config[i]->rnti = flexran_get_ue_crnti(mod_id,i);
//TODO: Set the number of LC configurations that will be reported for this UE
//Set this according to the current state of the UE. This is only a temporary fix
int status = 0;
status = mac_eNB_get_rrc_status(mod_id, flexran_get_ue_crnti(mod_id, i));
/* TODO needs to be revised and appropriate API to be implemented */
if (status < RRC_CONNECTED) {
lc_ue_config[i]->n_lc_config = 0;
} else if (status == RRC_CONNECTED) {
lc_ue_config[i]->n_lc_config = 1;
} else {
lc_ue_config[i]->n_lc_config = 3;
}
Protocol__FlexLcConfig **lc_config;
if (lc_ue_config[i]->n_lc_config > 0) {
lc_config = malloc(sizeof(Protocol__FlexLcConfig *) * lc_ue_config[i]->n_lc_config);
if (lc_config == NULL) {
goto error;
}
for (j = 0; j < lc_ue_config[i]->n_lc_config; j++) {
lc_config[j] = malloc(sizeof(Protocol__FlexLcConfig));
protocol__flex_lc_config__init(lc_config[j]);
lc_config[j]->has_lcid = 1;
lc_config[j]->lcid = j+1;
int lcg = flexran_get_lcg(mod_id, i, j+1);
if (lcg >= 0 && lcg <= 3) {
lc_config[j]->has_lcg = 1;
lc_config[j]->lcg = flexran_get_lcg(mod_id, i,j+1);
}
lc_config[j]->has_direction = 1;
lc_config[j]->direction = flexran_get_direction(i,j+1);
//TODO: Bearer type. One of FLQBT_* values. Currently only default bearer supported
lc_config[j]->has_qos_bearer_type = 1;
lc_config[j]->qos_bearer_type = PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_NON_GBR;
//TODO: Set the QCI defined in TS 23.203, coded as defined in TS 36.413
// One less than the actual QCI value. Needs to be generalized
lc_config[j]->has_qci = 1;
lc_config[j]->qci = 1;
if (lc_config[j]->direction == PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_GBR) {
/* TODO all of the need to be taken from API */
//TODO: Set the max bitrate (UL)
lc_config[j]->has_e_rab_max_bitrate_ul = 0;
lc_config[j]->e_rab_max_bitrate_ul = 0;
//TODO: Set the max bitrate (DL)
lc_config[j]->has_e_rab_max_bitrate_dl = 0;
lc_config[j]->e_rab_max_bitrate_dl = 0;
//TODO: Set the guaranteed bitrate (UL)
lc_config[j]->has_e_rab_guaranteed_bitrate_ul = 0;
lc_config[j]->e_rab_guaranteed_bitrate_ul = 0;
//TODO: Set the guaranteed bitrate (DL)
lc_config[j]->has_e_rab_guaranteed_bitrate_dl = 0;
lc_config[j]->e_rab_guaranteed_bitrate_dl = 0;
}
}
lc_ue_config[i]->lc_config = lc_config;
}
} // end for UE
lc_config_reply_msg->lc_ue_config = lc_ue_config;
} // lc_config_reply_msg->n_lc_ue_config > 0
*msg = malloc(sizeof(Protocol__FlexranMessage));
if (*msg == NULL)
goto error;
protocol__flexran_message__init(*msg);
(*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REPLY_MSG;
(*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
(*msg)->lc_config_reply_msg = lc_config_reply_msg;
return 0;
error:
// TODO: Need to make proper error handling
if (header != NULL)
free(header);
if (lc_config_reply_msg != NULL)
free(lc_config_reply_msg);
if(*msg != NULL)
free(*msg);
//LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
/*
* ************************************
* UE Configuration Reply
* ************************************
*/
int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
xid_t xid;
Protocol__FlexHeader *header = NULL;
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
Protocol__FlexUeConfigRequest *ue_config_request_msg = input->ue_config_request_msg;
xid = (ue_config_request_msg->header)->xid;
int i;
Protocol__FlexUeConfigReply *ue_config_reply_msg;
ue_config_reply_msg = malloc(sizeof(Protocol__FlexUeConfigReply));
if(ue_config_reply_msg == NULL)
goto error;
protocol__flex_ue_config_reply__init(ue_config_reply_msg);
if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_UE_CONFIG_REPLY, &header) != 0)
goto error;
ue_config_reply_msg->header = header;
ue_config_reply_msg->n_ue_config = flexran_get_num_ues(mod_id);
Protocol__FlexUeConfig **ue_config;
if (ue_config_reply_msg->n_ue_config > 0) {
ue_config = malloc(sizeof(Protocol__FlexUeConfig *) * ue_config_reply_msg->n_ue_config);
if (ue_config == NULL) {
goto error;
}
for (i = 0; i < ue_config_reply_msg->n_ue_config; i++) {
ue_config[i] = malloc(sizeof(Protocol__FlexUeConfig));
protocol__flex_ue_config__init(ue_config[i]);
ue_config[i]->rnti = flexran_get_ue_crnti(mod_id,i);
ue_config[i]->has_rnti = 1;
ue_config[i]->imsi = flexran_get_ue_imsi(mod_id, i);
ue_config[i]->has_imsi = 1;
//TODO: Set the DRX configuration (optional)
//Not supported for now, so we do not set it
if (flexran_get_time_alignment_timer(mod_id,i) != -1) {
ue_config[i]->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i);
ue_config[i]->has_time_alignment_timer = 1;
}
if (flexran_get_meas_gap_config(mod_id,i) != -1) {
ue_config[i]->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i);
ue_config[i]->has_meas_gap_config_pattern = 1;
}
if (ue_config[i]->has_meas_gap_config_pattern == 1 &&
ue_config[i]->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) {
ue_config[i]->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i);
ue_config[i]->has_meas_gap_config_sf_offset = 1;
}
//TODO: Set the SPS configuration (Optional)
//Not supported for noe, so we do not set it
//TODO: Set the SR configuration (Optional)
//We do not set it for now
//TODO: Set the CQI configuration (Optional)
//We do not set it for now
if (flexran_get_ue_transmission_mode(mod_id,i) != -1) {
ue_config[i]->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i);
ue_config[i]->has_transmission_mode = 1;
}
ue_config[i]->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i);
ue_config[i]->has_ue_aggregated_max_bitrate_ul = 1;
ue_config[i]->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i);
ue_config[i]->has_ue_aggregated_max_bitrate_dl = 1;
Protocol__FlexUeCapabilities *capabilities;
capabilities = malloc(sizeof(Protocol__FlexUeCapabilities));
protocol__flex_ue_capabilities__init(capabilities);
capabilities->has_half_duplex = 1;
capabilities->half_duplex = flexran_get_half_duplex(mod_id, i);
capabilities->has_intra_sf_hopping = 1;
capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, i);
capabilities->has_type2_sb_1 = 1;
capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, i);
capabilities->has_ue_category = 1;
capabilities->ue_category = flexran_get_ue_category(mod_id, i);
capabilities->has_res_alloc_type1 = 1;
capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, i);
//Set the capabilites to the message
ue_config[i]->capabilities = capabilities;
if (flexran_get_ue_transmission_antenna(mod_id,i) != -1) {
ue_config[i]->has_ue_transmission_antenna = 1;
ue_config[i]->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i);
}
if (flexran_get_tti_bundling(mod_id,i) != -1) {
ue_config[i]->has_tti_bundling = 1;
ue_config[i]->tti_bundling = flexran_get_tti_bundling(mod_id,i);
}
if (flexran_get_maxHARQ_TX(mod_id,i) != -1) {
ue_config[i]->has_max_harq_tx = 1;
ue_config[i]->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i);
}
if (flexran_get_beta_offset_ack_index(mod_id,i) != -1) {
ue_config[i]->has_beta_offset_ack_index = 1;
ue_config[i]->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i);
}
if (flexran_get_beta_offset_ri_index(mod_id,i) != -1) {
ue_config[i]->has_beta_offset_ri_index = 1;
ue_config[i]->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i);
}
if (flexran_get_beta_offset_cqi_index(mod_id,i) != -1) {
ue_config[i]->has_beta_offset_cqi_index = 1;
ue_config[i]->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i);
}
/* assume primary carrier */
if (flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0) != -1) {
ue_config[i]->has_ack_nack_simultaneous_trans = 1;
ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0);
}
if (flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) {
ue_config[i]->has_simultaneous_ack_nack_cqi = 1;
ue_config[i]->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i);
}
if (flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) {
ue_config[i]->has_aperiodic_cqi_rep_mode = 1;
int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i);
if (mode > 4) {
ue_config[i]->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE;
} else {
ue_config[i]->aperiodic_cqi_rep_mode = mode;
}
}
if (flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) {
ue_config[i]->has_tdd_ack_nack_feedback = 1;
ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i);
}
if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) {
ue_config[i]->has_ack_nack_repetition_factor = 1;
ue_config[i]->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i);
}
if (flexran_get_extended_bsr_size(mod_id, i) != -1) {
ue_config[i]->has_extended_bsr_size = 1;
ue_config[i]->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i);
}
//TODO: Set carrier aggregation support (boolean)
ue_config[i]->has_ca_support = 0;
ue_config[i]->ca_support = 0;
ue_config[i]->has_pcell_carrier_index = 1;
ue_config[i]->pcell_carrier_index = UE_PCCID(mod_id, i);
if(ue_config[i]->has_ca_support){
//TODO: Set cross carrier scheduling support (boolean)
ue_config[i]->has_cross_carrier_sched_support = 0;
ue_config[i]->cross_carrier_sched_support = 0;
//TODO: Set secondary cells configuration
// We do not set it for now. No carrier aggregation support
//TODO: Set deactivation timer for secondary cell
ue_config[i]->has_scell_deactivation_timer = 0;
ue_config[i]->scell_deactivation_timer = 0;
}
}
ue_config_reply_msg->ue_config = ue_config;
}
*msg = malloc(sizeof(Protocol__FlexranMessage));
if (*msg == NULL)
goto error;
protocol__flexran_message__init(*msg);
(*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG;
(*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
(*msg)->ue_config_reply_msg = ue_config_reply_msg;
return 0;
error:
// TODO: Need to make proper error handling
if (header != NULL)
free(header);
if (ue_config_reply_msg != NULL)
free(ue_config_reply_msg);
if(*msg != NULL)
free(*msg);
//LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
/*
* ************************************
* eNB Configuration Request and Reply
* ************************************
*/
int flexran_agent_enb_config_request(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg) {
Protocol__FlexHeader *header = NULL;
xid_t xid = 1;
Protocol__FlexEnbConfigRequest *enb_config_request_msg;
enb_config_request_msg = malloc(sizeof(Protocol__FlexEnbConfigRequest));
if(enb_config_request_msg == NULL)
goto error;
protocol__flex_enb_config_request__init(enb_config_request_msg);
if(flexran_create_header(xid,PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REQUEST, &header) != 0)
goto error;
enb_config_request_msg->header = header;
*msg = malloc(sizeof(Protocol__FlexranMessage));
if(*msg == NULL)
goto error;
protocol__flexran_message__init(*msg);
(*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG;
(*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
(*msg)->enb_config_request_msg = enb_config_request_msg;
return 0;
error:
// TODO: Need to make proper error handling
if (header != NULL)
free(header);
if (enb_config_request_msg != NULL)
free(enb_config_request_msg);
if(*msg != NULL)
free(*msg);
//LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
xid_t xid;
Protocol__FlexHeader *header = NULL;
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
Protocol__FlexEnbConfigRequest *enb_config_req_msg = input->enb_config_request_msg;
xid = (enb_config_req_msg->header)->xid;
int i, j;
Protocol__FlexEnbConfigReply *enb_config_reply_msg;
enb_config_reply_msg = malloc(sizeof(Protocol__FlexEnbConfigReply));
if(enb_config_reply_msg == NULL)
goto error;
protocol__flex_enb_config_reply__init(enb_config_reply_msg);
if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REPLY, &header) != 0)
goto error;
enb_config_reply_msg->header = header;
enb_config_reply_msg->n_cell_config = MAX_NUM_CCs;
Protocol__FlexCellConfig **cell_conf;
if(enb_config_reply_msg->n_cell_config > 0){
cell_conf = malloc(sizeof(Protocol__FlexCellConfig *) * enb_config_reply_msg->n_cell_config);
if(cell_conf == NULL)
goto error;
for(i = 0; i < enb_config_reply_msg->n_cell_config; i++){
cell_conf[i] = malloc(sizeof(Protocol__FlexCellConfig));
protocol__flex_cell_config__init(cell_conf[i]);
cell_conf[i]->phy_cell_id = 1;
cell_conf[i]->has_phy_cell_id = flexran_get_cell_id(mod_id,i);
cell_conf[i]->cell_id = i;
cell_conf[i]->has_cell_id = 1;
cell_conf[i]->pusch_hopping_offset = flexran_get_hopping_offset(mod_id,i);
cell_conf[i]->has_pusch_hopping_offset = 1;
cell_conf[i]->hopping_mode = flexran_get_hopping_mode(mod_id,i);
cell_conf[i]->has_hopping_mode = 1;
cell_conf[i]->n_sb = flexran_get_n_SB(mod_id,i);
cell_conf[i]->has_n_sb = 1;
cell_conf[i]->phich_resource = flexran_get_phich_resource(mod_id,i);
cell_conf[i]->has_phich_resource = 1;
cell_conf[i]->phich_duration = flexran_get_phich_duration(mod_id,i);
cell_conf[i]->has_phich_duration = 1;
cell_conf[i]->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(mod_id,i);
cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 1;
Protocol__FlexSiConfig *si_config;
si_config = malloc(sizeof(Protocol__FlexSiConfig));
if(si_config == NULL)
goto error;
protocol__flex_si_config__init(si_config);
si_config->sfn = flexran_get_current_system_frame_num(mod_id);
si_config->has_sfn = 1;
si_config->sib1_length = flexran_get_sib1_length(mod_id,i);
si_config->has_sib1_length = 1;
si_config->si_window_length = (uint32_t) flexran_get_si_window_length(mod_id, i);
si_config->has_si_window_length = 1;
si_config->n_si_message = 0;
/* Protocol__FlexSiMessage **si_message; */
/* si_message = malloc(sizeof(Protocol__FlexSiMessage *) * si_config->n_si_message); */
/* if(si_message == NULL) */
/* goto error; */
/* for(j = 0; j < si_config->n_si_message; j++){ */
/* si_message[j] = malloc(sizeof(Protocol__FlexSiMessage)); */
/* if(si_message[j] == NULL) */
/* goto error; */
/* protocol__flex_si_message__init(si_message[j]); */
/* //TODO: Fill in with actual value, Periodicity of SI msg in radio frames */
/* si_message[j]->periodicity = 1; //SIPeriod */
/* si_message[j]->has_periodicity = 1; */
/* //TODO: Fill in with actual value, rhe length of the SI message in bytes */
/* si_message[j]->length = 10; */
/* si_message[j]->has_length = 1; */
/* } */
/* if(si_config->n_si_message > 0){ */
/* si_config->si_message = si_message; */
/* } */
cell_conf[i]->si_config = si_config;
cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(mod_id,i);
cell_conf[i]->has_dl_bandwidth = 1;
cell_conf[i]->ul_bandwidth = flexran_get_N_RB_UL(mod_id,i);
cell_conf[i]->has_ul_bandwidth = 1;
cell_conf[i]->ul_cyclic_prefix_length = flexran_get_ul_cyclic_prefix_length(mod_id, i);
cell_conf[i]->has_ul_cyclic_prefix_length = 1;
cell_conf[i]->dl_cyclic_prefix_length = flexran_get_dl_cyclic_prefix_length(mod_id,i);
cell_conf[i]->has_dl_cyclic_prefix_length = 1;
cell_conf[i]->antenna_ports_count = flexran_get_antenna_ports(mod_id, i);
cell_conf[i]->has_antenna_ports_count = 1;
cell_conf[i]->duplex_mode = flexran_get_duplex_mode(mod_id,i);
cell_conf[i]->has_duplex_mode = 1;
cell_conf[i]->subframe_assignment = flexran_get_subframe_assignment(mod_id, i);
cell_conf[i]->has_subframe_assignment = 1;
cell_conf[i]->special_subframe_patterns = flexran_get_special_subframe_assignment(mod_id,i);
cell_conf[i]->has_special_subframe_patterns = 1;
//TODO: Fill in with actual value, The MBSFN radio frame period
cell_conf[i]->n_mbsfn_subframe_config_rfperiod = 0;
uint32_t *elem_rfperiod;
elem_rfperiod = (uint32_t *) malloc(sizeof(uint32_t) *cell_conf[i]->n_mbsfn_subframe_config_rfperiod);
if(elem_rfperiod == NULL)
goto error;
for(j = 0; j < cell_conf[i]->n_mbsfn_subframe_config_rfperiod; j++){
elem_rfperiod[j] = 1;
}
cell_conf[i]->mbsfn_subframe_config_rfperiod = elem_rfperiod;
//TODO: Fill in with actual value, The MBSFN radio frame offset
cell_conf[i]->n_mbsfn_subframe_config_rfoffset = 0;
uint32_t *elem_rfoffset;
elem_rfoffset = (uint32_t *) malloc(sizeof(uint32_t) *cell_conf[i]->n_mbsfn_subframe_config_rfoffset);
if(elem_rfoffset == NULL)
goto error;
for(j = 0; j < cell_conf[i]->n_mbsfn_subframe_config_rfoffset; j++){
elem_rfoffset[j] = 1;
}
cell_conf[i]->mbsfn_subframe_config_rfoffset = elem_rfoffset;
//TODO: Fill in with actual value, Bitmap indicating the MBSFN subframes
cell_conf[i]->n_mbsfn_subframe_config_sfalloc = 0;
uint32_t *elem_sfalloc;
elem_sfalloc = (uint32_t *) malloc(sizeof(uint32_t) *cell_conf[i]->n_mbsfn_subframe_config_sfalloc);
if(elem_sfalloc == NULL)
goto error;
for(j = 0; j < cell_conf[i]->n_mbsfn_subframe_config_sfalloc; j++){
elem_sfalloc[j] = 1;
}
cell_conf[i]->mbsfn_subframe_config_sfalloc = elem_sfalloc;
cell_conf[i]->prach_config_index = flexran_get_prach_ConfigIndex(mod_id,i);
cell_conf[i]->has_prach_config_index = 1;
cell_conf[i]->prach_freq_offset = flexran_get_prach_FreqOffset(mod_id,i);
cell_conf[i]->has_prach_freq_offset = 1;
cell_conf[i]->ra_response_window_size = flexran_get_ra_ResponseWindowSize(mod_id,i);
cell_conf[i]->has_ra_response_window_size = 1;
cell_conf[i]->mac_contention_resolution_timer = flexran_get_mac_ContentionResolutionTimer(mod_id,i);
cell_conf[i]->has_mac_contention_resolution_timer = 1;
cell_conf[i]->max_harq_msg3tx = flexran_get_maxHARQ_Msg3Tx(mod_id,i);
cell_conf[i]->has_max_harq_msg3tx = 1;
cell_conf[i]->n1pucch_an = flexran_get_n1pucch_an(mod_id,i);
cell_conf[i]->has_n1pucch_an = 1;
cell_conf[i]->deltapucch_shift = flexran_get_deltaPUCCH_Shift(mod_id,i);
cell_conf[i]->has_deltapucch_shift = 1;
cell_conf[i]->nrb_cqi = flexran_get_nRB_CQI(mod_id,i);
cell_conf[i]->has_nrb_cqi = 1;
cell_conf[i]->srs_subframe_config = flexran_get_srs_SubframeConfig(mod_id,i);
cell_conf[i]->has_srs_subframe_config = 1;
cell_conf[i]->srs_bw_config = flexran_get_srs_BandwidthConfig(mod_id,i);
cell_conf[i]->has_srs_bw_config = 1;
cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(mod_id,i);
cell_conf[i]->has_srs_mac_up_pts = 1;
cell_conf[i]->dl_freq = flexran_agent_get_operating_dl_freq (mod_id,i);
cell_conf[i]->has_dl_freq = 1;
cell_conf[i]->ul_freq = flexran_agent_get_operating_ul_freq (mod_id, i);
cell_conf[i]->has_ul_freq = 1;
cell_conf[i]->eutra_band = flexran_agent_get_operating_eutra_band (mod_id,i);
cell_conf[i]->has_eutra_band = 1;
cell_conf[i]->dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(mod_id, i);
cell_conf[i]->has_dl_pdsch_power = 1;
cell_conf[i]->ul_pusch_power = flexran_agent_get_operating_pusch_p0 (mod_id,i);
cell_conf[i]->has_ul_pusch_power = 1;
cell_conf[i]->enable_64qam = flexran_get_enable64QAM(mod_id,i);
cell_conf[i]->has_enable_64qam = 1;
cell_conf[i]->carrier_index = i;
cell_conf[i]->has_carrier_index = 1;
}
enb_config_reply_msg->cell_config=cell_conf;
}
*msg = malloc(sizeof(Protocol__FlexranMessage));
if(*msg == NULL)
goto error;
protocol__flexran_message__init(*msg);
(*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG;
(*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
(*msg)->enb_config_reply_msg = enb_config_reply_msg;
return 0;
error:
// TODO: Need to make proper error handling
if (header != NULL)
free(header);
if (enb_config_reply_msg != NULL)
free(enb_config_reply_msg);
if(*msg != NULL)
free(*msg);
//LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
protocol_ctxt_t ctxt;
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
Protocol__FlexRrcTriggering *triggering = input->rrc_triggering;
agent_reconf_rrc *reconf_param = malloc(sizeof(agent_reconf_rrc));
reconf_param->trigger_policy = triggering->rrc_trigger;
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[mod_id]->rrc_ue_head)){
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id);
flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, ue_context_p, 0, reconf_param);
}
*msg = NULL;
return 0;
}
int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg){
// TODO
return 0;
}