FlexRAN: Simplify stats request handling
* only set up timer for sending requests * simplify interface for timer setup * on timer expiry, do not pass through stats request function but directly send the reply * Remove whatever report structure and use stats request directly for inferring the data to send
This commit is contained in:
@@ -63,9 +63,12 @@ pthread_mutex_t sc_update_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
|
||||
int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
const report_config_t *report_config,
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
Protocol__FlexCellStatsReport **cell_report) {
|
||||
int n_ue,
|
||||
uint32_t ue_flags,
|
||||
Protocol__FlexCellStatsReport **cell_report,
|
||||
int n_cc,
|
||||
uint32_t cc_flags) {
|
||||
|
||||
|
||||
// Protocol__FlexHeader *header;
|
||||
@@ -75,18 +78,16 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
int enb_id = mod_id;
|
||||
|
||||
/* Allocate memory for list of UE reports */
|
||||
if (report_config->nr_ue > 0) {
|
||||
if (n_ue > 0) {
|
||||
|
||||
|
||||
for (i = 0; i < report_config->nr_ue; i++) {
|
||||
for (i = 0; i < n_ue; i++) {
|
||||
|
||||
UE_id = flexran_get_mac_ue_id(mod_id, i);
|
||||
|
||||
ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti;
|
||||
ue_report[i]->has_rnti = 1;
|
||||
const rnti_t rnti = ue_report[i]->rnti;
|
||||
UE_id = flexran_get_mac_ue_id_rnti(mod_id, rnti);
|
||||
|
||||
/* Check flag for creation of buffer status report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) {
|
||||
if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) {
|
||||
//TODO should be automated
|
||||
ue_report[i]->n_bsr = 4;
|
||||
uint32_t *elem;
|
||||
@@ -103,7 +104,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
}
|
||||
|
||||
/* Check flag for creation of PHR report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) {
|
||||
if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) {
|
||||
ue_report[i]->phr = flexran_get_ue_phr (enb_id, UE_id); // eNB_UE_list->UE_template[UE_PCCID(enb_id,UE_id)][UE_id].phr_info;
|
||||
ue_report[i]->has_phr = 1;
|
||||
ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR;
|
||||
@@ -111,7 +112,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
}
|
||||
|
||||
/* Check flag for creation of RLC buffer status report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) {
|
||||
if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) {
|
||||
ue_report[i]->n_rlc_report = 3; // Set this to the number of LCs for this UE. This needs to be generalized for for LCs
|
||||
Protocol__FlexRlcBsr ** rlc_reports;
|
||||
rlc_reports = malloc(sizeof(Protocol__FlexRlcBsr *) * ue_report[i]->n_rlc_report);
|
||||
@@ -157,7 +158,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
}
|
||||
|
||||
/* Check flag for creation of MAC CE buffer status report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) {
|
||||
if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) {
|
||||
// TODO: Fill in the actual MAC CE buffer status report
|
||||
ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id, UE_id, 0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15;
|
||||
// Use as bitmap. Set one or more of the; /* Use as bitmap. Set one or more of the
|
||||
@@ -169,7 +170,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
}
|
||||
|
||||
/* Check flag for creation of DL CQI report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) {
|
||||
if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) {
|
||||
// TODO: Fill in the actual DL CQI report for the UE based on its configuration
|
||||
Protocol__FlexDlCqiReport * dl_report;
|
||||
dl_report = malloc(sizeof(Protocol__FlexDlCqiReport));
|
||||
@@ -420,7 +421,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
}
|
||||
|
||||
/* Check flag for creation of paging buffer status report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) {
|
||||
if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) {
|
||||
//TODO: Fill in the actual paging buffer status report. For this field to be valid, the RNTI
|
||||
//set in the report must be a P-RNTI
|
||||
Protocol__FlexPagingBufferReport *paging_report;
|
||||
@@ -474,7 +475,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
}
|
||||
|
||||
/* Check flag for creation of UL CQI report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) {
|
||||
if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) {
|
||||
|
||||
//Fill in the full UL CQI report of the UE
|
||||
Protocol__FlexUlCqiReport *full_ul_report;
|
||||
@@ -559,7 +560,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI;
|
||||
|
||||
}
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) {
|
||||
if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) {
|
||||
|
||||
Protocol__FlexMacStats *macstats;
|
||||
macstats = malloc(sizeof(Protocol__FlexMacStats));
|
||||
@@ -668,15 +669,15 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
}
|
||||
|
||||
/* Allocate memory for list of cell reports */
|
||||
if (report_config->nr_cc > 0) {
|
||||
if (n_cc > 0) {
|
||||
|
||||
|
||||
// Fill in the Cell reports
|
||||
for (i = 0; i < report_config->nr_cc; i++) {
|
||||
for (i = 0; i < n_cc; i++) {
|
||||
|
||||
|
||||
/* Check flag for creation of noise and interference report */
|
||||
if(report_config->cc_report_type[i].cc_report_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) {
|
||||
if(cc_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) {
|
||||
// TODO: Fill in the actual noise and interference report for this cell
|
||||
Protocol__FlexNoiseInterferenceReport *ni_report;
|
||||
ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport));
|
||||
@@ -710,8 +711,8 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
error:
|
||||
|
||||
if (cell_report != NULL) {
|
||||
if (report_config->nr_cc > 0) {
|
||||
for (i = 0; i < report_config->nr_cc; i++) {
|
||||
if (n_cc > 0) {
|
||||
for (i = 0; i < n_cc; i++) {
|
||||
if (cell_report[i]->noise_inter_report != NULL) {
|
||||
free(cell_report[i]->noise_inter_report);
|
||||
cell_report[i]->noise_inter_report = NULL;
|
||||
@@ -723,8 +724,8 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
}
|
||||
|
||||
if (ue_report != NULL) {
|
||||
if (report_config->nr_ue > 0) {
|
||||
for (i = 0; i < report_config->nr_ue; i++) {
|
||||
if (n_ue > 0) {
|
||||
for (i = 0; i < n_ue; i++) {
|
||||
if (ue_report[i]->bsr != NULL) {
|
||||
free(ue_report[i]->bsr);
|
||||
ue_report[i]->bsr = NULL;
|
||||
|
||||
@@ -52,7 +52,13 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle
|
||||
int flexran_agent_mac_destroy_sf_trigger(Protocol__FlexranMessage *msg);
|
||||
|
||||
/* Statistics reply protocol message constructor and destructor */
|
||||
int flexran_agent_mac_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report);
|
||||
int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
int n_ue,
|
||||
uint32_t ue_flags,
|
||||
Protocol__FlexCellStatsReport **cell_report,
|
||||
int n_cc,
|
||||
uint32_t cc_flags);
|
||||
int flexran_agent_mac_destroy_stats_reply(Protocol__FlexStatsReply *reply);
|
||||
|
||||
/* DL MAC scheduling decision protocol message constructor (empty command) and destructor */
|
||||
|
||||
@@ -61,12 +61,6 @@ err_code_t flexran_agent_init_cont_mac_stats_update(mid_t mod_id);
|
||||
err_code_t flexran_agent_destroy_cont_mac_stats_update(mid_t mod_id);
|
||||
|
||||
|
||||
/*Enable/Disable the continuous stats update service for the MAC*/
|
||||
err_code_t flexran_agent_enable_cont_mac_stats_update(mid_t mod_id, xid_t xid,
|
||||
stats_request_config_t *stats_req);
|
||||
|
||||
err_code_t flexran_agent_disable_cont_mac_stats_update(mid_t mod_id);
|
||||
|
||||
Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol__FlexranMessage *new_report,
|
||||
Protocol__FlexranMessage *old_report);
|
||||
|
||||
|
||||
@@ -65,25 +65,17 @@ void flexran_agent_pdcp_aggregate_stats(const mid_t mod_id,
|
||||
|
||||
|
||||
int flexran_agent_pdcp_stats_reply(mid_t mod_id,
|
||||
const report_config_t *report_config,
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
Protocol__FlexCellStatsReport **cell_report) {
|
||||
|
||||
|
||||
// Protocol__FlexHeader *header;
|
||||
int i;
|
||||
// int cc_id = 0;
|
||||
|
||||
|
||||
/* Allocate memory for list of UE reports */
|
||||
if (report_config->nr_ue > 0) {
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
int n_ue,
|
||||
uint32_t ue_flags) {
|
||||
if (n_ue > 0) {
|
||||
|
||||
for (i = 0; i < report_config->nr_ue; i++) {
|
||||
const rnti_t rnti = report_config->ue_report_type[i].ue_rnti;
|
||||
for (int i = 0; i < n_ue; i++) {
|
||||
const rnti_t rnti = ue_report[i]->rnti;
|
||||
const uint16_t uid = flexran_get_pdcp_uid_from_rnti(mod_id, rnti);
|
||||
|
||||
/* Check flag for creation of buffer status report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PDCP_STATS) {
|
||||
if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PDCP_STATS) {
|
||||
|
||||
Protocol__FlexPdcpStats *pdcp_aggr_stats;
|
||||
pdcp_aggr_stats = malloc(sizeof(Protocol__FlexPdcpStats));
|
||||
@@ -129,12 +121,6 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id,
|
||||
|
||||
error:
|
||||
LOG_W(FLEXRAN_AGENT, "Can't allocate PDCP stats\n");
|
||||
|
||||
/* if (cell_report != NULL)
|
||||
free(cell_report);
|
||||
if (ue_report != NULL)
|
||||
free(ue_report);
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,9 +48,9 @@
|
||||
|
||||
/* Send to the controller all the pdcp stat updates that occured during this subframe*/
|
||||
int flexran_agent_pdcp_stats_reply(mid_t mod_id,
|
||||
const report_config_t *report_config,
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
Protocol__FlexCellStatsReport **cell_report);
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
int n_ue,
|
||||
uint32_t ue_flags);
|
||||
int flexran_agent_pdcp_destroy_stats_reply(Protocol__FlexStatsReply *reply);
|
||||
|
||||
/* Get the stats from RAN API and aggregate them per USER*/
|
||||
|
||||
@@ -380,18 +380,15 @@ void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t* measRes
|
||||
|
||||
|
||||
int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
const report_config_t *report_config,
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
Protocol__FlexCellStatsReport **cell_report) {
|
||||
|
||||
if (report_config->nr_ue > 0) {
|
||||
rnti_t rntis[report_config->nr_ue];
|
||||
flexran_get_rrc_rnti_list(mod_id, rntis, report_config->nr_ue);
|
||||
for (int i = 0; i < report_config->nr_ue; i++) {
|
||||
const rnti_t rnti = rntis[i];
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
int n_ue,
|
||||
uint32_t ue_flags) {
|
||||
if (n_ue > 0) {
|
||||
for (int i = 0; i < n_ue; i++) {
|
||||
const rnti_t rnti = ue_report[i]->rnti;
|
||||
|
||||
/* Check flag for creation of buffer status report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) {
|
||||
if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) {
|
||||
|
||||
/*Source cell EUTRA Measurements*/
|
||||
Protocol__FlexRrcMeasurements *rrc_measurements;
|
||||
@@ -531,7 +528,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
for (int i = 0; i < report_config->nr_ue; i++) {
|
||||
for (int i = 0; i < n_ue; i++) {
|
||||
if (ue_report[i]->rrc_measurements && ue_report[i]->rrc_measurements->neigh_meas != NULL) {
|
||||
for (int j = 0; j < ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++) {
|
||||
free(ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]);
|
||||
@@ -540,8 +537,6 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
}
|
||||
}
|
||||
|
||||
if (cell_report != NULL)
|
||||
free(cell_report);
|
||||
if (ue_report != NULL)
|
||||
free(ue_report);
|
||||
return -1;
|
||||
@@ -575,20 +570,18 @@ int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply)
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_stats_reply(mid_t mod_id,
|
||||
const report_config_t *report_config,
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
Protocol__FlexCellStatsReport **cell_report) {
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
int n_ue,
|
||||
uint32_t ue_flags) {
|
||||
/* This function fills the GTP part of the statistics. The necessary
|
||||
* information is, for our purposes, completely maintained in the RRC layer.
|
||||
* It would be possible to add a GTP module that handles this, though. */
|
||||
if (report_config->nr_ue > 0) {
|
||||
rnti_t rntis[report_config->nr_ue];
|
||||
flexran_get_rrc_rnti_list(mod_id, rntis, report_config->nr_ue);
|
||||
for (int i = 0; i < report_config->nr_ue; i++) {
|
||||
const rnti_t rnti = rntis[i];
|
||||
if (n_ue > 0) {
|
||||
for (int i = 0; i < n_ue; i++) {
|
||||
const rnti_t rnti = ue_report[i]->rnti;
|
||||
|
||||
/* Check flag for creation of buffer status report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_GTP_STATS) {
|
||||
if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_GTP_STATS) {
|
||||
|
||||
/* get number of rabs for this UE */
|
||||
const int num_e_rab = flexran_agent_rrc_gtp_num_e_rab(mod_id, rnti);
|
||||
@@ -618,7 +611,7 @@ int flexran_agent_rrc_gtp_stats_reply(mid_t mod_id,
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
for (int i = 0; i < report_config->nr_ue; i++) {
|
||||
for (int i = 0; i < n_ue; i++) {
|
||||
if (!ue_report[i]->gtp_stats) continue;
|
||||
for (int r = 0; r < ue_report[i]->n_gtp_stats; ++r) {
|
||||
if (ue_report[i]->gtp_stats[r]) {
|
||||
|
||||
@@ -57,12 +57,18 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg);
|
||||
void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t *);
|
||||
|
||||
/* Statistics reply protocol message constructor and destructor */
|
||||
int flexran_agent_rrc_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report);
|
||||
int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
int n_ue,
|
||||
uint32_t ue_flags);
|
||||
int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply);
|
||||
|
||||
/* Statistic reply for GTP statistics which OAI stores also in the RRC layer.
|
||||
* This might be moved to a separate GTP module in the future */
|
||||
int flexran_agent_rrc_gtp_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report);
|
||||
int flexran_agent_rrc_gtp_stats_reply(mid_t mod_id,
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
int n_ue,
|
||||
uint32_t ue_flags);
|
||||
int flexran_agent_rrc_gtp_destroy_stats_reply(Protocol__FlexStatsReply *reply);
|
||||
|
||||
/* Fill the RRC part of a ue_config message */
|
||||
|
||||
@@ -202,8 +202,6 @@ int flexran_agent_start(mid_t mod_id)
|
||||
*flexran_agent_register_channel(mod_id, channel, FLEXRAN_AGENT_MAC);
|
||||
*/
|
||||
|
||||
/*Initialize the continuous stats update mechanism*/
|
||||
flexran_agent_init_cont_stats_update(mod_id);
|
||||
pthread_t t;
|
||||
threadCreate(&t, receive_thread, flexran, "flexran", -1, OAI_PRIORITY_RT);
|
||||
|
||||
|
||||
@@ -153,21 +153,17 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id,
|
||||
Protocol__FlexranMessage *flexran_agent_handle_timed_task(void *args);
|
||||
|
||||
/*Top level Statistics hanlder*/
|
||||
Protocol__FlexranMessage *flexran_agent_send_stats_reply(void *args);
|
||||
int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg);
|
||||
|
||||
/* Function to be used to handle reply message . */
|
||||
int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg);
|
||||
int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const Protocol__FlexStatsRequest *stats_req, Protocol__FlexranMessage **msg);
|
||||
int flexran_agent_destroy_stats_reply(Protocol__FlexranMessage *msg);
|
||||
|
||||
/* Top level Statistics request protocol message constructor and destructor */
|
||||
int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg);
|
||||
//int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg);
|
||||
int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg);
|
||||
|
||||
err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id);
|
||||
|
||||
err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, xid_t xid, stats_request_config_t *stats_req) ;
|
||||
err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id);
|
||||
|
||||
/* Handle a received eNB config reply message as an "order" to reconfigure. It
|
||||
* does not come as a reconfiguration message as this is a "structured"
|
||||
* ProtoBuf message (as opposed to "unstructured" YAML). There is no destructor
|
||||
|
||||
@@ -193,38 +193,4 @@ typedef struct {
|
||||
|
||||
} agent_reconf_rrc;
|
||||
|
||||
|
||||
/* These structs will be used to give
|
||||
instructions for the type of stats reports
|
||||
we need to create */
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t ue_rnti;
|
||||
uint32_t ue_report_flags; /* Indicates the report elements
|
||||
required for this UE id. See
|
||||
FlexRAN specification 1.2.4.2 */
|
||||
} ue_report_type_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t cc_id;
|
||||
uint32_t cc_report_flags; /* Indicates the report elements
|
||||
required for this CC index. See
|
||||
FlexRAN specification 1.2.4.3 */
|
||||
} cc_report_type_t;
|
||||
|
||||
typedef struct {
|
||||
int nr_ue;
|
||||
ue_report_type_t *ue_report_type;
|
||||
int nr_cc;
|
||||
cc_report_type_t *cc_report_type;
|
||||
} report_config_t;
|
||||
|
||||
typedef struct stats_request_config_s{
|
||||
uint8_t report_type;
|
||||
uint8_t report_frequency;
|
||||
uint16_t period; /*In number of subframes*/
|
||||
report_config_t *config;
|
||||
} stats_request_config_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -196,335 +196,186 @@ err_code_t flexran_agent_destroy_flexran_message(Protocol__FlexranMessage *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 = 0;
|
||||
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;
|
||||
|
||||
int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
|
||||
*msg = NULL;
|
||||
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
|
||||
|
||||
Protocol__FlexStatsRequest *stats_req = input->stats_request_msg;
|
||||
xid = (stats_req->header)->xid;
|
||||
const xid_t 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
|
||||
if (stats_req->body_case != PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST) {
|
||||
LOG_E(FLEXRAN_AGENT, "only complete stats are supported at the moment\n");
|
||||
return -1;
|
||||
}
|
||||
Protocol__FlexCompleteStatsRequest *comp_req = stats_req->complete_stats_request;
|
||||
flexran_agent_timer_args_t *timer_args = NULL;
|
||||
|
||||
//Set the number of UEs and create list with their RNTIs stats configs
|
||||
report_config.nr_ue = 0;
|
||||
if (flexran_agent_get_rrc_xface(mod_id))
|
||||
report_config.nr_ue = flexran_get_rrc_num_ues(mod_id);
|
||||
else if (flexran_agent_get_mac_xface(mod_id))
|
||||
report_config.nr_ue = flexran_get_mac_num_ues(mod_id);
|
||||
|
||||
if (flexran_agent_get_rrc_xface(mod_id) && flexran_agent_get_mac_xface(mod_id)
|
||||
&& flexran_get_rrc_num_ues(mod_id) != flexran_get_mac_num_ues(mod_id)) {
|
||||
const int nrrc = flexran_get_rrc_num_ues(mod_id);
|
||||
const int nmac = flexran_get_mac_num_ues(mod_id);
|
||||
report_config.nr_ue = nrrc < nmac ? nrrc : nmac;
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %d UEs\n",
|
||||
__func__, nrrc, nmac, report_config.nr_ue);
|
||||
}
|
||||
report_config.ue_report_type = 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;
|
||||
}
|
||||
if (flexran_agent_get_rrc_xface(mod_id)) {
|
||||
rnti_t rntis[report_config.nr_ue];
|
||||
flexran_get_rrc_rnti_list(mod_id, rntis, report_config.nr_ue);
|
||||
for (i = 0; i < report_config.nr_ue; i++) {
|
||||
report_config.ue_report_type[i].ue_rnti = rntis[i];
|
||||
report_config.ue_report_type[i].ue_report_flags = ue_flags;
|
||||
}
|
||||
}
|
||||
if (flexran_agent_get_mac_xface(mod_id) && !flexran_agent_get_rrc_xface(mod_id)) {
|
||||
for (i = 0; i < report_config.nr_ue; i++) {
|
||||
const int UE_id = flexran_get_mac_ue_id(mod_id, i);
|
||||
report_config.ue_report_type[i].ue_rnti = flexran_get_mac_ue_crnti(enb_id, UE_id);
|
||||
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 = 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 = NULL;
|
||||
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 = 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;
|
||||
if (flexran_agent_stats_request(enb_id, xid, &request_config, &timer_msg) == -1) {
|
||||
err_code = -100;
|
||||
goto error;
|
||||
}
|
||||
/* Create a timer */
|
||||
long timer_id = 0;
|
||||
flexran_agent_timer_args_t *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 = 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 = 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 = 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++) {
|
||||
const int UE_id = flexran_get_mac_ue_id(mod_id, i);
|
||||
report_config.ue_report_type[i].ue_rnti = ue_req->rnti[UE_id];
|
||||
report_config.ue_report_type[i].ue_report_flags = ue_req->flags;
|
||||
}
|
||||
break;
|
||||
switch (comp_req->report_frequency) {
|
||||
case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_OFF:
|
||||
flexran_agent_destroy_timer_by_task_id(xid);
|
||||
return 0;
|
||||
case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE:
|
||||
LOG_E(FLEXRAN_AGENT, "one-shot timer not implemented yet\n");
|
||||
return -1;
|
||||
case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_PERIODICAL:
|
||||
/* Create a one off flexran message as an argument for the periodical task */
|
||||
timer_args = calloc(1, sizeof(flexran_agent_timer_args_t));
|
||||
AssertFatal(timer_args, "cannot allocate memory for timer\n");
|
||||
timer_args->mod_id = mod_id;
|
||||
timer_args->msg = input;
|
||||
flexran_agent_create_timer(mod_id, comp_req->sf,
|
||||
FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid,
|
||||
flexran_agent_send_stats_reply, timer_args);
|
||||
/* return 1: do not dispose comp_req message we received, we still need it */
|
||||
return 1;
|
||||
case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS:
|
||||
LOG_E(FLEXRAN_AGENT, "unsupported report frequency continuous\n");
|
||||
return -1;
|
||||
default:
|
||||
//TODO: Add appropriate error code
|
||||
err_code = -100;
|
||||
goto error;
|
||||
LOG_E(FLEXRAN_AGENT, "unknown report frequency\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flexran_agent_stats_reply(enb_id, xid, &report_config, msg )) {
|
||||
err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (report_config.ue_report_type)
|
||||
free(report_config.ue_report_type);
|
||||
if (report_config.cc_report_type)
|
||||
free(report_config.cc_report_type);
|
||||
|
||||
return 0;
|
||||
|
||||
error :
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): errno %d occured\n", __func__, err_code);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
/*
|
||||
Top level reply
|
||||
*/
|
||||
Protocol__FlexranMessage *flexran_agent_send_stats_reply(void *args) {
|
||||
const flexran_agent_timer_args_t *timer_args = args;
|
||||
const mid_t enb_id = timer_args->mod_id;
|
||||
const Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)timer_args->msg;
|
||||
const Protocol__FlexStatsRequest *stats_req = input->stats_request_msg;
|
||||
const xid_t xid = stats_req->header->xid;
|
||||
|
||||
int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg){
|
||||
Protocol__FlexranMessage *reply = NULL;
|
||||
err_code_t rc = flexran_agent_stats_reply(enb_id, xid, stats_req, &reply);
|
||||
if (rc < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): errno %d occured, cannot send stats_reply\n",
|
||||
__func__, rc);
|
||||
return NULL;
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
int flexran_agent_stats_reply(mid_t enb_id,
|
||||
xid_t xid,
|
||||
const Protocol__FlexStatsRequest *stats_req,
|
||||
Protocol__FlexranMessage **msg) {
|
||||
|
||||
Protocol__FlexHeader *header = NULL;
|
||||
Protocol__FlexUeStatsReport **ue_report = NULL;
|
||||
Protocol__FlexCellStatsReport **cell_report = NULL;
|
||||
Protocol__FlexStatsReply *stats_reply_msg = NULL;
|
||||
err_code_t err_code = PROTOCOL__FLEXRAN_ERR__UNEXPECTED;
|
||||
int i,j;
|
||||
AssertFatal(stats_req->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST,
|
||||
"%s() handles only complete stats requests\n",
|
||||
__func__);
|
||||
const uint32_t cell_flags = stats_req->complete_stats_request->cell_report_flags;
|
||||
const uint32_t ue_flags = stats_req->complete_stats_request->ue_report_flags;
|
||||
|
||||
if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) {
|
||||
goto error;
|
||||
/* TODO: get_number in own function */
|
||||
int n_ue = 0;
|
||||
if (flexran_agent_get_rrc_xface(enb_id))
|
||||
n_ue = flexran_get_rrc_num_ues(enb_id);
|
||||
else if (flexran_agent_get_mac_xface(enb_id))
|
||||
n_ue = flexran_get_mac_num_ues(enb_id);
|
||||
|
||||
if (flexran_agent_get_rrc_xface(enb_id) && flexran_agent_get_mac_xface(enb_id)
|
||||
&& flexran_get_rrc_num_ues(enb_id) != flexran_get_mac_num_ues(enb_id)) {
|
||||
const int nrrc = flexran_get_rrc_num_ues(enb_id);
|
||||
const int nmac = flexran_get_mac_num_ues(enb_id);
|
||||
n_ue = nrrc < nmac ? nrrc : nmac;
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %d UEs\n",
|
||||
__func__, nrrc, nmac, n_ue);
|
||||
}
|
||||
|
||||
stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply));
|
||||
|
||||
if (stats_reply_msg == NULL) {
|
||||
goto error;
|
||||
rnti_t rntis[n_ue];
|
||||
if (flexran_agent_get_rrc_xface(enb_id))
|
||||
flexran_get_rrc_rnti_list(enb_id, rntis, n_ue);
|
||||
if (flexran_agent_get_mac_xface(enb_id) && !flexran_agent_get_rrc_xface(enb_id)) {
|
||||
for (int i = 0; i < n_ue; i++) {
|
||||
const int UE_id = flexran_get_mac_ue_id(enb_id, i);
|
||||
rntis[i] = flexran_get_mac_ue_crnti(enb_id, UE_id);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
ue_report = malloc(sizeof(Protocol__FlexUeStatsReport *) * report_config->nr_ue);
|
||||
int n_cc = MAX_NUM_CCs;
|
||||
|
||||
ue_report = calloc(n_ue, sizeof(Protocol__FlexUeStatsReport *));
|
||||
if (ue_report == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (i = 0; i < report_config->nr_ue; i++) {
|
||||
|
||||
ue_report[i] = malloc(sizeof(Protocol__FlexUeStatsReport));
|
||||
if (ue_report[i] == NULL) {
|
||||
goto error;
|
||||
}
|
||||
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]->has_flags = 1; /* actual flags are filled in the CMs below */
|
||||
|
||||
for (int i = 0; i < n_ue; i++) {
|
||||
ue_report[i] = malloc(sizeof(Protocol__FlexUeStatsReport));
|
||||
if (ue_report[i] == NULL) {
|
||||
goto error;
|
||||
}
|
||||
protocol__flex_ue_stats_report__init(ue_report[i]);
|
||||
ue_report[i]->rnti = rntis[i];
|
||||
ue_report[i]->has_rnti = 1;
|
||||
ue_report[i]->has_flags = 1; /* actual flags are filled in the CMs below */
|
||||
}
|
||||
|
||||
// cell rpoert
|
||||
|
||||
cell_report = malloc(sizeof(Protocol__FlexCellStatsReport *) * report_config->nr_cc);
|
||||
cell_report = calloc(n_cc, sizeof(Protocol__FlexCellStatsReport *));
|
||||
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]->has_flags = 1; /* actual flags are filled in the CMs below */
|
||||
|
||||
for (int i = 0; i < n_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 = i;
|
||||
cell_report[i]->has_carrier_index = 1;
|
||||
cell_report[i]->has_flags = 1; /* actual flags are filled in the CMs below */
|
||||
}
|
||||
|
||||
/* MAC reply split */
|
||||
if (flexran_agent_get_mac_xface(enb_id)
|
||||
&& flexran_agent_mac_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) {
|
||||
&& flexran_agent_mac_stats_reply(enb_id,
|
||||
ue_report, n_ue, ue_flags,
|
||||
cell_report, n_cc, cell_flags) < 0) {
|
||||
err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* RRC reply split */
|
||||
if (flexran_agent_get_rrc_xface(enb_id)
|
||||
&& flexran_agent_rrc_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) {
|
||||
&& flexran_agent_rrc_stats_reply(enb_id, ue_report, n_ue, ue_flags) < 0) {
|
||||
err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* PDCP reply split */
|
||||
if (flexran_agent_get_pdcp_xface(enb_id)
|
||||
&& flexran_agent_pdcp_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) {
|
||||
&& flexran_agent_pdcp_stats_reply(enb_id, ue_report, n_ue, ue_flags) < 0) {
|
||||
err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* GTP reply split, currently performed through RRC module */
|
||||
if (flexran_agent_get_rrc_xface(enb_id)
|
||||
&& flexran_agent_rrc_gtp_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) {
|
||||
&& flexran_agent_rrc_gtp_stats_reply(enb_id, ue_report, n_ue, ue_flags) < 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) {
|
||||
if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) {
|
||||
goto error;
|
||||
}
|
||||
stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply));
|
||||
AssertFatal(stats_reply_msg, "no memory for stats_reply_msg\n");
|
||||
protocol__flex_stats_reply__init(stats_reply_msg);
|
||||
stats_reply_msg->header = header;
|
||||
stats_reply_msg->n_ue_report = n_ue;
|
||||
stats_reply_msg->ue_report = ue_report;
|
||||
stats_reply_msg->n_cell_report = n_cc;
|
||||
stats_reply_msg->cell_report = cell_report;
|
||||
|
||||
*msg = malloc(sizeof(Protocol__FlexranMessage));
|
||||
AssertFatal(*msg, "no memory for stats_reply container msg\n");
|
||||
protocol__flexran_message__init(*msg);
|
||||
(*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG;
|
||||
(*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
|
||||
@@ -546,7 +397,7 @@ error :
|
||||
}
|
||||
|
||||
if (ue_report != NULL) {
|
||||
for (j = 0; j < report_config->nr_ue; j++) {
|
||||
for (int j = 0; j < n_ue; j++) {
|
||||
if (ue_report[j] != NULL) {
|
||||
free(ue_report[j]);
|
||||
}
|
||||
@@ -556,7 +407,7 @@ error :
|
||||
}
|
||||
|
||||
if (cell_report != NULL) {
|
||||
for (j = 0; j < report_config->nr_cc; j++) {
|
||||
for (int j = 0; j < n_cc; j++) {
|
||||
if (cell_report[j] != NULL) {
|
||||
free(cell_report[j]);
|
||||
}
|
||||
@@ -572,6 +423,7 @@ error :
|
||||
Top Level Request
|
||||
*/
|
||||
|
||||
/*
|
||||
int flexran_agent_stats_request(mid_t mod_id,
|
||||
xid_t xid,
|
||||
const stats_request_config_t *report_config,
|
||||
@@ -678,6 +530,7 @@ int flexran_agent_stats_request(mid_t mod_id,
|
||||
//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)
|
||||
@@ -719,88 +572,3 @@ int flexran_agent_destroy_stats_reply(Protocol__FlexranMessage *msg)
|
||||
free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 = NULL;
|
||||
|
||||
flexran_agent_stats_request(mod_id, xid, stats_req, &req_msg);
|
||||
|
||||
if (req_msg != NULL) {
|
||||
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) != 0)
|
||||
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);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -58,48 +58,48 @@ int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
err_code_t flexran_agent_create_timer(uint32_t interval_sec,
|
||||
uint32_t interval_usec,
|
||||
agent_id_t agent_id,
|
||||
instance_t instance,
|
||||
err_code_t flexran_agent_create_timer(mid_t mod_id,
|
||||
uint32_t sf,
|
||||
uint32_t timer_type,
|
||||
xid_t xid,
|
||||
xid_t xid,
|
||||
flexran_agent_timer_callback_t cb,
|
||||
void *timer_args,
|
||||
long *timer_id) {
|
||||
struct flexran_agent_timer_element_s *e = calloc(1, sizeof(*e));
|
||||
DevAssert(e != NULL);
|
||||
//uint32_t timer_id;
|
||||
void *timer_args) {
|
||||
int ret=-1;
|
||||
|
||||
if ((interval_sec == 0) && (interval_usec == 0 )) {
|
||||
free(e);
|
||||
if (sf <= 0)
|
||||
return TIMER_NULL;
|
||||
}
|
||||
|
||||
if (timer_type >= FLEXRAN_AGENT_TIMER_TYPE_MAX) {
|
||||
free(e);
|
||||
if (timer_type >= FLEXRAN_AGENT_TIMER_TYPE_MAX)
|
||||
return TIMER_TYPE_INVALIDE;
|
||||
}
|
||||
|
||||
uint32_t interval_usec = sf * 1000;
|
||||
uint32_t interval_sec = 0;
|
||||
if (interval_usec >= 1000 * 1000) {
|
||||
interval_sec = interval_usec / (1000 * 1000);
|
||||
interval_usec = interval_usec % (1000 * 1000);
|
||||
}
|
||||
struct flexran_agent_timer_element_s *e = calloc(1, sizeof(*e));
|
||||
DevAssert(e != NULL);
|
||||
long timer_id = 0;
|
||||
AssertFatal(e, "cannot allocate memory for FlexRAN timer!\n");
|
||||
if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_ONESHOT) {
|
||||
ret = timer_setup(interval_sec,
|
||||
interval_usec,
|
||||
TASK_FLEXRAN_AGENT,
|
||||
instance,
|
||||
mod_id,
|
||||
TIMER_ONE_SHOT,
|
||||
timer_args,
|
||||
timer_id);
|
||||
&timer_id);
|
||||
|
||||
e->type = TIMER_ONE_SHOT;
|
||||
} else if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_PERIODIC ) {
|
||||
ret = timer_setup(interval_sec,
|
||||
interval_usec,
|
||||
TASK_FLEXRAN_AGENT,
|
||||
instance,
|
||||
mod_id,
|
||||
TIMER_PERIODIC,
|
||||
timer_args,
|
||||
timer_id);
|
||||
&timer_id);
|
||||
e->type = TIMER_PERIODIC;
|
||||
}
|
||||
|
||||
@@ -108,10 +108,10 @@ err_code_t flexran_agent_create_timer(uint32_t interval_sec,
|
||||
return TIMER_SETUP_FAILED;
|
||||
}
|
||||
|
||||
e->agent_id = agent_id;
|
||||
e->instance = instance;
|
||||
e->agent_id = mod_id;
|
||||
e->instance = mod_id;
|
||||
e->state = FLEXRAN_AGENT_TIMER_STATE_ACTIVE;
|
||||
e->timer_id = *timer_id;
|
||||
e->timer_id = timer_id;
|
||||
e->xid = xid;
|
||||
e->timer_args = timer_args;
|
||||
e->cb = cb;
|
||||
|
||||
@@ -89,17 +89,13 @@ typedef struct flexran_agent_timer_instance_s{
|
||||
|
||||
err_code_t flexran_agent_init_timer(void);
|
||||
|
||||
/* Create a timer for some agent related event with id xid. Will store the id
|
||||
of the generated timer in timer_id */
|
||||
err_code_t flexran_agent_create_timer(uint32_t interval_sec,
|
||||
uint32_t interval_usec,
|
||||
agent_id_t agent_id,
|
||||
instance_t instance,
|
||||
uint32_t timer_type,
|
||||
xid_t xid,
|
||||
flexran_agent_timer_callback_t cb,
|
||||
void* timer_args,
|
||||
long *timer_id);
|
||||
/* Create a timer for some agent related event with id xid. */
|
||||
err_code_t flexran_agent_create_timer(mid_t mod_id,
|
||||
uint32_t sf,
|
||||
uint32_t timer_type,
|
||||
xid_t xid,
|
||||
flexran_agent_timer_callback_t cb,
|
||||
void *timer_args);
|
||||
|
||||
/* Destroy all existing timers */
|
||||
err_code_t flexran_agent_destroy_timers(void);
|
||||
|
||||
Reference in New Issue
Block a user