Merge remote-tracking branch 'origin/flexran_agent_rrc_cm_rebased2' into develop_integration_2019_w27
This commit is contained in:
@@ -885,6 +885,7 @@ add_library(FLEXRAN_AGENT
|
||||
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.c
|
||||
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
|
||||
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
|
||||
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_internal.c
|
||||
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c
|
||||
${OPENAIR2_DIR}/ENB_APP/flexran_agent.c
|
||||
${OPENAIR2_DIR}/ENB_APP/flexran_agent_task_manager.c
|
||||
|
||||
@@ -39,6 +39,8 @@ MESSAGE_DEF(X2AP_REGISTER_ENB_CNF , MESSAGE_PRIORITY_MED, x2ap_reg
|
||||
MESSAGE_DEF(X2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, x2ap_deregistered_enb_ind_t , x2ap_deregistered_enb_ind)
|
||||
|
||||
/* handover messages X2AP <-> RRC */
|
||||
MESSAGE_DEF(X2AP_SETUP_REQ , MESSAGE_PRIORITY_MED, x2ap_setup_req_t , x2ap_setup_req)
|
||||
MESSAGE_DEF(X2AP_SETUP_RESP , MESSAGE_PRIORITY_MED, x2ap_setup_resp_t , x2ap_setup_resp)
|
||||
MESSAGE_DEF(X2AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, x2ap_handover_req_t , x2ap_handover_req)
|
||||
MESSAGE_DEF(X2AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_handover_req_ack_t , x2ap_handover_req_ack)
|
||||
MESSAGE_DEF(X2AP_HANDOVER_CANCEL , MESSAGE_PRIORITY_MED, x2ap_handover_cancel_t , x2ap_handover_cancel)
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
// Defines to access message fields.
|
||||
|
||||
#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req
|
||||
#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req
|
||||
#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp
|
||||
#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req
|
||||
#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack
|
||||
#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
|
||||
@@ -41,6 +43,16 @@
|
||||
|
||||
// eNB application layer -> X2AP messages
|
||||
|
||||
typedef struct x2ap_setup_req_s {
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
} x2ap_setup_req_t;
|
||||
|
||||
typedef struct x2ap_setup_resp_s {
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
} x2ap_setup_resp_t;
|
||||
|
||||
/* X2AP UE CONTEXT RELEASE */
|
||||
typedef struct x2ap_ue_context_release_s {
|
||||
/* used for X2AP->RRC in source and RRC->X2AP in target */
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file flexran_agent_mac.c
|
||||
/*! \file flexran_agent_rrc.c
|
||||
* \brief FlexRAN agent Control Module RRC
|
||||
* \author shahab SHARIAT BAGHERI
|
||||
* \date 2017
|
||||
@@ -130,6 +130,18 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) {
|
||||
free(msg->ue_state_change_msg->header);
|
||||
if (msg->ue_state_change_msg->config->capabilities)
|
||||
free(msg->ue_state_change_msg->config->capabilities);
|
||||
if (msg->ue_state_change_msg->config->info) {
|
||||
if (msg->ue_state_change_msg->config->info->cell_individual_offset) {
|
||||
free(msg->ue_state_change_msg->config->info->cell_individual_offset);
|
||||
}
|
||||
if (msg->ue_state_change_msg->config->info->event) {
|
||||
if (msg->ue_state_change_msg->config->info->event->a3) {
|
||||
free(msg->ue_state_change_msg->config->info->event->a3);
|
||||
}
|
||||
free(msg->ue_state_change_msg->config->info->event);
|
||||
}
|
||||
free(msg->ue_state_change_msg->config->info);
|
||||
}
|
||||
free(msg->ue_state_change_msg->config);
|
||||
free(msg->ue_state_change_msg);
|
||||
free(msg);
|
||||
@@ -381,7 +393,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
/* 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) {
|
||||
|
||||
/*Source Cell*/
|
||||
/*Source cell EUTRA Measurements*/
|
||||
Protocol__FlexRrcMeasurements *rrc_measurements;
|
||||
rrc_measurements = malloc(sizeof(Protocol__FlexRrcMeasurements));
|
||||
if (rrc_measurements == NULL)
|
||||
@@ -397,7 +409,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id, rnti);
|
||||
rrc_measurements->has_pcell_rsrq = 1 ;
|
||||
|
||||
/* Target Cell, Neghibouring*/
|
||||
/* Neighbouring cells EUTRA Measurements*/
|
||||
Protocol__FlexNeighCellsMeasurements *neigh_meas;
|
||||
neigh_meas = malloc(sizeof(Protocol__FlexNeighCellsMeasurements));
|
||||
if (neigh_meas == NULL) {
|
||||
@@ -406,14 +418,12 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
goto error;
|
||||
}
|
||||
protocol__flex_neigh_cells_measurements__init(neigh_meas);
|
||||
|
||||
|
||||
neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, rnti);
|
||||
|
||||
Protocol__FlexEutraMeasurements **eutra_meas = NULL;
|
||||
|
||||
if (neigh_meas->n_eutra_meas > 0){
|
||||
|
||||
if (neigh_meas->n_eutra_meas > 0) {
|
||||
eutra_meas = malloc(sizeof(Protocol__FlexEutraMeasurements) * neigh_meas->n_eutra_meas);
|
||||
if (eutra_meas == NULL) {
|
||||
free(neigh_meas);
|
||||
@@ -422,127 +432,138 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (int j = 0; j < neigh_meas->n_eutra_meas; j++ ){
|
||||
for (int j = 0; j < neigh_meas->n_eutra_meas; j++ ) {
|
||||
eutra_meas[j] = malloc(sizeof(Protocol__FlexEutraMeasurements));
|
||||
if (eutra_meas[j] == NULL) {
|
||||
for (int k = 0 ; k < j ; k++)
|
||||
free(eutra_meas[k]);
|
||||
free(eutra_meas);
|
||||
free(neigh_meas);
|
||||
free(rrc_measurements);
|
||||
rrc_measurements = NULL;
|
||||
goto error;
|
||||
}
|
||||
protocol__flex_eutra_measurements__init(eutra_meas[j]);
|
||||
|
||||
eutra_meas[j] = malloc(sizeof(Protocol__FlexEutraMeasurements));
|
||||
if (eutra_meas[j] == NULL) {
|
||||
for (int k = 0 ; k < j ; k++) {
|
||||
free(eutra_meas[k]);
|
||||
}
|
||||
free(eutra_meas);
|
||||
free(neigh_meas);
|
||||
free(rrc_measurements);
|
||||
rrc_measurements = NULL;
|
||||
goto error;
|
||||
}
|
||||
/* Fill in the physical cell identifier. */
|
||||
eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, rnti, j);
|
||||
eutra_meas[j]->has_phys_cell_id = 1;
|
||||
|
||||
protocol__flex_eutra_measurements__init(eutra_meas[j]);
|
||||
/* The following is not correctly implemented */
|
||||
//if (flexran_get_rrc_neigh_cgi(mod_id, rnti, j)) {
|
||||
// /* Initialize CGI measurements. */
|
||||
// Protocol__FlexEutraCgiMeasurements *cgi_meas;
|
||||
// cgi_meas = malloc(sizeof(Protocol__FlexEutraCgiMeasurements));
|
||||
|
||||
eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, rnti, j);
|
||||
eutra_meas[j]->has_phys_cell_id = 1;
|
||||
// if (cgi_meas) {
|
||||
// protocol__flex_eutra_cgi_measurements__init(cgi_meas);
|
||||
|
||||
// cgi_meas->tracking_area_code = flexran_get_rrc_neigh_cgi_tac(mod_id, rnti, j);
|
||||
// cgi_meas->has_tracking_area_code = 1;
|
||||
|
||||
/*TODO: Extend for CGI and PLMNID*/
|
||||
// /* EUTRA Cell Global Identity (CGI) */
|
||||
// Protocol__FlexCellGlobalEutraId *cgi;
|
||||
// cgi = malloc(sizeof(Protocol__FlexCellGlobalEutraId));
|
||||
|
||||
Protocol__FlexEutraRefSignalMeas *meas_result;
|
||||
meas_result = malloc(sizeof(Protocol__FlexEutraRefSignalMeas));
|
||||
// if (cgi) {
|
||||
// protocol__flex_cell_global_eutra_id__init(cgi);
|
||||
|
||||
protocol__flex_eutra_ref_signal_meas__init(meas_result);
|
||||
// cgi->cell_id = flexran_get_rrc_neigh_cgi_cell_id(mod_id, rnti, j);
|
||||
// cgi->has_cell_id = 1;
|
||||
|
||||
meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, rnti, eutra_meas[j]->phys_cell_id);
|
||||
// /* PLMN for neighbouring cell */
|
||||
// Protocol__FlexPlmnIdentity *plmn_id;
|
||||
// plmn_id = malloc(sizeof(Protocol__FlexPlmnIdentity));
|
||||
|
||||
// if (plmn_id) {
|
||||
// protocol__flex_plmn_identity__init(plmn_id);
|
||||
|
||||
// plmn_id->mcc = 0;
|
||||
// plmn_id->n_mcc = flexran_get_rrc_neigh_cgi_num_mcc(mod_id, rnti, j);
|
||||
|
||||
// for (int m = 0; m < plmn_id->n_mcc; m++) {
|
||||
// plmn_id->mcc += flexran_get_rrc_neigh_cgi_mcc(mod_id, rnti, j, m);
|
||||
// }
|
||||
|
||||
// plmn_id->mnc = 0;
|
||||
// plmn_id->n_mnc = flexran_get_rrc_neigh_cgi_num_mnc(mod_id, rnti, j);
|
||||
|
||||
// for (int m = 0; m < plmn_id->n_mnc; m++) {
|
||||
// plmn_id->mnc += flexran_get_rrc_neigh_cgi_mnc(mod_id, rnti, j, m);
|
||||
// }
|
||||
|
||||
// cgi->plmn_id = plmn_id;
|
||||
// }
|
||||
// cgi_meas->cgi = cgi;
|
||||
// }
|
||||
// eutra_meas[j]->cgi_meas = cgi_meas;
|
||||
// }
|
||||
//}
|
||||
|
||||
/*RSRP/RSRQ of the neighbouring cell */
|
||||
Protocol__FlexEutraRefSignalMeas *meas_result;
|
||||
meas_result = malloc(sizeof(Protocol__FlexEutraRefSignalMeas));
|
||||
|
||||
if (meas_result) {
|
||||
protocol__flex_eutra_ref_signal_meas__init(meas_result);
|
||||
|
||||
meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, rnti, j);
|
||||
meas_result->has_rsrp = 1;
|
||||
|
||||
meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, rnti, eutra_meas[j]->phys_cell_id);
|
||||
meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, rnti, j);
|
||||
meas_result->has_rsrq = 1;
|
||||
|
||||
eutra_meas[j]->meas_result = meas_result;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
neigh_meas->eutra_meas = eutra_meas;
|
||||
neigh_meas->eutra_meas = eutra_meas;
|
||||
|
||||
rrc_measurements->neigh_meas = neigh_meas;
|
||||
|
||||
rrc_measurements->neigh_meas = neigh_meas;
|
||||
} else {
|
||||
free(neigh_meas);
|
||||
}
|
||||
|
||||
ue_report[i]->rrc_measurements = rrc_measurements;
|
||||
ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS;
|
||||
|
||||
ue_report[i]->rrc_measurements = rrc_measurements;
|
||||
ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* To be considered for RRC signaling of cell*/
|
||||
// if (report_config->nr_cc > 0) {
|
||||
|
||||
|
||||
// // Fill in the Cell reports
|
||||
// for (i = 0; i < report_config->nr_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) {
|
||||
// // TODO: Fill in the actual noise and interference report for this cell
|
||||
// Protocol__FlexNoiseInterferenceReport *ni_report;
|
||||
// ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport));
|
||||
// if(ni_report == NULL)
|
||||
// goto error;
|
||||
// protocol__flex_noise_interference_report__init(ni_report);
|
||||
// // Current frame and subframe number
|
||||
// ni_report->sfn_sf = flexran_get_sfn_sf(enb_id);
|
||||
// ni_report->has_sfn_sf = 1;
|
||||
// //TODO:Received interference power in dbm
|
||||
// ni_report->rip = 0;
|
||||
// ni_report->has_rip = 1;
|
||||
// //TODO:Thermal noise power in dbm
|
||||
// ni_report->tnp = 0;
|
||||
// ni_report->has_tnp = 1;
|
||||
|
||||
// ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0);
|
||||
// ni_report->has_p0_nominal_pucch = 1;
|
||||
// cell_report[i]->noise_inter_report = ni_report;
|
||||
// cell_report[i]->flags |= PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// }
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
||||
for (int i = 0; i < report_config->nr_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]);
|
||||
}
|
||||
free(ue_report[i]->rrc_measurements->neigh_meas);
|
||||
for (int i = 0; i < report_config->nr_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]);
|
||||
}
|
||||
free(ue_report[i]->rrc_measurements->neigh_meas);
|
||||
}
|
||||
}
|
||||
|
||||
if (cell_report != NULL)
|
||||
free(cell_report);
|
||||
free(cell_report);
|
||||
if (ue_report != NULL)
|
||||
free(ue_report);
|
||||
|
||||
free(ue_report);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply)
|
||||
{
|
||||
for (int i = 0; i < reply->n_ue_report; i++){
|
||||
if (reply->ue_report[i]->rrc_measurements && reply->ue_report[i]->rrc_measurements->neigh_meas){
|
||||
for (int j = 0; j < reply->ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++){
|
||||
free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->meas_result);
|
||||
if (reply->ue_report[i]->rrc_measurements && reply->ue_report[i]->rrc_measurements->neigh_meas) {
|
||||
for (int j = 0; j < reply->ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++) {
|
||||
//if (reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas) {
|
||||
// if (reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas->cgi) {
|
||||
// if (reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas->plmn_id) {
|
||||
// free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas->cgi->plmn_id);
|
||||
// }
|
||||
// free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas->cgi);
|
||||
// }
|
||||
// free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas);
|
||||
//}
|
||||
if (reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->meas_result) {
|
||||
free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->meas_result);
|
||||
}
|
||||
free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]);
|
||||
}
|
||||
free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas);
|
||||
@@ -553,6 +574,79 @@ int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
/* 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];
|
||||
|
||||
/* 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) {
|
||||
|
||||
/* get number of rabs for this UE */
|
||||
const int num_e_rab = flexran_agent_rrc_gtp_num_e_rab(mod_id, rnti);
|
||||
Protocol__FlexGtpStats **gtp_stats = NULL;
|
||||
if (num_e_rab > 0) {
|
||||
gtp_stats = calloc(num_e_rab, sizeof(Protocol__FlexGtpStats *));
|
||||
if (!gtp_stats) goto error;
|
||||
for (int r = 0; r < num_e_rab; ++r) {
|
||||
gtp_stats[r] = malloc(sizeof(Protocol__FlexGtpStats));
|
||||
if (!gtp_stats[r]) goto error;
|
||||
protocol__flex_gtp_stats__init(gtp_stats[r]);
|
||||
gtp_stats[r]->e_rab_id = flexran_agent_rrc_gtp_get_e_rab_id(mod_id, rnti, r);
|
||||
gtp_stats[r]->has_e_rab_id = 1;
|
||||
gtp_stats[r]->teid_enb = flexran_agent_rrc_gtp_get_teid_enb(mod_id, rnti, r);
|
||||
gtp_stats[r]->has_teid_enb = 1;
|
||||
gtp_stats[r]->addr_enb = NULL;
|
||||
gtp_stats[r]->teid_sgw = flexran_agent_rrc_gtp_get_teid_sgw(mod_id, rnti, r);
|
||||
gtp_stats[r]->has_teid_sgw = 1;
|
||||
gtp_stats[r]->addr_sgw = NULL;
|
||||
}
|
||||
}
|
||||
ue_report[i]->n_gtp_stats = num_e_rab;
|
||||
ue_report[i]->gtp_stats = gtp_stats;
|
||||
ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_GTP_STATS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
for (int i = 0; i < report_config->nr_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]) {
|
||||
free(ue_report[i]->gtp_stats[r]);
|
||||
ue_report[i]->gtp_stats[r] = NULL;
|
||||
}
|
||||
}
|
||||
free(ue_report[i]->gtp_stats);
|
||||
ue_report[i]->gtp_stats = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_destroy_stats_reply(Protocol__FlexStatsReply *reply) {
|
||||
for (int i = 0; i < reply->n_ue_report; ++i) {
|
||||
if (!reply->ue_report[i]->n_gtp_stats == 0) continue;
|
||||
|
||||
for (int r = 0; r < reply->ue_report[i]->n_gtp_stats; ++r) {
|
||||
//if (reply->ue_report[i]->gtp_stats[r]->addr_enb)
|
||||
// free(reply->ue_report[i]->gtp_stats[r]->addr_enb);
|
||||
//if (reply->ue_report[i]->gtp_stats[r]->addr_sgw)
|
||||
// free(reply->ue_report[i]->gtp_stats[r]->addr_sgw);
|
||||
free(reply->ue_report[i]->gtp_stats[r]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void flexran_agent_fill_rrc_ue_config(mid_t mod_id, rnti_t rnti,
|
||||
Protocol__FlexUeConfig *ue_conf)
|
||||
{
|
||||
@@ -651,6 +745,76 @@ void flexran_agent_fill_rrc_ue_config(mid_t mod_id, rnti_t rnti,
|
||||
|
||||
ue_conf->has_extended_bsr_size = 1;
|
||||
ue_conf->extended_bsr_size = flexran_get_extended_bsr_size(mod_id, rnti);
|
||||
|
||||
Protocol__FlexMeasurementInfo *meas_info;
|
||||
meas_info = malloc(sizeof(Protocol__FlexMeasurementInfo));
|
||||
|
||||
if (meas_info) {
|
||||
protocol__flex_measurement_info__init(meas_info);
|
||||
|
||||
meas_info->has_offset_freq_serving = 1;
|
||||
meas_info->offset_freq_serving = flexran_get_rrc_ofp(mod_id, rnti);
|
||||
|
||||
meas_info->has_offset_freq_neighbouring = 1;
|
||||
meas_info->offset_freq_neighbouring = flexran_get_rrc_ofn(mod_id, rnti);
|
||||
|
||||
int num_adj_cells = flexran_get_rrc_num_adj_cells(mod_id);
|
||||
meas_info->n_cell_individual_offset = num_adj_cells + 1;
|
||||
|
||||
int64_t *cell_individual_offset;
|
||||
if (num_adj_cells > 0) {
|
||||
cell_individual_offset = malloc(sizeof(int64_t)*(num_adj_cells+1));
|
||||
if (cell_individual_offset) {
|
||||
cell_individual_offset[0] = flexran_get_rrc_ocp(mod_id, rnti);
|
||||
for (int i=0; i < num_adj_cells; i++) {
|
||||
cell_individual_offset[i+1] = flexran_get_rrc_ocn(mod_id, rnti,i);
|
||||
}
|
||||
meas_info->cell_individual_offset = cell_individual_offset;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cell_individual_offset = malloc(sizeof(int64_t));
|
||||
if (cell_individual_offset) {
|
||||
*cell_individual_offset = flexran_get_rrc_ocp(mod_id, rnti);
|
||||
meas_info->cell_individual_offset = cell_individual_offset;
|
||||
}
|
||||
}
|
||||
|
||||
meas_info->has_filter_coefficient_rsrp = 1;
|
||||
meas_info->filter_coefficient_rsrp = flexran_get_filter_coeff_rsrp(mod_id, rnti);
|
||||
|
||||
meas_info->has_filter_coefficient_rsrq = 1;
|
||||
meas_info->filter_coefficient_rsrq = flexran_get_filter_coeff_rsrq(mod_id, rnti);
|
||||
|
||||
Protocol__FlexMeasurementEvent *event;
|
||||
event = malloc(sizeof(Protocol__FlexMeasurementEvent));
|
||||
|
||||
if (event) {
|
||||
protocol__flex_measurement_event__init(event);
|
||||
Protocol__FlexA3Event *a3_event;
|
||||
a3_event = malloc(sizeof(Protocol__FlexA3Event));
|
||||
if (a3_event) {
|
||||
protocol__flex_a3_event__init(a3_event);
|
||||
a3_event->has_a3_offset = 1;
|
||||
a3_event->a3_offset = flexran_get_rrc_a3_event_a3_offset(mod_id, rnti);
|
||||
|
||||
a3_event->has_report_on_leave = 1;
|
||||
a3_event->report_on_leave = flexran_get_rrc_a3_event_reportOnLeave(mod_id, rnti);
|
||||
|
||||
a3_event->has_hysteresis = 1;
|
||||
a3_event->hysteresis = flexran_get_rrc_a3_event_hysteresis(mod_id, rnti);
|
||||
|
||||
a3_event->has_time_to_trigger = 1;
|
||||
a3_event->time_to_trigger = flexran_get_rrc_a3_event_timeToTrigger(mod_id, rnti);
|
||||
|
||||
a3_event->has_max_report_cells = 1;
|
||||
a3_event->max_report_cells = flexran_get_rrc_a3_event_maxReportCells(mod_id, rnti);
|
||||
event->a3 = a3_event;
|
||||
}
|
||||
meas_info->event = event;
|
||||
}
|
||||
ue_conf->info = meas_info;
|
||||
}
|
||||
}
|
||||
|
||||
int flexran_agent_register_rrc_xface(mid_t mod_id)
|
||||
@@ -742,6 +906,9 @@ void flexran_agent_fill_rrc_cell_config(mid_t mod_id, uint8_t cc_id,
|
||||
} else {
|
||||
conf->n_plmn_id = 0;
|
||||
}
|
||||
|
||||
conf->x2_ho_net_control = flexran_get_x2_ho_net_control(mod_id);
|
||||
conf->has_x2_ho_net_control = 1;
|
||||
}
|
||||
|
||||
int flexran_agent_unregister_rrc_xface(mid_t mod_id)
|
||||
|
||||
@@ -60,6 +60,11 @@ void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t *);
|
||||
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_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_destroy_stats_reply(Protocol__FlexStatsReply *reply);
|
||||
|
||||
/* Fill the RRC part of a ue_config message */
|
||||
void flexran_agent_fill_rrc_ue_config(mid_t mod_id, rnti_t rnti,
|
||||
Protocol__FlexUeConfig *ue_conf);
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "flexran_agent_rrc_internal.h"
|
||||
#include "flexran_agent_ran_api.h"
|
||||
|
||||
int update_rrc_reconfig(mid_t mod_id, rnti_t rnti, Protocol__FlexRrcTriggering *trigg) {
|
||||
|
||||
// Measurement info reconfiguration
|
||||
|
||||
if (trigg->meas_info) {
|
||||
|
||||
/* Set serving cell frequency offset */
|
||||
if (trigg->meas_info->has_offset_freq_serving) {
|
||||
if (flexran_set_rrc_ofp(mod_id, rnti, trigg->meas_info->offset_freq_serving) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Serving cell frequency offset\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set neighbouring cell frequency offset */
|
||||
if (trigg->meas_info->has_offset_freq_neighbouring) {
|
||||
if (flexran_set_rrc_ofn(mod_id, rnti, trigg->meas_info->offset_freq_neighbouring) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Neighbouring cell frequency offset\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (trigg->meas_info->n_cell_individual_offset > 0) {
|
||||
/* Set the serving cell offset */
|
||||
if (flexran_set_rrc_ocp(mod_id, rnti, trigg->meas_info->cell_individual_offset[0]) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Serving cell offset\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the neighbouring cell offset */
|
||||
for (int i=0; i<(trigg->meas_info->n_cell_individual_offset-1); i++) {
|
||||
if (flexran_set_rrc_ocn(mod_id, rnti, i, trigg->meas_info->cell_individual_offset[i+1]) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Neighbouring cell offset\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trigg->meas_info->has_offset_freq_neighbouring) {
|
||||
if (flexran_set_rrc_ofn(mod_id, rnti, trigg->meas_info->offset_freq_neighbouring) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Neighbouring cell frequency offset\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Set rsrp filter coefficient */
|
||||
if (trigg->meas_info->has_filter_coefficient_rsrp) {
|
||||
if (flexran_set_filter_coeff_rsrp(mod_id, rnti, trigg->meas_info->filter_coefficient_rsrp) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set RSRP filter coefficient\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set rsrq filter coefficient */
|
||||
if (trigg->meas_info->has_filter_coefficient_rsrq) {
|
||||
if (flexran_set_filter_coeff_rsrq(mod_id, rnti, trigg->meas_info->filter_coefficient_rsrq) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set RSRQ filter coefficient\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (trigg->meas_info->event) {
|
||||
|
||||
/* Set Periodic event parameters */
|
||||
if (trigg->meas_info->event->periodical) {
|
||||
|
||||
/* Set Periodic event maximum number of reported cells */
|
||||
if (trigg->meas_info->event->periodical->has_max_report_cells) {
|
||||
if (flexran_set_rrc_per_event_maxReportCells(mod_id, rnti, trigg->meas_info->event->periodical->max_report_cells) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Periodic event max\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set A3 event parameters */
|
||||
if (trigg->meas_info->event->a3) {
|
||||
|
||||
/* Set A3 event a3 offset */
|
||||
if (trigg->meas_info->event->a3->has_a3_offset) {
|
||||
if (flexran_set_rrc_a3_event_a3_offset(mod_id, rnti, trigg->meas_info->event->a3->a3_offset) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set A3 event offset\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set A3 event report on leave */
|
||||
if (trigg->meas_info->event->a3->has_report_on_leave) {
|
||||
if (flexran_set_rrc_a3_event_reportOnLeave(mod_id, rnti, trigg->meas_info->event->a3->report_on_leave) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set A3 event report on leave\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set A3 event hysteresis */
|
||||
if (trigg->meas_info->event->a3->has_hysteresis) {
|
||||
if (flexran_set_rrc_a3_event_hysteresis(mod_id, rnti, trigg->meas_info->event->a3->hysteresis) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set A3 event hysteresis\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set A3 event time to trigger */
|
||||
if (trigg->meas_info->event->a3->has_time_to_trigger) {
|
||||
if (flexran_set_rrc_a3_event_timeToTrigger(mod_id, rnti, trigg->meas_info->event->a3->time_to_trigger) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set A3 event time to trigger\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set A3 event maximum number of reported cells */
|
||||
if (trigg->meas_info->event->a3->has_max_report_cells) {
|
||||
if (flexran_set_rrc_a3_event_maxReportCells(mod_id, rnti, trigg->meas_info->event->a3->max_report_cells) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set A3 event max report cells\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef FLEXRAN_AGENT_RRC_INTERNAL_H_
|
||||
#define FLEXRAN_AGENT_RRC_INTERNAL_H_
|
||||
|
||||
#include "flexran_agent_rrc_internal.h"
|
||||
#include "flexran_agent_ran_api.h"
|
||||
|
||||
int update_rrc_reconfig(mid_t mod_id, rnti_t rnti, Protocol__FlexRrcTriggering *trigg);
|
||||
|
||||
#endif /*FLEXRAN_AGENT_RRC_INTERNAL_H_*/
|
||||
|
||||
@@ -268,3 +268,71 @@ message flex_plmn {
|
||||
optional uint32 mnc = 2;
|
||||
optional uint32 mnc_length = 3;
|
||||
}
|
||||
|
||||
//
|
||||
// UE-related RRC configuration
|
||||
|
||||
message flex_measurement_info {
|
||||
// arbitrary offset OFS, from TS
|
||||
optional int64 offset_freq_serving = 1;
|
||||
// arbitrary offset OFN
|
||||
optional int64 offset_freq_neighbouring = 2;
|
||||
// arbitrary offset OCS + OCN
|
||||
repeated int64 cell_individual_offset = 3;
|
||||
// Parameter k for exponential moving average calculation coefficient
|
||||
// a = 1/2^(k/4) of all measured RSRPs
|
||||
optional int64 filter_coefficient_rsrp = 4;
|
||||
// Parameter k for RSRQ filtering
|
||||
optional int64 filter_coefficient_rsrq = 5;
|
||||
optional flex_measurement_event event = 6;
|
||||
}
|
||||
|
||||
message flex_measurement_event {
|
||||
optional flex_per_event periodical = 1;
|
||||
optional flex_a1_event a1 = 2;
|
||||
optional flex_a2_event a2 = 3;
|
||||
optional flex_a3_event a3 = 4;
|
||||
optional flex_a4_event a4 = 5;
|
||||
optional flex_a5_event a5 = 6;
|
||||
}
|
||||
|
||||
message flex_per_event {
|
||||
optional int64 max_report_cells = 1;
|
||||
}
|
||||
|
||||
message flex_a1_event {
|
||||
optional int64 threshold_rsrp = 1;
|
||||
optional int64 hysteresis = 2;
|
||||
optional int64 time_to_trigger = 3;
|
||||
optional int64 max_report_cells = 4;
|
||||
}
|
||||
|
||||
message flex_a2_event {
|
||||
optional int64 threshold_rsrp = 1;
|
||||
optional int64 hysteresis = 2;
|
||||
optional int64 time_to_trigger = 3;
|
||||
optional int64 max_report_cells = 4;
|
||||
}
|
||||
|
||||
message flex_a3_event {
|
||||
optional int64 a3_offset = 1;
|
||||
optional int32 report_on_leave = 2;
|
||||
optional int64 hysteresis = 3;
|
||||
optional int64 time_to_trigger = 4;
|
||||
optional int64 max_report_cells = 5;
|
||||
}
|
||||
|
||||
message flex_a4_event {
|
||||
optional int64 threshold_rsrp = 1;
|
||||
optional int64 hysteresis = 2;
|
||||
optional int64 time_to_trigger = 3;
|
||||
optional int64 max_report_cells = 4;
|
||||
}
|
||||
|
||||
message flex_a5_event {
|
||||
optional int64 threshold_rsrp_1 = 1;
|
||||
optional int64 threshold_rsrp_2 = 2;
|
||||
optional int64 hysteresis = 3;
|
||||
optional int64 time_to_trigger = 4;
|
||||
optional int64 max_report_cells = 5;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ message flex_cell_config {
|
||||
repeated flex_plmn plmn_id = 40; // The PLMN cell id of this cell
|
||||
|
||||
optional flex_slice_config slice_config = 42;
|
||||
optional bool x2_ho_net_control = 43;
|
||||
}
|
||||
|
||||
message flex_slice_config {
|
||||
@@ -97,6 +98,8 @@ message flex_ue_config {
|
||||
optional uint64 imsi = 30;
|
||||
optional uint32 dl_slice_id = 31;
|
||||
optional uint32 ul_slice_id = 32;
|
||||
// Configuration about RRC measurements
|
||||
optional flex_measurement_info info = 33;
|
||||
}
|
||||
|
||||
message flex_lc_ue_config {
|
||||
|
||||
@@ -7,7 +7,7 @@ import "time_common.proto";
|
||||
import "config_messages.proto";
|
||||
import "controller_commands.proto";
|
||||
import "control_delegation.proto";
|
||||
|
||||
import "config_common.proto";
|
||||
|
||||
message flexran_message {
|
||||
optional flexran_direction msg_dir = 100;
|
||||
@@ -32,6 +32,7 @@ message flexran_message {
|
||||
flex_rrc_triggering rrc_triggering = 18;
|
||||
flex_ul_mac_config ul_mac_config_msg = 19;
|
||||
flex_disconnect disconnect_msg = 20;
|
||||
flex_ho_command ho_command_msg = 21;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +189,14 @@ message flex_ul_mac_config {
|
||||
message flex_rrc_triggering {
|
||||
|
||||
optional flex_header header = 1;
|
||||
optional string rrc_trigger = 2;
|
||||
optional string rrc_trigger = 2;
|
||||
optional flex_measurement_info meas_info = 3;
|
||||
}
|
||||
|
||||
message flex_ho_command {
|
||||
optional flex_header header = 1;
|
||||
optional uint32 rnti = 2;
|
||||
optional uint32 target_phy_cell_id = 3;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -34,6 +34,7 @@ enum flex_type {
|
||||
|
||||
//Controller command messages
|
||||
FLPT_DL_MAC_CONFIG = 13;
|
||||
FLPT_HO_COMMAND = 21;
|
||||
|
||||
// UE state change messages
|
||||
FLPT_UE_STATE_CHANGE = 14;
|
||||
|
||||
@@ -305,3 +305,15 @@ message flex_mac_sdus_dl {
|
||||
optional uint32 sdu_length = 1;
|
||||
optional uint32 lcid = 2;
|
||||
}
|
||||
|
||||
//
|
||||
// GTP stats
|
||||
//
|
||||
|
||||
message flex_gtp_stats {
|
||||
optional uint32 e_rab_id = 1;
|
||||
optional uint32 teid_enb = 2;
|
||||
optional string addr_enb = 3;
|
||||
optional uint32 teid_sgw = 4;
|
||||
optional string addr_sgw = 5;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ message flex_ue_stats_report {
|
||||
optional flex_rrc_measurements rrc_measurements = 10;
|
||||
optional flex_pdcp_stats pdcp_stats = 11;
|
||||
optional flex_mac_stats mac_stats = 12;
|
||||
repeated flex_gtp_stats gtp_stats = 13;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -89,6 +90,7 @@ enum flex_ue_stats_type {
|
||||
FLUST_MAC_STATS = 128;
|
||||
|
||||
FLUST_PDCP_STATS = 1024;
|
||||
FLUST_GTP_STATS = 2048;
|
||||
FLUST_RRC_MEASUREMENTS = 65536;
|
||||
// To be extended with more types of stats
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
//#include "PHY/extern.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "flexran_agent_mac_internal.h"
|
||||
#include "flexran_agent_rrc_internal.h"
|
||||
|
||||
//#include "SCHED/defs.h"
|
||||
#include "RRC/LTE/rrc_extern.h"
|
||||
@@ -804,27 +805,91 @@ error:
|
||||
}
|
||||
|
||||
|
||||
int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
|
||||
protocol_ctxt_t ctxt;
|
||||
int flexran_agent_rrc_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
|
||||
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;
|
||||
reconf_param->report_interval = 0;
|
||||
reconf_param->report_amount = 0;
|
||||
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);
|
||||
// Set the proper values using FlexRAN API (protected with mutex ?)
|
||||
if (!flexran_agent_get_rrc_xface(mod_id)) {
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): no RRC present, aborting\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int num_ue = flexran_get_rrc_num_ues(mod_id);
|
||||
if (num_ue == 0)
|
||||
return 0;
|
||||
|
||||
rnti_t rntis[num_ue];
|
||||
flexran_get_rrc_rnti_list(mod_id, rntis, num_ue);
|
||||
for (int i = 0; i < num_ue; i++) {
|
||||
const rnti_t rnti = rntis[i];
|
||||
const int error = update_rrc_reconfig(mod_id, rnti, triggering);
|
||||
if (error < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Error in updating user %d\n", i);
|
||||
continue;
|
||||
}
|
||||
// Call the proper wrapper in FlexRAN API
|
||||
if (flexran_call_rrc_reconfiguration (mod_id, rnti) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Error in reconfiguring user %d\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
*msg = NULL;
|
||||
free(reconf_param);
|
||||
reconf_param = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_trigger_handover(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
|
||||
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
|
||||
Protocol__FlexHoCommand *ho_command = input->ho_command_msg;
|
||||
|
||||
int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg) {
|
||||
int rnti_found = 0;
|
||||
|
||||
// Set the proper values using FlexRAN API (protected with mutex ?)
|
||||
if (!flexran_agent_get_rrc_xface(mod_id)) {
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): no RRC present, aborting\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int num_ue = flexran_get_rrc_num_ues(mod_id);
|
||||
if (num_ue == 0)
|
||||
return 0;
|
||||
|
||||
if (!ho_command->has_rnti) {
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): no UE rnti is present, aborting\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ho_command->has_target_phy_cell_id) {
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): no target physical cell id is present, aborting\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rnti_t rntis[num_ue];
|
||||
flexran_get_rrc_rnti_list(mod_id, rntis, num_ue);
|
||||
for (int i = 0; i < num_ue; i++) {
|
||||
const rnti_t rnti = rntis[i];
|
||||
if (ho_command->rnti == rnti) {
|
||||
rnti_found = 1;
|
||||
// Call the proper wrapper in FlexRAN API
|
||||
if (flexran_call_rrc_trigger_handover(mod_id, ho_command->rnti, ho_command->target_phy_cell_id) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Error in handovering user %d/RNTI %x\n", i, rnti);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rnti_found)
|
||||
return -1;
|
||||
|
||||
*msg = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_agent_destroy_rrc_reconfiguration(Protocol__FlexranMessage *msg) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_agent_destroy_rrc_trigger_handover(Protocol__FlexranMessage *msg) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
@@ -849,6 +914,12 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot
|
||||
// initiate_soft_restart(mod_id, enb_config->cell_config[0]);
|
||||
}
|
||||
|
||||
if (flexran_agent_get_rrc_xface(mod_id) && enb_config->cell_config[0]->has_x2_ho_net_control) {
|
||||
if (flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network");
|
||||
}
|
||||
}
|
||||
|
||||
*msg = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -137,9 +137,12 @@ int flexran_agent_reconfiguration(mid_t mod_id, const void *params, Protocol__Fl
|
||||
int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg);
|
||||
|
||||
/* rrc triggering measurement message constructor and destructor */
|
||||
int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg);
|
||||
int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg);
|
||||
int flexran_agent_rrc_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg);
|
||||
int flexran_agent_destroy_rrc_reconfiguration(Protocol__FlexranMessage *msg);
|
||||
|
||||
/* rrc triggering handover command message constructor and destructor */
|
||||
int flexran_agent_rrc_trigger_handover(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg);
|
||||
int flexran_agent_destroy_rrc_trigger_handover(Protocol__FlexranMessage *msg);
|
||||
|
||||
/* FlexRAN protocol message dispatcher function */
|
||||
Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id,
|
||||
|
||||
@@ -55,7 +55,10 @@ 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_rrc_reconfiguration, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_RRC_TRIGGERING_MSG*/
|
||||
{0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_MAC_CONFIG_MSG*/
|
||||
{0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_DISCONNECT_MSG*/
|
||||
{flexran_agent_rrc_trigger_handover, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_HO_COMMAND_MSG*/
|
||||
};
|
||||
|
||||
flexran_agent_message_destruction_callback message_destruction_callback[] = {
|
||||
@@ -508,7 +511,13 @@ int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *re
|
||||
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) {
|
||||
err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
|
||||
goto error;
|
||||
}
|
||||
|
||||
stats_reply_msg->cell_report = cell_report;
|
||||
stats_reply_msg->ue_report = ue_report;
|
||||
|
||||
|
||||
@@ -71,19 +71,10 @@ sub_frame_t flexran_get_current_subframe(mid_t mod_id)
|
||||
return RC.mac[mod_id]->subframe;
|
||||
}
|
||||
|
||||
/* Why uint16_t, frame_t and sub_frame_t are defined as uint32_t? */
|
||||
uint16_t flexran_get_sfn_sf(mid_t mod_id)
|
||||
uint32_t flexran_get_sfn_sf(mid_t mod_id)
|
||||
{
|
||||
if (!mac_is_present(mod_id)) return 0;
|
||||
frame_t frame = flexran_get_current_system_frame_num(mod_id);
|
||||
sub_frame_t subframe = flexran_get_current_subframe(mod_id);
|
||||
uint16_t sfn_sf, frame_mask, sf_mask;
|
||||
|
||||
frame_mask = (1 << 12) - 1;
|
||||
sf_mask = (1 << 4) - 1;
|
||||
sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4);
|
||||
|
||||
return sfn_sf;
|
||||
return flexran_get_current_frame(mod_id) * 10 + flexran_get_current_subframe(mod_id);
|
||||
}
|
||||
|
||||
uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time)
|
||||
@@ -1434,9 +1425,31 @@ uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, uint16_t uid, lcid_t lcid)
|
||||
}
|
||||
|
||||
/******************** RRC *****************************/
|
||||
/* RRC Wrappers */
|
||||
int flexran_call_rrc_reconfiguration (mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
protocol_ctxt_t ctxt;
|
||||
memset(&ctxt, 0, sizeof(ctxt));
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti)
|
||||
{
|
||||
int flexran_call_rrc_trigger_handover (mid_t mod_id, rnti_t rnti, int target_cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
protocol_ctxt_t ctxt;
|
||||
memset(&ctxt, 0, sizeof(ctxt));
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
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);
|
||||
return flexran_rrc_eNB_trigger_handover(mod_id, &ctxt, ue_context_p, target_cell_id);
|
||||
}
|
||||
|
||||
/* RRC Getters */
|
||||
|
||||
LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
@@ -1444,97 +1457,687 @@ LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti)
|
||||
return ue_context_p->ue_context.measResults->measId;
|
||||
}
|
||||
|
||||
float flexran_get_rrc_pcell_rsrp(mid_t mod_id, rnti_t rnti)
|
||||
{
|
||||
float flexran_get_rrc_pcell_rsrp(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measResults) return -1;
|
||||
return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult];
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
|
||||
return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult];
|
||||
#else
|
||||
return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultServCell.rsrpResult];
|
||||
#endif
|
||||
}
|
||||
|
||||
float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti)
|
||||
{
|
||||
float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measResults) return -1;
|
||||
return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult];
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
|
||||
return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult];
|
||||
#else
|
||||
return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultServCell.rsrqResult];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Number of neighbouring cells for specific UE*/
|
||||
int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti)
|
||||
{
|
||||
int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
if (!ue_context_p->ue_context.measResults) return 0;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0;
|
||||
if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0;
|
||||
//if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0;
|
||||
return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count;
|
||||
}
|
||||
|
||||
long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id)
|
||||
{
|
||||
long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measResults) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
|
||||
if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
//if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1;
|
||||
return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId;
|
||||
}
|
||||
|
||||
float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id)
|
||||
{
|
||||
int flexran_get_rrc_neigh_cgi(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
if (!ue_context_p->ue_context.measResults) return 0;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0;
|
||||
//if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return 0;
|
||||
return (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info)?0:1;
|
||||
}
|
||||
|
||||
uint32_t flexran_get_rrc_neigh_cgi_cell_id(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
uint8_t *cId = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.cellIdentity.buf;
|
||||
return ((cId[0] << 20) + (cId[1] << 12) + (cId[2] << 4) + (cId[3] >> 4));
|
||||
}
|
||||
|
||||
uint32_t flexran_get_rrc_neigh_cgi_tac(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
uint8_t *tac = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->trackingAreaCode.buf;
|
||||
return (tac[0] << 8) + (tac[1]);
|
||||
}
|
||||
|
||||
int flexran_get_rrc_neigh_cgi_num_mnc(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.count;
|
||||
}
|
||||
|
||||
int flexran_get_rrc_neigh_cgi_num_mcc(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.count;
|
||||
}
|
||||
|
||||
uint32_t flexran_get_rrc_neigh_cgi_mnc(mid_t mod_id, rnti_t rnti, long cell_id, int mnc_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
int num_mnc = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.count;
|
||||
return *(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.array[mnc_id]) *
|
||||
((uint32_t) pow(10, num_mnc - mnc_id - 1));
|
||||
}
|
||||
|
||||
uint32_t flexran_get_rrc_neigh_cgi_mcc(mid_t mod_id, rnti_t rnti, long cell_id, int mcc_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
int num_mcc = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.count;
|
||||
return *(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.array[mcc_id]) *
|
||||
((uint32_t) pow(10, num_mcc - mcc_id - 1));
|
||||
}
|
||||
|
||||
float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measResults) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
|
||||
if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
//if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult) return 0;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult) return -1;
|
||||
return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)];
|
||||
}
|
||||
|
||||
float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id)
|
||||
{
|
||||
float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measResults) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
|
||||
if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return 0;
|
||||
//if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return -1;
|
||||
return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)];
|
||||
}
|
||||
|
||||
uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id)
|
||||
{
|
||||
/* Measurement offsets */
|
||||
|
||||
long flexran_get_rrc_ofp(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->offsetFreq;
|
||||
}
|
||||
|
||||
long flexran_get_rrc_ofn(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->offsetFreq;
|
||||
}
|
||||
|
||||
long flexran_get_rrc_ocp(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
switch (ue_context_p->ue_context.measurement_info->cellIndividualOffset[0]) {
|
||||
case LTE_Q_OffsetRange_dB_24: return -24;
|
||||
case LTE_Q_OffsetRange_dB_22: return -22;
|
||||
case LTE_Q_OffsetRange_dB_20: return -20;
|
||||
case LTE_Q_OffsetRange_dB_18: return -18;
|
||||
case LTE_Q_OffsetRange_dB_16: return -16;
|
||||
case LTE_Q_OffsetRange_dB_14: return -14;
|
||||
case LTE_Q_OffsetRange_dB_12: return -12;
|
||||
case LTE_Q_OffsetRange_dB_10: return -10;
|
||||
case LTE_Q_OffsetRange_dB_8: return -8;
|
||||
case LTE_Q_OffsetRange_dB_6: return -6;
|
||||
case LTE_Q_OffsetRange_dB_5: return -5;
|
||||
case LTE_Q_OffsetRange_dB_4: return -4;
|
||||
case LTE_Q_OffsetRange_dB_3: return -3;
|
||||
case LTE_Q_OffsetRange_dB_2: return -2;
|
||||
case LTE_Q_OffsetRange_dB_1: return -1;
|
||||
case LTE_Q_OffsetRange_dB0: return 0;
|
||||
case LTE_Q_OffsetRange_dB1: return 1;
|
||||
case LTE_Q_OffsetRange_dB2: return 2;
|
||||
case LTE_Q_OffsetRange_dB3: return 3;
|
||||
case LTE_Q_OffsetRange_dB4: return 4;
|
||||
case LTE_Q_OffsetRange_dB5: return 5;
|
||||
case LTE_Q_OffsetRange_dB6: return 6;
|
||||
case LTE_Q_OffsetRange_dB8: return 8;
|
||||
case LTE_Q_OffsetRange_dB10: return 10;
|
||||
case LTE_Q_OffsetRange_dB12: return 12;
|
||||
case LTE_Q_OffsetRange_dB14: return 14;
|
||||
case LTE_Q_OffsetRange_dB16: return 16;
|
||||
case LTE_Q_OffsetRange_dB18: return 18;
|
||||
case LTE_Q_OffsetRange_dB20: return 20;
|
||||
case LTE_Q_OffsetRange_dB22: return 22;
|
||||
case LTE_Q_OffsetRange_dB24: return 24;
|
||||
default: return -99;
|
||||
}
|
||||
}
|
||||
|
||||
long flexran_get_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
switch (ue_context_p->ue_context.measurement_info->cellIndividualOffset[cell_id+1]) {
|
||||
case LTE_Q_OffsetRange_dB_24: return -24;
|
||||
case LTE_Q_OffsetRange_dB_22: return -22;
|
||||
case LTE_Q_OffsetRange_dB_20: return -20;
|
||||
case LTE_Q_OffsetRange_dB_18: return -18;
|
||||
case LTE_Q_OffsetRange_dB_16: return -16;
|
||||
case LTE_Q_OffsetRange_dB_14: return -14;
|
||||
case LTE_Q_OffsetRange_dB_12: return -12;
|
||||
case LTE_Q_OffsetRange_dB_10: return -10;
|
||||
case LTE_Q_OffsetRange_dB_8: return -8;
|
||||
case LTE_Q_OffsetRange_dB_6: return -6;
|
||||
case LTE_Q_OffsetRange_dB_5: return -5;
|
||||
case LTE_Q_OffsetRange_dB_4: return -4;
|
||||
case LTE_Q_OffsetRange_dB_3: return -3;
|
||||
case LTE_Q_OffsetRange_dB_2: return -2;
|
||||
case LTE_Q_OffsetRange_dB_1: return -1;
|
||||
case LTE_Q_OffsetRange_dB0: return 0;
|
||||
case LTE_Q_OffsetRange_dB1: return 1;
|
||||
case LTE_Q_OffsetRange_dB2: return 2;
|
||||
case LTE_Q_OffsetRange_dB3: return 3;
|
||||
case LTE_Q_OffsetRange_dB4: return 4;
|
||||
case LTE_Q_OffsetRange_dB5: return 5;
|
||||
case LTE_Q_OffsetRange_dB6: return 6;
|
||||
case LTE_Q_OffsetRange_dB8: return 8;
|
||||
case LTE_Q_OffsetRange_dB10: return 10;
|
||||
case LTE_Q_OffsetRange_dB12: return 12;
|
||||
case LTE_Q_OffsetRange_dB14: return 14;
|
||||
case LTE_Q_OffsetRange_dB16: return 16;
|
||||
case LTE_Q_OffsetRange_dB18: return 18;
|
||||
case LTE_Q_OffsetRange_dB20: return 20;
|
||||
case LTE_Q_OffsetRange_dB22: return 22;
|
||||
case LTE_Q_OffsetRange_dB24: return 24;
|
||||
default: return -99;
|
||||
}
|
||||
}
|
||||
|
||||
long flexran_get_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
switch (ue_context_p->ue_context.measurement_info->filterCoefficientRSRP) {
|
||||
case LTE_FilterCoefficient_fc0: return 0;
|
||||
case LTE_FilterCoefficient_fc1: return 1;
|
||||
case LTE_FilterCoefficient_fc2: return 2;
|
||||
case LTE_FilterCoefficient_fc3: return 3;
|
||||
case LTE_FilterCoefficient_fc4: return 4;
|
||||
case LTE_FilterCoefficient_fc5: return 5;
|
||||
case LTE_FilterCoefficient_fc6: return 6;
|
||||
case LTE_FilterCoefficient_fc7: return 7;
|
||||
case LTE_FilterCoefficient_fc8: return 8;
|
||||
case LTE_FilterCoefficient_fc9: return 9;
|
||||
case LTE_FilterCoefficient_fc11: return 11;
|
||||
case LTE_FilterCoefficient_fc13: return 13;
|
||||
case LTE_FilterCoefficient_fc15: return 15;
|
||||
case LTE_FilterCoefficient_fc17: return 17;
|
||||
case LTE_FilterCoefficient_fc19: return 19;
|
||||
case LTE_FilterCoefficient_spare1: return -1; /* spare means no coefficient */
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long flexran_get_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
switch (ue_context_p->ue_context.measurement_info->filterCoefficientRSRQ) {
|
||||
case LTE_FilterCoefficient_fc0: return 0;
|
||||
case LTE_FilterCoefficient_fc1: return 1;
|
||||
case LTE_FilterCoefficient_fc2: return 2;
|
||||
case LTE_FilterCoefficient_fc3: return 3;
|
||||
case LTE_FilterCoefficient_fc4: return 4;
|
||||
case LTE_FilterCoefficient_fc5: return 5;
|
||||
case LTE_FilterCoefficient_fc6: return 6;
|
||||
case LTE_FilterCoefficient_fc7: return 7;
|
||||
case LTE_FilterCoefficient_fc8: return 8;
|
||||
case LTE_FilterCoefficient_fc9: return 9;
|
||||
case LTE_FilterCoefficient_fc11: return 11;
|
||||
case LTE_FilterCoefficient_fc13: return 13;
|
||||
case LTE_FilterCoefficient_fc15: return 15;
|
||||
case LTE_FilterCoefficient_fc17: return 17;
|
||||
case LTE_FilterCoefficient_fc19: return 19;
|
||||
case LTE_FilterCoefficient_spare1: return -1; /* spare means no coefficient */
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Periodic event */
|
||||
|
||||
long flexran_get_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->per_event) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->events->per_event->maxReportCells;
|
||||
}
|
||||
|
||||
/* A3 event */
|
||||
|
||||
long flexran_get_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->events->a3_event->hysteresis;
|
||||
}
|
||||
|
||||
long flexran_get_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
switch (ue_context_p->ue_context.measurement_info->events->a3_event->timeToTrigger) {
|
||||
case LTE_TimeToTrigger_ms0: return 0;
|
||||
case LTE_TimeToTrigger_ms40: return 40;
|
||||
case LTE_TimeToTrigger_ms64: return 64;
|
||||
case LTE_TimeToTrigger_ms80: return 80;
|
||||
case LTE_TimeToTrigger_ms100: return 100;
|
||||
case LTE_TimeToTrigger_ms128: return 128;
|
||||
case LTE_TimeToTrigger_ms160: return 160;
|
||||
case LTE_TimeToTrigger_ms256: return 256;
|
||||
case LTE_TimeToTrigger_ms320: return 320;
|
||||
case LTE_TimeToTrigger_ms480: return 480;
|
||||
case LTE_TimeToTrigger_ms512: return 512;
|
||||
case LTE_TimeToTrigger_ms640: return 640;
|
||||
case LTE_TimeToTrigger_ms1024: return 1024;
|
||||
case LTE_TimeToTrigger_ms1280: return 1280;
|
||||
case LTE_TimeToTrigger_ms2560: return 2560;
|
||||
case LTE_TimeToTrigger_ms5120: return 5120;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long flexran_get_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->events->a3_event->maxReportCells;
|
||||
}
|
||||
|
||||
long flexran_get_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->events->a3_event->a3_offset;
|
||||
}
|
||||
|
||||
int flexran_get_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->events->a3_event->reportOnLeave;
|
||||
}
|
||||
|
||||
/* RRC Setters */
|
||||
|
||||
/* Measurement offsets */
|
||||
|
||||
int flexran_set_rrc_ofp(mid_t mod_id, rnti_t rnti, long offsetFreq) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!((offsetFreq >= -15) && (offsetFreq <= 15))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->offsetFreq = offsetFreq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_ofn(mid_t mod_id, rnti_t rnti, long offsetFreq) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!((offsetFreq >= -15) && (offsetFreq <= 15))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->offsetFreq = offsetFreq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_ocp(mid_t mod_id, rnti_t rnti, long cellIndividualOffset) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
LTE_Q_OffsetRange_t *cio = &ue_context_p->ue_context.measurement_info->cellIndividualOffset[0];
|
||||
switch (cellIndividualOffset) {
|
||||
case -24: *cio = LTE_Q_OffsetRange_dB_24; break;
|
||||
case -22: *cio = LTE_Q_OffsetRange_dB_22; break;
|
||||
case -20: *cio = LTE_Q_OffsetRange_dB_20; break;
|
||||
case -18: *cio = LTE_Q_OffsetRange_dB_18; break;
|
||||
case -16: *cio = LTE_Q_OffsetRange_dB_16; break;
|
||||
case -14: *cio = LTE_Q_OffsetRange_dB_14; break;
|
||||
case -12: *cio = LTE_Q_OffsetRange_dB_12; break;
|
||||
case -10: *cio = LTE_Q_OffsetRange_dB_10; break;
|
||||
case -8: *cio = LTE_Q_OffsetRange_dB_8; break;
|
||||
case -6: *cio = LTE_Q_OffsetRange_dB_6; break;
|
||||
case -5: *cio = LTE_Q_OffsetRange_dB_5; break;
|
||||
case -4: *cio = LTE_Q_OffsetRange_dB_4; break;
|
||||
case -3: *cio = LTE_Q_OffsetRange_dB_3; break;
|
||||
case -2: *cio = LTE_Q_OffsetRange_dB_2; break;
|
||||
case -1: *cio = LTE_Q_OffsetRange_dB_1; break;
|
||||
case 0: *cio = LTE_Q_OffsetRange_dB0; break;
|
||||
case 1: *cio = LTE_Q_OffsetRange_dB1; break;
|
||||
case 2: *cio = LTE_Q_OffsetRange_dB2; break;
|
||||
case 3: *cio = LTE_Q_OffsetRange_dB3; break;
|
||||
case 4: *cio = LTE_Q_OffsetRange_dB4; break;
|
||||
case 5: *cio = LTE_Q_OffsetRange_dB5; break;
|
||||
case 6: *cio = LTE_Q_OffsetRange_dB6; break;
|
||||
case 8: *cio = LTE_Q_OffsetRange_dB8; break;
|
||||
case 10: *cio = LTE_Q_OffsetRange_dB10; break;
|
||||
case 12: *cio = LTE_Q_OffsetRange_dB12; break;
|
||||
case 14: *cio = LTE_Q_OffsetRange_dB14; break;
|
||||
case 16: *cio = LTE_Q_OffsetRange_dB16; break;
|
||||
case 18: *cio = LTE_Q_OffsetRange_dB18; break;
|
||||
case 20: *cio = LTE_Q_OffsetRange_dB20; break;
|
||||
case 22: *cio = LTE_Q_OffsetRange_dB22; break;
|
||||
case 24: *cio = LTE_Q_OffsetRange_dB24; break;
|
||||
default: return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id, long cellIndividualOffset) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
LTE_Q_OffsetRange_t *cio = &ue_context_p->ue_context.measurement_info->cellIndividualOffset[cell_id+1];
|
||||
switch (cellIndividualOffset) {
|
||||
case -24: *cio = LTE_Q_OffsetRange_dB_24; break;
|
||||
case -22: *cio = LTE_Q_OffsetRange_dB_22; break;
|
||||
case -20: *cio = LTE_Q_OffsetRange_dB_20; break;
|
||||
case -18: *cio = LTE_Q_OffsetRange_dB_18; break;
|
||||
case -16: *cio = LTE_Q_OffsetRange_dB_16; break;
|
||||
case -14: *cio = LTE_Q_OffsetRange_dB_14; break;
|
||||
case -12: *cio = LTE_Q_OffsetRange_dB_12; break;
|
||||
case -10: *cio = LTE_Q_OffsetRange_dB_10; break;
|
||||
case -8: *cio = LTE_Q_OffsetRange_dB_8; break;
|
||||
case -6: *cio = LTE_Q_OffsetRange_dB_6; break;
|
||||
case -5: *cio = LTE_Q_OffsetRange_dB_5; break;
|
||||
case -4: *cio = LTE_Q_OffsetRange_dB_4; break;
|
||||
case -3: *cio = LTE_Q_OffsetRange_dB_3; break;
|
||||
case -2: *cio = LTE_Q_OffsetRange_dB_2; break;
|
||||
case -1: *cio = LTE_Q_OffsetRange_dB_1; break;
|
||||
case 0: *cio = LTE_Q_OffsetRange_dB0; break;
|
||||
case 1: *cio = LTE_Q_OffsetRange_dB1; break;
|
||||
case 2: *cio = LTE_Q_OffsetRange_dB2; break;
|
||||
case 3: *cio = LTE_Q_OffsetRange_dB3; break;
|
||||
case 4: *cio = LTE_Q_OffsetRange_dB4; break;
|
||||
case 5: *cio = LTE_Q_OffsetRange_dB5; break;
|
||||
case 6: *cio = LTE_Q_OffsetRange_dB6; break;
|
||||
case 8: *cio = LTE_Q_OffsetRange_dB8; break;
|
||||
case 10: *cio = LTE_Q_OffsetRange_dB10; break;
|
||||
case 12: *cio = LTE_Q_OffsetRange_dB12; break;
|
||||
case 14: *cio = LTE_Q_OffsetRange_dB14; break;
|
||||
case 16: *cio = LTE_Q_OffsetRange_dB16; break;
|
||||
case 18: *cio = LTE_Q_OffsetRange_dB18; break;
|
||||
case 20: *cio = LTE_Q_OffsetRange_dB20; break;
|
||||
case 22: *cio = LTE_Q_OffsetRange_dB22; break;
|
||||
case 24: *cio = LTE_Q_OffsetRange_dB24; break;
|
||||
default: return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRP) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
LTE_FilterCoefficient_t *fc = &ue_context_p->ue_context.measurement_info->filterCoefficientRSRP;
|
||||
switch (filterCoefficientRSRP) {
|
||||
case 0: *fc = LTE_FilterCoefficient_fc0; break;
|
||||
case 1: *fc = LTE_FilterCoefficient_fc1; break;
|
||||
case 2: *fc = LTE_FilterCoefficient_fc2; break;
|
||||
case 3: *fc = LTE_FilterCoefficient_fc3; break;
|
||||
case 4: *fc = LTE_FilterCoefficient_fc4; break;
|
||||
case 5: *fc = LTE_FilterCoefficient_fc5; break;
|
||||
case 6: *fc = LTE_FilterCoefficient_fc6; break;
|
||||
case 7: *fc = LTE_FilterCoefficient_fc7; break;
|
||||
case 8: *fc = LTE_FilterCoefficient_fc8; break;
|
||||
case 9: *fc = LTE_FilterCoefficient_fc9; break;
|
||||
case 11: *fc = LTE_FilterCoefficient_fc11; break;
|
||||
case 13: *fc = LTE_FilterCoefficient_fc13; break;
|
||||
case 15: *fc = LTE_FilterCoefficient_fc15; break;
|
||||
case 17: *fc = LTE_FilterCoefficient_fc17; break;
|
||||
case 19: *fc = LTE_FilterCoefficient_fc19; break;
|
||||
case -1: *fc = LTE_FilterCoefficient_spare1; break;
|
||||
default: return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRQ) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
LTE_FilterCoefficient_t *fc = &ue_context_p->ue_context.measurement_info->filterCoefficientRSRQ;
|
||||
switch (filterCoefficientRSRQ) {
|
||||
case 0: *fc = LTE_FilterCoefficient_fc0; break;
|
||||
case 1: *fc = LTE_FilterCoefficient_fc1; break;
|
||||
case 2: *fc = LTE_FilterCoefficient_fc2; break;
|
||||
case 3: *fc = LTE_FilterCoefficient_fc3; break;
|
||||
case 4: *fc = LTE_FilterCoefficient_fc4; break;
|
||||
case 5: *fc = LTE_FilterCoefficient_fc5; break;
|
||||
case 6: *fc = LTE_FilterCoefficient_fc6; break;
|
||||
case 7: *fc = LTE_FilterCoefficient_fc7; break;
|
||||
case 8: *fc = LTE_FilterCoefficient_fc8; break;
|
||||
case 9: *fc = LTE_FilterCoefficient_fc9; break;
|
||||
case 11: *fc = LTE_FilterCoefficient_fc11; break;
|
||||
case 13: *fc = LTE_FilterCoefficient_fc13; break;
|
||||
case 15: *fc = LTE_FilterCoefficient_fc15; break;
|
||||
case 17: *fc = LTE_FilterCoefficient_fc17; break;
|
||||
case 19: *fc = LTE_FilterCoefficient_fc19; break;
|
||||
case -1: *fc = LTE_FilterCoefficient_spare1; break;
|
||||
default: return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Periodic event */
|
||||
|
||||
int flexran_set_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->per_event) return -1;
|
||||
if (!((maxReportCells >= 1) && (maxReportCells <= 8))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->events->per_event->maxReportCells = maxReportCells;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* A3 event */
|
||||
|
||||
int flexran_set_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti, long hysteresis) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
if (!((hysteresis >=0) && (hysteresis <= 30))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->events->a3_event->hysteresis = hysteresis;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti, long timeToTrigger) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
LTE_TimeToTrigger_t *ttt = &ue_context_p->ue_context.measurement_info->events->a3_event->timeToTrigger;
|
||||
switch (timeToTrigger) {
|
||||
case 0: *ttt = LTE_TimeToTrigger_ms0; break;
|
||||
case 40: *ttt = LTE_TimeToTrigger_ms40; break;
|
||||
case 64: *ttt = LTE_TimeToTrigger_ms64; break;
|
||||
case 80: *ttt = LTE_TimeToTrigger_ms80; break;
|
||||
case 100: *ttt = LTE_TimeToTrigger_ms100; break;
|
||||
case 128: *ttt = LTE_TimeToTrigger_ms128; break;
|
||||
case 160: *ttt = LTE_TimeToTrigger_ms160; break;
|
||||
case 256: *ttt = LTE_TimeToTrigger_ms256; break;
|
||||
case 320: *ttt = LTE_TimeToTrigger_ms320; break;
|
||||
case 480: *ttt = LTE_TimeToTrigger_ms480; break;
|
||||
case 512: *ttt = LTE_TimeToTrigger_ms512; break;
|
||||
case 640: *ttt = LTE_TimeToTrigger_ms640; break;
|
||||
case 1024: *ttt = LTE_TimeToTrigger_ms1024; break;
|
||||
case 1280: *ttt = LTE_TimeToTrigger_ms1280; break;
|
||||
case 2560: *ttt = LTE_TimeToTrigger_ms2560; break;
|
||||
case 5120: *ttt = LTE_TimeToTrigger_ms5120; break;
|
||||
default: return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
if (!((maxReportCells >= 1) && (maxReportCells <= 8))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->events->a3_event->maxReportCells = maxReportCells;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti, long a3_offset) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
if (!((a3_offset >= -30) && (a3_offset <= 30))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->events->a3_event->a3_offset = a3_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti, int reportOnLeave) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
if (!((reportOnLeave == 0) || (reportOnLeave == 1))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->events->a3_event->reportOnLeave = reportOnLeave;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_x2_ho_net_control(mid_t mod_id, int x2_ho_net_control) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
if (!((x2_ho_net_control == 0) || (x2_ho_net_control == 1))) return -1;
|
||||
RC.rrc[mod_id]->x2_ho_net_control = x2_ho_net_control;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_get_x2_ho_net_control(mid_t mod_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
return RC.rrc[mod_id]->x2_ho_net_control;
|
||||
}
|
||||
|
||||
uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
return RC.rrc[mod_id]->configuration.num_plmn;
|
||||
}
|
||||
|
||||
uint16_t flexran_get_rrc_mcc(mid_t mod_id, uint8_t index)
|
||||
{
|
||||
uint16_t flexran_get_rrc_mcc(mid_t mod_id, uint8_t index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
return RC.rrc[mod_id]->configuration.mcc[index];
|
||||
}
|
||||
|
||||
uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index)
|
||||
{
|
||||
uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
return RC.rrc[mod_id]->configuration.mnc[index];
|
||||
}
|
||||
|
||||
uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index)
|
||||
{
|
||||
uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
return RC.rrc[mod_id]->configuration.mnc_digit_length[index];
|
||||
}
|
||||
|
||||
int flexran_get_rrc_num_adj_cells(mid_t mod_id) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
return RC.rrc[mod_id]->num_neigh_cells;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_num_e_rab(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
return ue_context_p->ue_context.setup_e_rabs;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_get_e_rab_id(mid_t mod_id, rnti_t rnti, int index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
return ue_context_p->ue_context.e_rab[index].param.e_rab_id;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_get_teid_enb(mid_t mod_id, rnti_t rnti, int index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
return ue_context_p->ue_context.enb_gtp_teid[index];
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
return ue_context_p->ue_context.e_rab[index].param.gtp_teid;
|
||||
}
|
||||
|
||||
/**************************** SLICING ****************************/
|
||||
int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id)
|
||||
{
|
||||
|
||||
@@ -63,7 +63,7 @@ sub_frame_t flexran_get_current_subframe(mid_t mod_id);
|
||||
|
||||
/*Return the frame and subframe number in compact 16-bit format.
|
||||
Bits 0-3 subframe, rest for frame. Required by FlexRAN protocol*/
|
||||
uint16_t flexran_get_sfn_sf(mid_t mod_id);
|
||||
uint32_t flexran_get_sfn_sf(mid_t mod_id);
|
||||
|
||||
/* Return a future frame and subframe number that is ahead_of_time
|
||||
subframes later in compact 16-bit format. Bits 0-3 subframe,
|
||||
@@ -498,6 +498,12 @@ uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid);
|
||||
uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, uint16_t uid, lcid_t lcid);
|
||||
|
||||
/*********************RRC**********************/
|
||||
/* Call RRC Reconfiguration wrapper function */
|
||||
int flexran_call_rrc_reconfiguration (mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Call RRC to trigger handover wrapper function */
|
||||
int flexran_call_rrc_trigger_handover (mid_t mod_id, rnti_t rnti, int target_cell_id);
|
||||
|
||||
/*Get primary cell measuremeant id flexRAN*/
|
||||
LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
@@ -510,22 +516,107 @@ float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti);
|
||||
/* Get RRC neighbouring measurement */
|
||||
int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get physical cell id */
|
||||
/* Get neighbouring physical cell id */
|
||||
long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get neighbouring cgi */
|
||||
int flexran_get_rrc_neigh_cgi(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get neighbouring cgi info cell id */
|
||||
uint32_t flexran_get_rrc_neigh_cgi_cell_id(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get neighbouring cgi info tac */
|
||||
uint32_t flexran_get_rrc_neigh_cgi_tac(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get the number of neighbouring cgi mnc */
|
||||
int flexran_get_rrc_neigh_cgi_num_mnc(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get the number of neighbouring cgi mcc */
|
||||
int flexran_get_rrc_neigh_cgi_num_mcc(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get neighbouring cgi mnc */
|
||||
uint32_t flexran_get_rrc_neigh_cgi_mnc(mid_t mod_id, rnti_t rnti, long cell_id, int mnc_id);
|
||||
|
||||
/* Get neighbouring cgi mcc */
|
||||
uint32_t flexran_get_rrc_neigh_cgi_mcc(mid_t mod_id, rnti_t rnti, long cell_id, int mcc_id);
|
||||
|
||||
/* Get RSRP of neighbouring Cell */
|
||||
float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get RSRQ of neighbouring Cell */
|
||||
float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/*Get MCC PLMN identity neighbouring Cell*/
|
||||
/* currently not implemented
|
||||
int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, rnti_t rnti, int cell_id); */
|
||||
/* Get ofp offset */
|
||||
long flexran_get_rrc_ofp(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/*Get MNC PLMN identity neighbouring Cell*/
|
||||
/* currently not implemented
|
||||
int flexran_get_rrc_neigh_plmn_mnc(mid_t mod_id, mid_t ue_id, int cell_id); */
|
||||
/* Get ofn offset */
|
||||
long flexran_get_rrc_ofn(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get ocp offset */
|
||||
long flexran_get_rrc_ocp(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get ocn offset */
|
||||
long flexran_get_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get Periodic Event max reported cells */
|
||||
long flexran_get_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get A3 Event hysteresis */
|
||||
long flexran_get_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get A3 Event time to trigger */
|
||||
long flexran_get_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get A3 Event max reported cells */
|
||||
long flexran_get_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get A3 Event a3 offset */
|
||||
long flexran_get_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get A3 Event report on leave */
|
||||
int flexran_get_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get filter coefficient for rsrp */
|
||||
long flexran_get_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get filter coefficient for rsrq */
|
||||
long flexran_get_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Set ofp offset */
|
||||
int flexran_set_rrc_ofp(mid_t mod_id, rnti_t rnti, long offsetFreq);
|
||||
|
||||
/* Set ofn offset */
|
||||
int flexran_set_rrc_ofn(mid_t mod_id, rnti_t rnti, long offsetFreq);
|
||||
|
||||
/* Set ocp offset */
|
||||
int flexran_set_rrc_ocp(mid_t mod_id, rnti_t rnti, long cellIndividualOffset);
|
||||
|
||||
/* Set ocn offset */
|
||||
int flexran_set_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id, long cellIndividualOffset);
|
||||
|
||||
/* Set Periodic Event max reported cells */
|
||||
int flexran_set_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells);
|
||||
|
||||
/* Set A3 Event hysteresis */
|
||||
int flexran_set_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti, long hysteresis);
|
||||
|
||||
/* Set A3 Event time to trigger */
|
||||
int flexran_set_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti, long timeToTrigger);
|
||||
|
||||
/* Set A3 Event max reported cells */
|
||||
int flexran_set_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells);
|
||||
|
||||
/* Set A3 Event a3 offset */
|
||||
int flexran_set_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti, long a3_offset);
|
||||
|
||||
/* Set A3 Event report on leave */
|
||||
int flexran_set_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti, int reportOnLeave);
|
||||
|
||||
/* Set filter coefficient for rsrp */
|
||||
int flexran_set_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRP);
|
||||
|
||||
/* Set filter coefficient for rsrq */
|
||||
int flexran_set_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRQ);
|
||||
|
||||
/* Get number of PLMNs that is broadcasted in SIB1 */
|
||||
uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id);
|
||||
@@ -539,6 +630,27 @@ uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index);
|
||||
/* Get index'th MNC's digit length broadcasted in SIB1 */
|
||||
uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index);
|
||||
|
||||
/* Get X2 handover controlled by network */
|
||||
int flexran_get_x2_ho_net_control(mid_t mod_id);
|
||||
|
||||
/* Set X2 handover controlled by network */
|
||||
int flexran_set_x2_ho_net_control(mid_t mod_id, int x2_ho_net_control);
|
||||
|
||||
/* Get number of adjacent cells via X2 interface */
|
||||
int flexran_get_rrc_num_adj_cells(mid_t mod_id);
|
||||
|
||||
/* Get the number of E-RABs for UE */
|
||||
int flexran_agent_rrc_gtp_num_e_rab(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get the e-RAB ID for UE */
|
||||
int flexran_agent_rrc_gtp_get_e_rab_id(mid_t mod_id, rnti_t rnti, int index);
|
||||
|
||||
/* Get the TEID at the eNB for UE */
|
||||
int flexran_agent_rrc_gtp_get_teid_enb(mid_t mod_id, rnti_t rnti, int index);
|
||||
|
||||
/* Get the TEID at the SGW for UE */
|
||||
int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index);
|
||||
|
||||
/************************** Slice configuration **************************/
|
||||
|
||||
/* Get the DL slice ID for a UE */
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
|
||||
#define MAX_PAYLOAD 1024 /* maximum payload size*/
|
||||
|
||||
#define MAX_NUM_NEIGH_CELLs 6 /* maximum neighbouring cells number */
|
||||
|
||||
#define UE_STATE_NOTIFICATION_INTERVAL 50
|
||||
|
||||
#define IPV4_ADDR "%u.%u.%u.%u"
|
||||
@@ -477,6 +479,73 @@ typedef struct HANDOVER_INFO_s {
|
||||
int x2_id; /* X2AP UE ID in the target eNB */
|
||||
} HANDOVER_INFO;
|
||||
|
||||
typedef struct PER_EVENT_s {
|
||||
long maxReportCells;
|
||||
} PER_EVENT_t;
|
||||
|
||||
typedef struct A1_EVENT_s {
|
||||
long threshold_RSRP;
|
||||
long hysteresis;
|
||||
long timeToTrigger;
|
||||
long maxReportCells;
|
||||
} A1_EVENT_t;
|
||||
|
||||
typedef struct A2_EVENT_s {
|
||||
long threshold_RSRP;
|
||||
long hysteresis;
|
||||
long timeToTrigger;
|
||||
long maxReportCells;
|
||||
} A2_EVENT_t;
|
||||
|
||||
typedef struct A3_EVENT_s {
|
||||
long a3_offset;
|
||||
int reportOnLeave;
|
||||
long hysteresis;
|
||||
long timeToTrigger;
|
||||
long maxReportCells;
|
||||
} A3_EVENT_t;
|
||||
|
||||
|
||||
typedef struct A4_EVENT_s {
|
||||
long threshold_RSRP;
|
||||
long hysteresis;
|
||||
long timeToTrigger;
|
||||
long maxReportCells;
|
||||
} A4_EVENT_t;
|
||||
|
||||
typedef struct A5_EVENT_s {
|
||||
long threshold_RSRP_1;
|
||||
long threshold_RSRP_2;
|
||||
long hysteresis;
|
||||
long timeToTrigger;
|
||||
long maxReportCells;
|
||||
} A5_EVENT_t;
|
||||
|
||||
typedef struct EVENTS_s {
|
||||
PER_EVENT_t *per_event;
|
||||
|
||||
A1_EVENT_t *a1_event;
|
||||
|
||||
A2_EVENT_t *a2_event;
|
||||
|
||||
A3_EVENT_t *a3_event;
|
||||
|
||||
A4_EVENT_t *a4_event;
|
||||
|
||||
A5_EVENT_t *a5_event;
|
||||
} EVENTS_t;
|
||||
|
||||
typedef struct MEASUREMENT_INFO_s {
|
||||
//TODO: Extend to multiple meas objects for OFP/OFN offsets
|
||||
long offsetFreq;
|
||||
//TODO: extend to multiple carriers for OCP/OCN offsets
|
||||
long cellIndividualOffset[MAX_NUM_NEIGH_CELLs+1];
|
||||
long filterCoefficientRSRP;
|
||||
long filterCoefficientRSRQ;
|
||||
EVENTS_t *events;
|
||||
} MEASUREMENT_INFO;
|
||||
|
||||
|
||||
#define RRC_HEADER_SIZE_MAX 64
|
||||
#define RRC_BUFFER_SIZE_MAX 1024
|
||||
typedef struct {
|
||||
@@ -559,6 +628,7 @@ typedef struct eNB_RRC_UE_s {
|
||||
SRB_INFO_TABLE_ENTRY Srb2;
|
||||
LTE_MeasConfig_t *measConfig;
|
||||
HANDOVER_INFO *handover_info;
|
||||
MEASUREMENT_INFO *measurement_info;
|
||||
LTE_MeasResults_t *measResults;
|
||||
LTE_MobilityControlInfo_t *mobilityInfo;
|
||||
|
||||
@@ -756,6 +826,14 @@ typedef struct eNB_RRC_INST_s {
|
||||
/// NR cell id
|
||||
uint64_t nr_cellid;
|
||||
|
||||
// X2 handover controlled by network
|
||||
int x2_ho_net_control;
|
||||
|
||||
// Neighborouring cells id
|
||||
int num_neigh_cells;
|
||||
int num_neigh_cells_cc[MAX_NUM_CCs];
|
||||
uint32_t neigh_cells_id[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs];
|
||||
|
||||
// other RAN parameters
|
||||
int srb1_timer_poll_retransmit;
|
||||
int srb1_poll_pdu;
|
||||
|
||||
+628
-211
File diff suppressed because it is too large
Load Diff
@@ -306,8 +306,7 @@ void
|
||||
flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_eNB_ue_context_t *const ue_context_pP,
|
||||
const uint8_t ho_state,
|
||||
agent_reconf_rrc *trig_param
|
||||
const uint8_t ho_state
|
||||
);
|
||||
void
|
||||
rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
|
||||
@@ -357,6 +356,9 @@ void *rrc_enb_task(void *args_p);
|
||||
\param void *args_p Pointer on arguments to start the task. */
|
||||
void *rrc_ue_task(void *args_p);
|
||||
|
||||
void rrc_eNB_process_x2_setup_request(int mod_id, x2ap_setup_req_t *m);
|
||||
|
||||
void rrc_eNB_process_x2_setup_response(int mod_id, x2ap_setup_resp_t *m);
|
||||
|
||||
void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m);
|
||||
|
||||
@@ -610,6 +612,12 @@ rrc_eNB_generate_HandoverPreparationInformation(
|
||||
//LTE_PhysCellId_t targetPhyId
|
||||
);
|
||||
|
||||
int
|
||||
flexran_rrc_eNB_trigger_handover (int mod_id,
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_eNB_ue_context_t *ue_context_pP,
|
||||
int target_cell_id);
|
||||
|
||||
void
|
||||
check_handovers(
|
||||
protocol_ctxt_t *const ctxt_pP
|
||||
|
||||
@@ -291,6 +291,7 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance,
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
uint32_t eNB_id = 0;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
@@ -391,17 +392,25 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance,
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_SETUP_REQ);
|
||||
|
||||
X2AP_SETUP_REQ(msg).num_cc = ie->value.choice.ServedCells.list.count;
|
||||
|
||||
if (ie->value.choice.ServedCells.list.count > 0) {
|
||||
x2ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count;
|
||||
for (int i=0; i<ie->value.choice.ServedCells.list.count;i++) {
|
||||
servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i];
|
||||
x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI;
|
||||
X2AP_SETUP_REQ(msg).Nid_cell[i] = x2ap_eNB_data->Nid_cell[i];
|
||||
}
|
||||
}
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
|
||||
|
||||
return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data);
|
||||
}
|
||||
|
||||
@@ -418,6 +427,7 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
uint32_t eNB_id = 0;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
@@ -500,11 +510,16 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_SETUP_RESP);
|
||||
|
||||
X2AP_SETUP_RESP(msg).num_cc = ie->value.choice.ServedCells.list.count;
|
||||
|
||||
if (ie->value.choice.ServedCells.list.count > 0) {
|
||||
x2ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count;
|
||||
for (int i=0; i<ie->value.choice.ServedCells.list.count;i++) {
|
||||
servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i];
|
||||
x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI;
|
||||
X2AP_SETUP_RESP(msg).Nid_cell[i] = x2ap_eNB_data->Nid_cell[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,6 +536,8 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
|
||||
instance_p->x2_target_enb_associated_nb ++;
|
||||
x2ap_handle_x2_setup_message(instance_p, x2ap_eNB_data, 0);
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user