Commit a87220d3 authored by Robert Schmidt's avatar Robert Schmidt

Add S1AP control module for FlexRAN with status monitoring support

parent 44fdb23f
...@@ -923,6 +923,7 @@ include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY") ...@@ -923,6 +923,7 @@ include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY")
include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC")
include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC")
include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP")
include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/S1AP")
include_directories("${OPENAIR2_DIR}/UTIL/OSA") include_directories("${OPENAIR2_DIR}/UTIL/OSA")
include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds6.1.1/liblfds611/inc") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds6.1.1/liblfds611/inc")
include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds7.0.0/liblfds700/inc") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds7.0.0/liblfds700/inc")
...@@ -1016,6 +1017,7 @@ add_library(FLEXRAN_AGENT ...@@ -1016,6 +1017,7 @@ add_library(FLEXRAN_AGENT
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.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/RRC/flexran_agent_rrc_internal.c
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c
${OPENAIR2_DIR}/ENB_APP/flexran_agent.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent.c
${OPENAIR2_DIR}/ENB_APP/flexran_agent_task_manager.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_task_manager.c
${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file flexran_agent_s1ap.c
* \brief FlexRAN agent Control Module S1AP
* \author Navid Nikaein
* \date 2019
* \version 0.1
*/
#include "flexran_agent_s1ap.h"
/*Array containing the Agent-S1AP interfaces*/
AGENT_S1AP_xface *agent_s1ap_xface[NUM_MAX_ENB];
void flexran_agent_fill_s1ap_cell_config(mid_t mod_id,
Protocol__FlexS1apConfig **s1ap_config) {
*s1ap_config = malloc(sizeof(Protocol__FlexS1apConfig));
if (!*s1ap_config) return;
protocol__flex_s1ap_config__init(*s1ap_config);
LOG_D(FLEXRAN_AGENT, "flexran_agent_fill_s1ap_cell_config %d\n", mod_id);
// S1AP status
(*s1ap_config)->has_pending = 1;
(*s1ap_config)->pending = flexran_get_s1ap_mme_pending(mod_id);
(*s1ap_config)->has_connected = 1;
(*s1ap_config)->connected = flexran_get_s1ap_mme_connected(mod_id);
(*s1ap_config)->enb_s1_ip = flexran_get_s1ap_enb_s1_ip(mod_id);
if (!(*s1ap_config)->enb_s1_ip)
(*s1ap_config)->enb_s1_ip = "";
(*s1ap_config)->enb_name = flexran_get_s1ap_enb_name(mod_id);
(*s1ap_config)->mme = NULL;
(*s1ap_config)->n_mme = flexran_get_s1ap_nb_mme(mod_id);
if ((*s1ap_config)->n_mme > 0) {
Protocol__FlexS1apMme **mme_conf = calloc((*s1ap_config)->n_mme,
sizeof(Protocol__FlexS1apMme *));
AssertFatal(mme_conf, "%s(): MME malloc failed\n", __func__);
for(int i = 0; i < (*s1ap_config)->n_mme; i++){
mme_conf[i] = malloc(sizeof(Protocol__FlexS1apMme));
AssertFatal(mme_conf[i], "%s(): MME malloc failed\n", __func__);
protocol__flex_s1ap_mme__init(mme_conf[i]);
if (flexran_get_s1ap_mme_conf(mod_id, i, mme_conf[i]) < 0) {
LOG_E(FLEXRAN_AGENT,
"error in flexran_get_s1ap_mme_conf(): cannot retrieve MME state\n");
(*s1ap_config)->n_mme = 0;
break;
}
}
(*s1ap_config)->mme = mme_conf;
}
}
int flexran_agent_s1ap_stats_reply(mid_t mod_id,
Protocol__FlexUeStatsReport **ue_report,
int n_ue,
uint32_t ue_flags) {
if (n_ue <= 0)
return 0;
if (!(ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_S1AP_STATS))
return 0;
for (int i = 0; i < n_ue; i++) {
const rnti_t rnti = ue_report[i]->rnti;
Protocol__FlexS1apUe *ue = malloc(sizeof(Protocol__FlexS1apUe));
AssertFatal(ue, "%s(): MME malloc failed\n", __func__);
protocol__flex_s1ap_ue__init(ue);
if (flexran_get_s1ap_ue(mod_id, rnti, ue) < 0) {
LOG_E(FLEXRAN_AGENT, "error in %s(): cannot retrieve UE conf\n", __func__);
break;
}
ue_report[i]->s1ap_stats = ue;
ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_S1AP_STATS;
}
return 0;
}
void flexran_agent_free_s1ap_cell_config(Protocol__FlexS1apConfig **s1ap) {
for (int i = 0; i < (*s1ap)->n_mme; i++) {
/* following structures allocated in the RAN API */
for(int j = 0; j < (*s1ap)->mme[i]->n_served_gummeis; j++) {
free((*s1ap)->mme[i]->served_gummeis[j]->plmn);
free((*s1ap)->mme[i]->served_gummeis[j]);
}
free((*s1ap)->mme[i]->served_gummeis);
for (int j = 0; j < (*s1ap)->mme[i]->n_requested_plmns; j++)
free((*s1ap)->mme[i]->requested_plmns[j]);
free((*s1ap)->mme[i]->requested_plmns);
free((*s1ap)->mme[i]);
}
free((*s1ap)->mme);
free(*s1ap);
*s1ap = NULL;
}
void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply) {
for (int i = 0; i < reply->n_ue_report; ++i) {
if (!reply->ue_report[i]->s1ap_stats)
continue;
free(reply->ue_report[i]->s1ap_stats->selected_plmn);
free(reply->ue_report[i]->s1ap_stats);
reply->ue_report[i]->s1ap_stats = NULL;
}
}
int flexran_agent_register_s1ap_xface(mid_t mod_id) {
if (agent_s1ap_xface[mod_id]) {
LOG_E(FLEXRAN_AGENT, "S1AP agent CM for eNB %d is already registered\n", mod_id);
return -1;
}
AGENT_S1AP_xface *xface = malloc(sizeof(AGENT_S1AP_xface));
if (!xface) {
LOG_E(FLEXRAN_AGENT, "could not allocate memory for S1AP agent xface %d\n", mod_id);
return -1;
}
// not implemented yet
xface->flexran_s1ap_notify_release_request=NULL;
agent_s1ap_xface[mod_id] = xface;
return 0;
}
int flexran_agent_unregister_s1ap_xface(mid_t mod_id) {
if (!agent_s1ap_xface[mod_id]) {
LOG_E(FLEXRAN_AGENT, "S1AP agent for eNB %d is not registered\n", mod_id);
return -1;
}
agent_s1ap_xface[mod_id]->flexran_s1ap_notify_release_request=NULL;
free(agent_s1ap_xface[mod_id]);
agent_s1ap_xface[mod_id] = NULL;
return 0;
}
AGENT_S1AP_xface *flexran_agent_get_s1ap_xface(mid_t mod_id) {
return agent_s1ap_xface[mod_id];
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file flexran_agent_s1ap.h
* \brief FlexRAN agent S1AP Control Module
* \author navid nikaein
* \date 2017
* \version 0.1
*/
#ifndef FLEXRAN_AGENT_S1AP_H_
#define FLEXRAN_AGENT_S1AP_H_
#include "header.pb-c.h"
#include "flexran.pb-c.h"
#include "stats_messages.pb-c.h"
#include "stats_common.pb-c.h"
#include "flexran_agent_common.h"
#include "flexran_agent_defs.h"
#include "flexran_agent_s1ap_defs.h"
#include "flexran_agent_ran_api.h"
/***************************************
* FlexRAN agent - technology S1AP API *
***************************************/
/* Send to the controller all the S1AP configs */
void flexran_agent_fill_s1ap_cell_config(mid_t mod_id,
Protocol__FlexS1apConfig **s1ap_config);
/* Free allocated S1AP cell configs */
void flexran_agent_free_s1ap_cell_config(Protocol__FlexS1apConfig **s1ap);
/* Fill the stats message for S1AP */
int flexran_agent_s1ap_stats_reply(mid_t mod_id,
Protocol__FlexUeStatsReport **ue_report,
int n_ue,
uint32_t ue_flags);
/* Free allocated S1AP stats message */
void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply);
/* Register technology specific interface callbacks */
int flexran_agent_register_s1ap_xface(mid_t mod_id);
/* Unregister technology specific callbacks */
int flexran_agent_unregister_s1ap_xface(mid_t mod_id);
#endif
/*
* 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_S1AP_PRIMITIVES_H__
#define __FLEXRAN_AGENT_S1AP_PRIMITIVES_H__
#include "flexran_agent_defs.h"
/* FLEXRAN AGENT-S1AP Interface */
typedef struct {
// S1AP statistics
void (*flexran_s1ap_notify_release_request)(mid_t mod_id);
} AGENT_S1AP_xface;
#endif
...@@ -355,13 +355,6 @@ message flex_s1ap_mme { ...@@ -355,13 +355,6 @@ message flex_s1ap_mme {
optional uint32 rel_capacity = 6; // Relative MME capacity, TS23.401 optional uint32 rel_capacity = 6; // Relative MME capacity, TS23.401
} }
message flex_s1ap_ue {
optional string mme_s1_ip = 1; // IP of MME to which UE is connected
optional uint32 enb_ue_s1ap_id = 2; // S1AP ID on eNodeB side for UE
optional uint32 mme_ue_s1ap_id = 3; // S1AP ID on MME side for UE
optional flex_plmn selected_plmn = 4; // UE-selected PLMN in RRC Conn Setup Cplt
}
enum flex_mme_state { enum flex_mme_state {
FLMMES_DISCONNECTED = 0; FLMMES_DISCONNECTED = 0;
FLMMES_WAITING = 1; FLMMES_WAITING = 1;
......
...@@ -100,7 +100,6 @@ message flex_ue_config { ...@@ -100,7 +100,6 @@ message flex_ue_config {
optional uint32 ul_slice_id = 32; optional uint32 ul_slice_id = 32;
// Configuration about RRC measurements // Configuration about RRC measurements
optional flex_measurement_info info = 33; optional flex_measurement_info info = 33;
optional uint32 enb_ue_s1ap_id = 34; // S1AP ID on eNodeB side
} }
message flex_lc_ue_config { message flex_lc_ue_config {
...@@ -109,10 +108,9 @@ message flex_lc_ue_config { ...@@ -109,10 +108,9 @@ message flex_lc_ue_config {
} }
message flex_s1ap_config { message flex_s1ap_config {
optional uint32 pending = 1; // number of pending (to be connected) MMEs optional uint32 pending = 1; // number of pending (to be connected) MMEs
optional uint32 connected = 2; // number of connected MMEs optional uint32 connected = 2; // number of connected MMEs
optional string enb_s1_ip = 3; // S1-MME IP of eNodeB optional string enb_s1_ip = 3; // S1-MME IP of eNodeB
optional string enb_name = 4; // S1-MME name of eNodeB optional string enb_name = 4; // S1-MME name of eNodeB
repeated flex_s1ap_mme mme = 5; repeated flex_s1ap_mme mme = 5;
repeated flex_s1ap_ue ue = 6;
} }
...@@ -75,6 +75,7 @@ enum flex_bs_capability { ...@@ -75,6 +75,7 @@ enum flex_bs_capability {
PDCP = 5; PDCP = 5;
SDAP = 6; SDAP = 6;
RRC = 7; RRC = 7;
S1AP = 8;
} }
enum flex_bs_split { enum flex_bs_split {
......
...@@ -310,3 +310,15 @@ message flex_gtp_stats { ...@@ -310,3 +310,15 @@ message flex_gtp_stats {
optional uint32 teid_sgw = 4; optional uint32 teid_sgw = 4;
optional string addr_sgw = 5; optional string addr_sgw = 5;
} }
//
// S1AP stats
//
message flex_s1ap_ue {
optional string mme_s1_ip = 1; // IP of MME to which UE is connected
optional uint32 enb_ue_s1ap_id = 2; // S1AP ID on eNodeB side for UE
optional uint32 mme_ue_s1ap_id = 3; // S1AP ID on MME side for UE
optional flex_plmn selected_plmn = 4; // UE-selected PLMN in RRC Conn Setup Cplt
}
...@@ -51,6 +51,7 @@ message flex_ue_stats_report { ...@@ -51,6 +51,7 @@ message flex_ue_stats_report {
optional flex_pdcp_stats pdcp_stats = 11; optional flex_pdcp_stats pdcp_stats = 11;
optional flex_mac_stats mac_stats = 12; optional flex_mac_stats mac_stats = 12;
repeated flex_gtp_stats gtp_stats = 13; repeated flex_gtp_stats gtp_stats = 13;
optional flex_s1ap_ue s1ap_stats = 14;
} }
// //
...@@ -91,6 +92,7 @@ enum flex_ue_stats_type { ...@@ -91,6 +92,7 @@ enum flex_ue_stats_type {
FLUST_PDCP_STATS = 1024; FLUST_PDCP_STATS = 1024;
FLUST_GTP_STATS = 2048; FLUST_GTP_STATS = 2048;
FLUST_S1AP_STATS = 4096;
FLUST_RRC_MEASUREMENTS = 65536; FLUST_RRC_MEASUREMENTS = 65536;
// To be extended with more types of stats // To be extended with more types of stats
......
...@@ -177,8 +177,8 @@ int flexran_agent_start(mid_t mod_id) ...@@ -177,8 +177,8 @@ int flexran_agent_start(mid_t mod_id)
/* Register and initialize the control modules depending on capabilities. /* Register and initialize the control modules depending on capabilities.
* After registering, calling flexran_agent_get_*_xface() tells whether a * After registering, calling flexran_agent_get_*_xface() tells whether a
* control module is operational */ * control module is operational */
uint16_t caps = flexran_get_capabilities_mask(mod_id); uint32_t caps = flexran_get_capabilities_mask(mod_id);
LOG_I(FLEXRAN_AGENT, "Agent handles BS ID %ld, capabilities=0x%x => handling%s%s%s%s%s%s%s%s\n", LOG_I(FLEXRAN_AGENT, "Agent handles BS ID %ld, capabilities=0x%x => handling%s%s%s%s%s%s%s%s%s\n",
flexran_get_bs_id(mod_id), caps, flexran_get_bs_id(mod_id), caps,
FLEXRAN_CAP_LOPHY(caps) ? " LOPHY" : "", FLEXRAN_CAP_LOPHY(caps) ? " LOPHY" : "",
FLEXRAN_CAP_HIPHY(caps) ? " HIPHY" : "", FLEXRAN_CAP_HIPHY(caps) ? " HIPHY" : "",
...@@ -187,7 +187,8 @@ int flexran_agent_start(mid_t mod_id) ...@@ -187,7 +187,8 @@ int flexran_agent_start(mid_t mod_id)
FLEXRAN_CAP_RLC(caps) ? " RLC" : "", FLEXRAN_CAP_RLC(caps) ? " RLC" : "",
FLEXRAN_CAP_PDCP(caps) ? " PDCP" : "", FLEXRAN_CAP_PDCP(caps) ? " PDCP" : "",
FLEXRAN_CAP_SDAP(caps) ? " SDAP" : "", FLEXRAN_CAP_SDAP(caps) ? " SDAP" : "",
FLEXRAN_CAP_RRC(caps) ? " RRC" : ""); FLEXRAN_CAP_RRC(caps) ? " RRC" : "",
FLEXRAN_CAP_S1AP(caps) ? " S1AP" : "");
if (FLEXRAN_CAP_LOPHY(caps) || FLEXRAN_CAP_HIPHY(caps)) { if (FLEXRAN_CAP_LOPHY(caps) || FLEXRAN_CAP_HIPHY(caps)) {
flexran_agent_register_phy_xface(mod_id); flexran_agent_register_phy_xface(mod_id);
...@@ -210,6 +211,11 @@ int flexran_agent_start(mid_t mod_id) ...@@ -210,6 +211,11 @@ int flexran_agent_start(mid_t mod_id)
LOG_I(FLEXRAN_AGENT, "registered PDCP interface/CM for eNB %d\n", mod_id); LOG_I(FLEXRAN_AGENT, "registered PDCP interface/CM for eNB %d\n", mod_id);
} }
if (FLEXRAN_CAP_S1AP(caps)) {
flexran_agent_register_s1ap_xface(mod_id);
LOG_I(FLEXRAN_AGENT, "registered S1AP interface/CM for eNB %d\n", mod_id);
}
/* /*
* initilize a timer * initilize a timer
*/ */
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "flexran_agent_mac.h" #include "flexran_agent_mac.h"
#include "flexran_agent_rrc.h" #include "flexran_agent_rrc.h"
#include "flexran_agent_pdcp.h" #include "flexran_agent_pdcp.h"
#include "flexran_agent_s1ap.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include "assertions.h" #include "assertions.h"
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
/*! \file flexran_agent_common.c /*! \file flexran_agent_common.c
* \brief common primitives for all agents * \brief common primitives for all agents
* \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein, shahab SHARIAT BAGHERI * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein
* \date 2017 * \date 2017
* \version 0.1 * \version 0.1
*/ */
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "flexran_agent_phy.h" #include "flexran_agent_phy.h"
#include "flexran_agent_mac.h" #include "flexran_agent_mac.h"
#include "flexran_agent_rrc.h" #include "flexran_agent_rrc.h"
#include "flexran_agent_s1ap.h"
//#include "PHY/extern.h" //#include "PHY/extern.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include "flexran_agent_mac_internal.h" #include "flexran_agent_mac_internal.h"
...@@ -339,6 +340,9 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { ...@@ -339,6 +340,9 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
free(reply->cell_config[i]); free(reply->cell_config[i]);
} }
if (reply->s1ap)
flexran_agent_free_s1ap_cell_config(&reply->s1ap);
free(reply->cell_config); free(reply->cell_config);
free(reply); free(reply);
...@@ -757,9 +761,12 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F ...@@ -757,9 +761,12 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
cell_conf[i]->carrier_index = i; cell_conf[i]->carrier_index = i;
cell_conf[i]->has_carrier_index = 1; cell_conf[i]->has_carrier_index = 1;
} }
enb_config_reply_msg->cell_config=cell_conf; enb_config_reply_msg->cell_config=cell_conf;
} }
if (flexran_agent_get_s1ap_xface(mod_id))
flexran_agent_fill_s1ap_cell_config(mod_id, &enb_config_reply_msg->s1ap);
*msg = malloc(sizeof(Protocol__FlexranMessage)); *msg = malloc(sizeof(Protocol__FlexranMessage));
......
...@@ -116,6 +116,7 @@ typedef int32_t err_code_t; ...@@ -116,6 +116,7 @@ typedef int32_t err_code_t;
#define FLEXRAN_CAP_PDCP(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP)) > 0) #define FLEXRAN_CAP_PDCP(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP)) > 0)
#define FLEXRAN_CAP_SDAP(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)) > 0) #define FLEXRAN_CAP_SDAP(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)) > 0)
#define FLEXRAN_CAP_RRC(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC)) > 0) #define FLEXRAN_CAP_RRC(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC)) > 0)
#define FLEXRAN_CAP_S1AP(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__S1AP)) > 0)
typedef enum { typedef enum {
ENB_NORMAL_OPERATION = 0x0, ENB_NORMAL_OPERATION = 0x0,
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "flexran_agent_mac_defs.h" #include "flexran_agent_mac_defs.h"
#include "flexran_agent_rrc_defs.h" #include "flexran_agent_rrc_defs.h"
#include "flexran_agent_pdcp_defs.h" #include "flexran_agent_pdcp_defs.h"
#include "flexran_agent_s1ap_defs.h"
/* Control module interface for the communication of the PHY control module with the agent */ /* Control module interface for the communication of the PHY control module with the agent */
AGENT_PHY_xface *flexran_agent_get_phy_xface(mid_t mod_id); AGENT_PHY_xface *flexran_agent_get_phy_xface(mid_t mod_id);
...@@ -48,6 +49,9 @@ AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id); ...@@ -48,6 +49,9 @@ AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id);
/* Control module interface for the communication of the RRC Control Module with the agent */ /* Control module interface for the communication of the RRC Control Module with the agent */
AGENT_PDCP_xface *flexran_agent_get_pdcp_xface(mid_t mod_id); AGENT_PDCP_xface *flexran_agent_get_pdcp_xface(mid_t mod_id);
/* Control module interface for the communication of the S1AP Control Module with the agent */
AGENT_S1AP_xface *flexran_agent_get_s1ap_xface(mid_t mod_id);
/* Requried to know which UEs had a harq updated over some subframe */ /* Requried to know which UEs had a harq updated over some subframe */
extern int harq_pid_updated[NUM_MAX_UE][8]; extern int harq_pid_updated[NUM_MAX_UE][8];
extern int harq_pid_round[NUM_MAX_UE][8]; extern int harq_pid_round[NUM_MAX_UE][8];
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "flexran_agent_mac.h" #include "flexran_agent_mac.h"
#include "flexran_agent_rrc.h" #include "flexran_agent_rrc.h"
#include "flexran_agent_pdcp.h" #include "flexran_agent_pdcp.h"
#include "flexran_agent_s1ap.h"
#include "flexran_agent_timer.h" #include "flexran_agent_timer.h"
#include "flexran_agent_ran_api.h" #include "flexran_agent_ran_api.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
...@@ -324,6 +325,14 @@ int flexran_agent_stats_reply(mid_t enb_id, ...@@ -324,6 +325,14 @@ int flexran_agent_stats_reply(mid_t enb_id,
goto error; goto error;
} }
/* S1AP statistics, depends on RRC to find S1AP ID */
if (flexran_agent_get_rrc_xface(enb_id)
&& flexran_agent_get_s1ap_xface(enb_id)
&& flexran_agent_s1ap_stats_reply(enb_id, ue_report, n_ue, ue_flags) < 0) {
err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
goto error;
}
if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) { if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) {
goto error; goto error;
} }
...@@ -523,6 +532,8 @@ int flexran_agent_destroy_stats_reply(Protocol__FlexranMessage *msg) ...@@ -523,6 +532,8 @@ int flexran_agent_destroy_stats_reply(Protocol__FlexranMessage *msg)
flexran_agent_mac_destroy_stats_reply(msg->stats_reply_msg); flexran_agent_mac_destroy_stats_reply(msg->stats_reply_msg);
flexran_agent_rrc_destroy_stats_reply(msg->stats_reply_msg); flexran_agent_rrc_destroy_stats_reply(msg->stats_reply_msg);
flexran_agent_pdcp_destroy_stats_reply(msg->stats_reply_msg); flexran_agent_pdcp_destroy_stats_reply(msg->stats_reply_msg);
flexran_agent_rrc_gtp_destroy_stats_reply(msg->stats_reply_msg);
flexran_agent_s1ap_destroy_stats_reply(msg->stats_reply_msg);
for (int i = 0; i < msg->stats_reply_msg->n_cell_report; ++i) for (int i = 0; i < msg->stats_reply_msg->n_cell_report; ++i)
free(msg->stats_reply_msg->cell_report[i]); free(msg->stats_reply_msg->cell_report[i]);
for (int i = 0; i < msg->stats_reply_msg->n_ue_report; ++i) for (int i = 0; i < msg->stats_reply_msg->n_ue_report; ++i)
......
This diff is collapsed.
...@@ -652,6 +652,9 @@ int flexran_agent_rrc_gtp_get_teid_enb(mid_t mod_id, rnti_t rnti, int index); ...@@ -652,6 +652,9 @@ 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 */ /* 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); int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index);
/* gets the UEs S1AP ID at eNodeB, stored in RRC */
uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti);
/************************** Slice configuration **************************/ /************************** Slice configuration **************************/
/* Get the DL slice ID for a UE */ /* Get the DL slice ID for a UE */
...@@ -804,6 +807,31 @@ char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx); ...@@ -804,6 +807,31 @@ char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx);
/* Set the scheduler name for a slice in UL */ /* Set the scheduler name for a slice in UL */
int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name); int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name);
/************************** S1AP **************************/
/* Get the number of MMEs to be connected */
int flexran_get_s1ap_mme_pending(mid_t mod_id);
/* Get the number of connected MMEs */
int flexran_get_s1ap_mme_connected(mid_t mod_id);
/* Get the eNB S1AP IP address */
char* flexran_get_s1ap_enb_s1_ip(mid_t mod_id);
/* Get the name of the eNB */
char* flexran_get_s1ap_enb_name(mid_t mod_id);
/* Get the number of connected MMEs to this eNB */
int flexran_get_s1ap_nb_mme(mid_t mod_id);
/* Get the number of connected UEs to this eNB */
int flexran_get_s1ap_nb_ue(mid_t mod_id);
/* Get the S1AP MME conf */
int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apMme * mme_conf);
/* Get the S1AP UE conf */
int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf);
/********************* general information *****************/ /********************* general information *****************/
/* get an ID for this BS (or part of a BS) */ /* get an ID for this BS (or part of a BS) */
uint64_t flexran_get_bs_id(mid_t mod_id); uint64_t flexran_get_bs_id(mid_t mod_id);
...@@ -815,7 +843,7 @@ size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps) ...@@ -815,7 +843,7 @@ size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps)
/* get the capabilities supported by the underlying network function as a bit /* get the capabilities supported by the underlying network function as a bit
* mask. */ * mask. */
uint16_t flexran_get_capabilities_mask(mid_t mod_id); uint32_t flexran_get_capabilities_mask(mid_t mod_id);
/* get the splits used by the underlying network function, /* get the splits used by the underlying network function,
* return the number and stores list of this length in splits. If there are * return the number and stores list of this length in splits. If there are
......
...@@ -124,7 +124,9 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, ...@@ -124,7 +124,9 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
s1ap_mme_data_p->assoc_id = -1; s1ap_mme_data_p->assoc_id = -1;
s1ap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num; s1ap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num;
memcpy(&s1ap_mme_data_p->mme_s1_ip,
mme_ip_address,
sizeof(*mme_ip_address));
for (int i = 0; i < broadcast_plmn_num; ++i) for (int i = 0; i < broadcast_plmn_num; ++i)
s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i]; s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i];
...@@ -193,6 +195,10 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * ...@@ -193,6 +195,10 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
new_instance->eNB_id = s1ap_register_eNB->eNB_id; new_instance->eNB_id = s1ap_register_eNB->eNB_id;
new_instance->cell_type = s1ap_register_eNB->cell_type; new_instance->cell_type = s1ap_register_eNB->cell_type;
new_instance->tac = s1ap_register_eNB->tac; new_instance->tac = s1ap_register_eNB->tac;
memcpy(&new_instance->eNB_s1_ip,
&s1ap_register_eNB->enb_ip_address,
sizeof(s1ap_register_eNB->enb_ip_address));
for (int i = 0; i < s1ap_register_eNB->num_plmn; i++) { for (int i = 0; i < s1ap_register_eNB->num_plmn; i++) {
new_instance->mcc[i] = s1ap_register_eNB->mcc[i]; new_instance->mcc[i] = s1ap_register_eNB->mcc[i];
......
...@@ -124,6 +124,9 @@ typedef struct s1ap_eNB_mme_data_s { ...@@ -124,6 +124,9 @@ typedef struct s1ap_eNB_mme_data_s {
/* This is the optional name provided by the MME */ /* This is the optional name provided by the MME */
char *mme_name; char *mme_name;
/* MME S1AP IP address */
net_ip_address_t mme_s1_ip;
/* List of served GUMMEI per MME. There is one GUMMEI per RAT with a max /* List of served GUMMEI per MME. There is one GUMMEI per RAT with a max
* number of 8 RATs but in our case only one is used. The LTE related pool * number of 8 RATs but in our case only one is used. The LTE related pool
* configuration is included on the first place in the list. * configuration is included on the first place in the list.
...@@ -200,6 +203,9 @@ typedef struct s1ap_eNB_instance_s { ...@@ -200,6 +203,9 @@ typedef struct s1ap_eNB_instance_s {
/* Tracking area code */ /* Tracking area code */
uint16_t tac; uint16_t tac;
/* eNB S1AP IP address */
net_ip_address_t eNB_s1_ip;
/* Mobile Country Code /* Mobile Country Code
* Mobile Network Code * Mobile Network Code
*/ */
......
...@@ -1468,7 +1468,7 @@ int s1ap_eNB_path_switch_req(instance_t instance, ...@@ -1468,7 +1468,7 @@ int s1ap_eNB_path_switch_req(instance_t instance,
break; break;
} }
} while(1); } while(1);
ue_context_p->mme_ue_s1ap_id = path_switch_req_p->mme_ue_s1ap_id; ue_context_p->mme_ue_s1ap_id = path_switch_req_p->mme_ue_s1ap_id;
/* Prepare the S1AP message to encode */ /* Prepare the S1AP message to encode */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment