Merge branch 'feature-68-enb-agent' into feature-merge-f68

Try to merge feature-68-enb-agent into develop
develop should be fast-forwarded later to this branch to complete the merge
This code does not compile yet. Among other things:
- the scheduler structure needs to be reworked for FlexRAN
- the config is structured differently. The files enb_config.{c,h} from develop
  have been copied in here, the files with merge annotations are in
  enb_config.{c,h}.before_merge
- the restart needs to be restructured, since the PHY vars data structure lives
  in RC now
This commit is contained in:
Robert Schmidt
2018-01-24 11:47:28 +01:00
69 changed files with 9000 additions and 3990 deletions
+595 -7
View File
@@ -21,14 +21,18 @@
/*! \file flexran_agent_handler.c
* \brief FlexRAN agent tx and rx message handler
* \author Xenofon Foukas and Navid Nikaein
* \date 2016
* \author Xenofon Foukas and Navid Nikaein and shahab SHARIAT BAGHERI
* \date 2017
* \version 0.1
*/
#include "flexran_agent_defs.h"
#include "flexran_agent_common.h"
#include "flexran_agent_mac.h"
#include "flexran_agent_rrc.h"
#include "flexran_agent_pdcp.h"
#include "flexran_agent_timer.h"
#include "flexran_agent_ran_api.h"
#include "log.h"
#include "assertions.h"
@@ -37,7 +41,7 @@ flexran_agent_message_decoded_callback agent_messages_callback[][3] = {
{flexran_agent_hello, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG*/
{flexran_agent_echo_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG*/
{0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG*/ //Must add handler when receiving echo reply
{flexran_agent_mac_handle_stats, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG*/
{flexran_agent_handle_stats, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG*/
{0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG*/
{0, 0, 0}, /*PROTOCOK__FLEXRAN_MESSAGE__MSG_SF_TRIGGER_MSG*/
{0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_SR_INFO_MSG*/
@@ -51,13 +55,14 @@ flexran_agent_message_decoded_callback agent_messages_callback[][3] = {
{0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG*/
{flexran_agent_control_delegation, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_CONTROL_DELEGATION_MSG*/
{flexran_agent_reconfiguration, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_AGENT_RECONFIGURATION_MSG*/
{flexran_agent_rrc_measurement, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_RRC_TRIGGERING_MSG*/
};
flexran_agent_message_destruction_callback message_destruction_callback[] = {
flexran_agent_destroy_hello,
flexran_agent_destroy_echo_request,
flexran_agent_destroy_echo_reply,
flexran_agent_mac_destroy_stats_request,
flexran_agent_destroy_stats_request,
flexran_agent_mac_destroy_stats_reply,
flexran_agent_mac_destroy_sf_trigger,
flexran_agent_mac_destroy_sr_info,
@@ -93,7 +98,6 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id,
err_code= PROTOCOL__FLEXRAN_ERR__MSG_DECODING;
goto error;
}
if ((decoded_message->msg_case > sizeof(agent_messages_callback) / (3 * sizeof(flexran_agent_message_decoded_callback))) ||
(decoded_message->msg_dir > PROTOCOL__FLEXRAN_DIRECTION__UNSUCCESSFUL_OUTCOME)){
err_code= PROTOCOL__FLEXRAN_ERR__MSG_NOT_HANDLED;
@@ -139,7 +143,7 @@ void * flexran_agent_pack_message(Protocol__FlexranMessage *msg,
DevAssert(buffer !=NULL);
LOG_D(FLEXRAN_AGENT,"Serilized the enb mac stats reply (size %d)\n", *size);
LOG_D(FLEXRAN_AGENT,"Serilized the eNB-UE stats reply (size %d)\n", *size);
return buffer;
@@ -187,3 +191,587 @@ Protocol__FlexranMessage* flexran_agent_process_timeout(long timer_id, void* tim
err_code_t flexran_agent_destroy_flexran_message(Protocol__FlexranMessage *msg) {
return ((*message_destruction_callback[msg->msg_case-1])(msg));
}
/*
Top Level Statistics Report
*/
int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg){
// TODO: Must deal with sanitization of input
// TODO: Must check if RNTIs and cell ids of the request actually exist
// TODO: Must resolve conflicts among stats requests
int i;
err_code_t err_code;
xid_t xid;
uint32_t usec_interval, sec_interval;
//TODO: We do not deal with multiple CCs at the moment and eNB id is 0
int enb_id = mod_id;
//eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id];
//UE_list_t *eNB_UE_list= &eNB->UE_list;
report_config_t report_config;
uint32_t ue_flags = 0;
uint32_t c_flags = 0;
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
Protocol__FlexStatsRequest *stats_req = input->stats_request_msg;
xid = (stats_req->header)->xid;
// Check the type of request that is made
switch(stats_req->body_case) {
case PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST: ;
Protocol__FlexCompleteStatsRequest *comp_req = stats_req->complete_stats_request;
if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_OFF) {
/*Disable both periodic and continuous updates*/
// flexran_agent_disable_cont_stats_update(mod_id);
flexran_agent_destroy_timer_by_task_id(xid);
*msg = NULL;
return 0;
} else { //One-off, periodical or continuous reporting
//Set the proper flags
ue_flags = comp_req->ue_report_flags;
c_flags = comp_req->cell_report_flags;
//Create a list of all eNB RNTIs and cells
//Set the number of UEs and create list with their RNTIs stats configs
report_config.nr_ue = flexran_get_num_ues(mod_id); //eNB_UE_list->num_UEs
report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue);
if (report_config.ue_report_type == NULL) {
// TODO: Add appropriate error code
err_code = -100;
goto error;
}
for (i = 0; i < report_config.nr_ue; i++) {
report_config.ue_report_type[i].ue_rnti = flexran_get_ue_crnti(enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti;
report_config.ue_report_type[i].ue_report_flags = ue_flags;
}
//Set the number of CCs and create a list with the cell stats configs
report_config.nr_cc = MAX_NUM_CCs;
report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc);
if (report_config.cc_report_type == NULL) {
// TODO: Add appropriate error code
err_code = -100;
goto error;
}
for (i = 0; i < report_config.nr_cc; i++) {
//TODO: Must fill in the proper cell ids
report_config.cc_report_type[i].cc_id = i;
report_config.cc_report_type[i].cc_report_flags = c_flags;
}
/* Check if request was periodical */
if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_PERIODICAL) {
/* Create a one off flexran message as an argument for the periodical task */
Protocol__FlexranMessage *timer_msg;
stats_request_config_t request_config;
request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS;
request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE;
request_config.period = 0;
/* Need to make sure that the ue flags are saved (Bug) */
if (report_config.nr_ue == 0) {
report_config.nr_ue = 1;
report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t));
if (report_config.ue_report_type == NULL) {
// TODO: Add appropriate error code
err_code = -100;
goto error;
}
report_config.ue_report_type[0].ue_rnti = 0; // Dummy value
report_config.ue_report_type[0].ue_report_flags = ue_flags;
}
request_config.config = &report_config;
flexran_agent_stats_request(enb_id, xid, &request_config, &timer_msg);
/* Create a timer */
long timer_id = 0;
flexran_agent_timer_args_t *timer_args;
timer_args = malloc(sizeof(flexran_agent_timer_args_t));
memset (timer_args, 0, sizeof(flexran_agent_timer_args_t));
timer_args->mod_id = enb_id;
timer_args->msg = timer_msg;
/*Convert subframes to usec time*/
usec_interval = 1000*comp_req->sf;
sec_interval = 0;
/*add seconds if required*/
if (usec_interval >= 1000*1000) {
sec_interval = usec_interval/(1000*1000);
usec_interval = usec_interval%(1000*1000);
}
flexran_agent_create_timer(sec_interval, usec_interval, FLEXRAN_AGENT_DEFAULT, enb_id, FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid, flexran_agent_handle_timed_task,(void*) timer_args, &timer_id);
} else if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS) {
/*If request was for continuous updates, disable the previous configuration and
set up a new one*/
flexran_agent_disable_cont_stats_update(mod_id);
stats_request_config_t request_config;
request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS;
request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE;
request_config.period = 0;
/* Need to make sure that the ue flags are saved (Bug) */
if (report_config.nr_ue == 0) {
report_config.nr_ue = 1;
report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t));
if (report_config.ue_report_type == NULL) {
// TODO: Add appropriate error code
err_code = -100;
goto error;
}
report_config.ue_report_type[0].ue_rnti = 0; // Dummy value
report_config.ue_report_type[0].ue_report_flags = ue_flags;
}
request_config.config = &report_config;
flexran_agent_enable_cont_stats_update(enb_id, xid, &request_config);
}
}
break;
case PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST:;
Protocol__FlexCellStatsRequest *cell_req = stats_req->cell_stats_request;
// UE report config will be blank
report_config.nr_ue = 0;
report_config.ue_report_type = NULL;
report_config.nr_cc = cell_req->n_cell;
report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc);
if (report_config.cc_report_type == NULL) {
// TODO: Add appropriate error code
err_code = -100;
goto error;
}
for (i = 0; i < report_config.nr_cc; i++) {
//TODO: Must fill in the proper cell ids
report_config.cc_report_type[i].cc_id = cell_req->cell[i];
report_config.cc_report_type[i].cc_report_flags = cell_req->flags;
}
break;
case PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST:;
Protocol__FlexUeStatsRequest *ue_req = stats_req->ue_stats_request;
// Cell report config will be blank
report_config.nr_cc = 0;
report_config.cc_report_type = NULL;
report_config.nr_ue = ue_req->n_rnti;
report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue);
if (report_config.ue_report_type == NULL) {
// TODO: Add appropriate error code
err_code = -100;
goto error;
}
for (i = 0; i < report_config.nr_ue; i++) {
report_config.ue_report_type[i].ue_rnti = ue_req->rnti[i];
report_config.ue_report_type[i].ue_report_flags = ue_req->flags;
}
break;
default:
//TODO: Add appropriate error code
err_code = -100;
goto error;
}
if (flexran_agent_stats_reply(enb_id, xid, &report_config, msg )){
err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
goto error;
}
free(report_config.ue_report_type);
free(report_config.cc_report_type);
return 0;
error :
LOG_E(FLEXRAN_AGENT, "errno %d occured\n", err_code);
return err_code;
}
/*
Top level reply
*/
int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg){
Protocol__FlexHeader *header;
err_code_t err_code;
int i;
if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0)
goto error;
Protocol__FlexStatsReply *stats_reply_msg;
stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply));
if (stats_reply_msg == NULL)
goto error;
protocol__flex_stats_reply__init(stats_reply_msg);
stats_reply_msg->header = header;
stats_reply_msg->n_ue_report = report_config->nr_ue;
stats_reply_msg->n_cell_report = report_config->nr_cc;
// UE report
Protocol__FlexUeStatsReport **ue_report;
ue_report = malloc(sizeof(Protocol__FlexUeStatsReport *) * report_config->nr_ue);
if (ue_report == NULL)
goto error;
for (i = 0; i < report_config->nr_ue; i++) {
ue_report[i] = malloc(sizeof(Protocol__FlexUeStatsReport));
protocol__flex_ue_stats_report__init(ue_report[i]);
ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti;
ue_report[i]->has_rnti = 1;
ue_report[i]->flags = report_config->ue_report_type[i].ue_report_flags;
ue_report[i]->has_flags = 1;
}
// cell rpoert
Protocol__FlexCellStatsReport **cell_report;
cell_report = malloc(sizeof(Protocol__FlexCellStatsReport *) * report_config->nr_cc);
if (cell_report == NULL)
goto error;
for (i = 0; i < report_config->nr_cc; i++) {
cell_report[i] = malloc(sizeof(Protocol__FlexCellStatsReport));
if(cell_report[i] == NULL)
goto error;
protocol__flex_cell_stats_report__init(cell_report[i]);
cell_report[i]->carrier_index = report_config->cc_report_type[i].cc_id;
cell_report[i]->has_carrier_index = 1;
cell_report[i]->flags = report_config->cc_report_type[i].cc_report_flags;
cell_report[i]->has_flags = 1;
}
/*
MAC reply split
*/
if (flexran_agent_mac_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) {
err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
goto error;
}
/*
RRC reply split
*/
if (flexran_agent_rrc_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) {
err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
goto error;
}
/*
PDCP reply split
*/
if (flexran_agent_pdcp_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) {
err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
goto error;
}
stats_reply_msg->cell_report = cell_report;
stats_reply_msg->ue_report = ue_report;
*msg = malloc(sizeof(Protocol__FlexranMessage));
if(*msg == NULL)
goto error;
protocol__flexran_message__init(*msg);
(*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG;
(*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
(*msg)->stats_reply_msg = stats_reply_msg;
return 0;
error :
LOG_E(FLEXRAN_AGENT, "errno %d occured\n", err_code);
return err_code;
}
/*
Top Level Request
*/
int flexran_agent_stats_request(mid_t mod_id,
xid_t xid,
const stats_request_config_t *report_config,
Protocol__FlexranMessage **msg) {
Protocol__FlexHeader *header;
int i;
Protocol__FlexStatsRequest *stats_request_msg;
stats_request_msg = malloc(sizeof(Protocol__FlexStatsRequest));
if(stats_request_msg == NULL)
goto error;
protocol__flex_stats_request__init(stats_request_msg);
if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REQUEST, &header) != 0)
goto error;
stats_request_msg->header = header;
stats_request_msg->type = report_config->report_type;
stats_request_msg->has_type = 1;
switch (report_config->report_type) {
case PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS:
stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST;
Protocol__FlexCompleteStatsRequest *complete_stats;
complete_stats = malloc(sizeof(Protocol__FlexCompleteStatsRequest));
if(complete_stats == NULL)
goto error;
protocol__flex_complete_stats_request__init(complete_stats);
complete_stats->report_frequency = report_config->report_frequency;
complete_stats->has_report_frequency = 1;
complete_stats->sf = report_config->period;
complete_stats->has_sf = 1;
complete_stats->has_cell_report_flags = 1;
complete_stats->has_ue_report_flags = 1;
if (report_config->config->nr_cc > 0) {
complete_stats->cell_report_flags = report_config->config->cc_report_type[0].cc_report_flags;
}
if (report_config->config->nr_ue > 0) {
complete_stats->ue_report_flags = report_config->config->ue_report_type[0].ue_report_flags;
}
stats_request_msg->complete_stats_request = complete_stats;
break;
case PROTOCOL__FLEX_STATS_TYPE__FLST_CELL_STATS:
stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST;
Protocol__FlexCellStatsRequest *cell_stats;
cell_stats = malloc(sizeof(Protocol__FlexCellStatsRequest));
if(cell_stats == NULL)
goto error;
protocol__flex_cell_stats_request__init(cell_stats);
cell_stats->n_cell = report_config->config->nr_cc;
cell_stats->has_flags = 1;
if (cell_stats->n_cell > 0) {
uint32_t *cells;
cells = (uint32_t *) malloc(sizeof(uint32_t)*cell_stats->n_cell);
for (i = 0; i < cell_stats->n_cell; i++) {
cells[i] = report_config->config->cc_report_type[i].cc_id;
}
cell_stats->cell = cells;
cell_stats->flags = report_config->config->cc_report_type[i].cc_report_flags;
}
stats_request_msg->cell_stats_request = cell_stats;
break;
case PROTOCOL__FLEX_STATS_TYPE__FLST_UE_STATS:
stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST;
Protocol__FlexUeStatsRequest *ue_stats;
ue_stats = malloc(sizeof(Protocol__FlexUeStatsRequest));
if(ue_stats == NULL)
goto error;
protocol__flex_ue_stats_request__init(ue_stats);
ue_stats->n_rnti = report_config->config->nr_ue;
ue_stats->has_flags = 1;
if (ue_stats->n_rnti > 0) {
uint32_t *ues;
ues = (uint32_t *) malloc(sizeof(uint32_t)*ue_stats->n_rnti);
for (i = 0; i < ue_stats->n_rnti; i++) {
ues[i] = report_config->config->ue_report_type[i].ue_rnti;
}
ue_stats->rnti = ues;
ue_stats->flags = report_config->config->ue_report_type[i].ue_report_flags;
}
stats_request_msg->ue_stats_request = ue_stats;
break;
default:
goto error;
}
*msg = malloc(sizeof(Protocol__FlexranMessage));
if(*msg == NULL)
goto error;
protocol__flexran_message__init(*msg);
(*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG;
(*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
(*msg)->stats_request_msg = stats_request_msg;
return 0;
error:
// TODO: Need to make proper error handling
if (header != NULL)
free(header);
if (stats_request_msg != NULL)
free(stats_request_msg);
if(*msg != NULL)
free(*msg);
//LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg) {
if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG)
goto error;
free(msg->stats_request_msg->header);
if (msg->stats_request_msg->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST) {
free(msg->stats_request_msg->cell_stats_request->cell);
}
if (msg->stats_request_msg->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST) {
free(msg->stats_request_msg->ue_stats_request->rnti);
}
free(msg->stats_request_msg);
free(msg);
return 0;
error:
//LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
return -1;
}
/*
Top Level Update
*/
void flexran_agent_send_update_stats(mid_t mod_id) {
Protocol__FlexranMessage *current_report = NULL;
void *data;
int size;
err_code_t err_code;
int priority = 0;
if (pthread_mutex_lock(stats_context[mod_id].mutex)) {
goto error;
}
if (stats_context[mod_id].cont_update == 1) {
/*Create a fresh report with the required flags*/
err_code = flexran_agent_handle_stats(mod_id, (void *) stats_context[mod_id].stats_req, &current_report);
if (err_code < 0) {
goto error;
}
}
/* /\*TODO:Check if a previous reports exists and if yes, generate a report */
/* *that is the diff between the old and the new report, */
/* *respecting the thresholds. Otherwise send the new report*\/ */
/* if (stats_context[mod_id].prev_stats_reply != NULL) { */
/* msg = flexran_agent_generate_diff_mac_stats_report(current_report, stats_context[mod_id].prev_stats_reply); */
/* /\*Destroy the old stats*\/ */
/* flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); */
/* } */
/* /\*Use the current report for future comparissons*\/ */
/* stats_context[mod_id].prev_stats_reply = current_report; */
if (pthread_mutex_unlock(stats_context[mod_id].mutex)) {
goto error;
}
if (current_report != NULL){
data=flexran_agent_pack_message(current_report, &size);
/*Send any stats updates using the MAC channel of the eNB*/
if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_MAC, data, size, priority)) {
err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING;
goto error;
}
LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size);
return;
}
error:
LOG_D(FLEXRAN_AGENT, "Could not send sf trigger message\n");
}
err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id) {
/*Disable the continuous updates for the MAC*/
if (pthread_mutex_lock(stats_context[mod_id].mutex)) {
goto error;
}
stats_context[mod_id].cont_update = 0;
stats_context[mod_id].xid = 0;
if (stats_context[mod_id].stats_req != NULL) {
flexran_agent_destroy_flexran_message(stats_context[mod_id].stats_req);
}
if (stats_context[mod_id].prev_stats_reply != NULL) {
flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply);
}
if (pthread_mutex_unlock(stats_context[mod_id].mutex)) {
goto error;
}
return 0;
error:
LOG_E(FLEXRAN_AGENT, "stats_context for eNB %d is not initialized\n", mod_id);
return -1;
}
err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id,
xid_t xid, stats_request_config_t *stats_req) {
if (pthread_mutex_lock(stats_context[mod_id].mutex)) {
goto error;
}
Protocol__FlexranMessage *req_msg;
flexran_agent_stats_request(mod_id, xid, stats_req, &req_msg);
stats_context[mod_id].stats_req = req_msg;
stats_context[mod_id].prev_stats_reply = NULL;
stats_context[mod_id].cont_update = 1;
stats_context[mod_id].xid = xid;
if (pthread_mutex_unlock(stats_context[mod_id].mutex)) {
goto error;
}
return 0;
error:
LOG_E(FLEXRAN_AGENT, "stats_context for eNB %d is not initialized\n", mod_id);
return -1;
}
err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id) {
/*Initially the continuous update is set to false*/
stats_context[mod_id].cont_update = 0;
stats_context[mod_id].is_initialized = 1;
stats_context[mod_id].stats_req = NULL;
stats_context[mod_id].prev_stats_reply = NULL;
stats_context[mod_id].mutex = calloc(1, sizeof(pthread_mutex_t));
if (stats_context[mod_id].mutex == NULL)
goto error;
if (pthread_mutex_init(stats_context[mod_id].mutex, NULL))
goto error;
return 0;
error:
return -1;
}
err_code_t flexran_agent_destroy_cont_stats_update(mid_t mod_id) {
stats_context[mod_id].cont_update = 0;
stats_context[mod_id].is_initialized = 0;
flexran_agent_destroy_flexran_message(stats_context[mod_id].stats_req);
flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply);
free(stats_context[mod_id].mutex);
// mac_agent_registered[mod_id] = 0;
return 1;
}