Commit 79c920cd authored by Robert Schmidt's avatar Robert Schmidt

Introduce separate gNB-CU-UP ID in configuration

3GPP has the concept of a gNB-CU-UP ID and a (separate) gNB ID (for gNB,
CU-CP). This commit introduces the gNB-CU-UP as a separate ID that has to be
set in the configuration file when running as a CU-UP. For the
CU/monolithic gNB, it is optional (but needs to be the same as the
gNB-ID if specified).

The CU-UP ID is necessary, as some entities, e.g., the e2 agent, need to
signal both IDs, e.g., to reconcile a CU-CP and (multiple) CU-UP(s)
belonging together.
parent 6f14b118
......@@ -8,6 +8,7 @@ gNBs =
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_CU_UP_ID = 0xe00;
# cell_type = "CELL_MACRO_GNB";
......
......@@ -8,6 +8,7 @@ gNBs =
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_CU_UP_ID = 0xe00;
# cell_type = "CELL_MACRO_GNB";
......
......@@ -130,7 +130,8 @@ int main(int argc, char **argv)
AssertFatal(rc >= 0, "Create task for CUUP E1 failed\n");
nr_pdcp_layer_init(true);
cu_init_f1_ue_data(); // for CU-UP/CP mapping: we use the same
MessageDef *msg = RCconfig_NR_CU_E1(true);
E1_t e1type = UPtype;
MessageDef *msg = RCconfig_NR_CU_E1(&e1type);
AssertFatal(msg != NULL, "Send init to task for E1AP UP failed\n");
itti_send_msg_to_task(TASK_CUUP_E1, 0, msg);
......
......@@ -402,9 +402,9 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf
// If CU
if (node_type == ngran_gNB_CU || node_type == ngran_gNB) {
MessageDef *msg = RCconfig_NR_CU_E1(false);
MessageDef *msg = RCconfig_NR_CU_E1(NULL);
instance_t inst = 0;
createE1inst(UPtype, inst, &E1AP_REGISTER_REQ(msg).net_config, NULL);
createE1inst(UPtype, inst, E1AP_REGISTER_REQ(msg).gnb_id, &E1AP_REGISTER_REQ(msg).net_config, NULL);
cuup_init_n3(inst);
RC.nrrrc[gnb_id_start]->e1_inst = inst; // stupid instance !!!*/
......
......@@ -87,6 +87,7 @@ typedef struct e1ap_setup_req_s {
typedef struct e1ap_register_req_t {
e1ap_setup_req_t setup_req;
e1ap_net_config_t net_config;
uint32_t gnb_id; // unused in CU-UP, but might be necessary for some functionality, e.g., E2 agent
} e1ap_register_req_t;
typedef struct e1ap_setup_resp_s {
......
......@@ -1801,7 +1801,7 @@ void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr) {
void e1_task_handle_sctp_association_ind(E1_t type, instance_t instance, sctp_new_association_ind_t *sctp_new_ind)
{
if (!getCxtE1(instance))
createE1inst(type, instance, NULL, NULL);
createE1inst(type, instance, 0, NULL, NULL);
e1ap_upcp_inst_t *inst = getCxtE1(instance);
inst->sockState = SCTP_STATE_ESTABLISHED;
if (type == UPtype)
......@@ -1897,7 +1897,7 @@ void *E1AP_CUUP_task(void *arg) {
switch (msgType) {
case E1AP_REGISTER_REQ: {
e1ap_register_req_t *reg_req = &E1AP_REGISTER_REQ(msg);
createE1inst(UPtype, myInstance, &reg_req->net_config, &reg_req->setup_req);
createE1inst(UPtype, myInstance, reg_req->gnb_id, &reg_req->net_config, &reg_req->setup_req);
e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, &reg_req->net_config);
} break;
......
......@@ -37,12 +37,13 @@ e1ap_upcp_inst_t *getCxtE1(instance_t instance)
return e1ap_inst[instance];
}
void createE1inst(E1_t type, instance_t instance, e1ap_net_config_t *nc, e1ap_setup_req_t *req)
void createE1inst(E1_t type, instance_t instance, uint64_t gnb_id, e1ap_net_config_t *nc, e1ap_setup_req_t *req)
{
AssertFatal(e1ap_inst[instance] == NULL, "Double call to E1 instance %d\n", (int)instance);
e1ap_inst[instance] = calloc(1, sizeof(e1ap_upcp_inst_t));
e1ap_inst[instance]->type = type;
e1ap_inst[instance]->instance = instance;
e1ap_inst[instance]->gnb_id = gnb_id;
e1ap_inst[instance]->cuup.assoc_id = -1;
if (nc)
memcpy(&e1ap_inst[instance]->net_config, nc, sizeof(*nc));
......
......@@ -29,6 +29,7 @@
typedef struct e1ap_upcp_inst_s {
instance_t instance;
uint32_t gnb_id; // associated gNB's ID, unused in E1 but necessary for e.g. E2 agent
E1_t type;
enum sctp_state_e sockState;
struct {
......@@ -52,7 +53,7 @@ e1ap_upcp_inst_t *getCxtE1(instance_t instance);
long E1AP_get_next_transaction_identifier();
void E1AP_free_transaction_identifier(long id);
void createE1inst(E1_t type, instance_t instance, e1ap_net_config_t *nc, e1ap_setup_req_t *req);
void createE1inst(E1_t type, instance_t instance, uint64_t gnb_id, e1ap_net_config_t *nc, e1ap_setup_req_t *req);
int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, struct E1AP_E1AP_PDU *pdu, uint16_t stream, const char *func);
......
......@@ -68,7 +68,7 @@ static void get_NGU_S1U_addr(char **addr, uint16_t *port)
return;
}
MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process)
MessageDef *RCconfig_NR_CU_E1(const E1_t *entity)
{
MessageDef *msgConfig = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_REGISTER_REQ);
if (!msgConfig)
......@@ -82,14 +82,12 @@ MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process)
sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
AssertFatal(num_gnbs == 1, "Support only one gNB per process\n");
config_getlist(config_get_if(), &GNBParamList, GNBParams, sizeofArray(GNBParams), NULL);
paramdef_t *gnbParms = GNBParamList.paramarray[0];
e1ap_setup_req_t *e1Setup = &E1AP_REGISTER_REQ(msgConfig).setup_req;
if (num_gnbs > 0) {
config_getlist(config_get_if(), &GNBParamList, GNBParams, sizeofArray(GNBParams), NULL);
paramdef_t *gnbParms = GNBParamList.paramarray[0];
AssertFatal(gnbParms[GNB_GNB_ID_IDX].uptr != NULL, "gNB id %d is not defined in configuration file\n", 0);
e1ap_setup_req_t *e1Setup = &E1AP_REGISTER_REQ(msgConfig).setup_req;
msgConfig->ittiMsgHeader.destinationInstance = 0;
e1Setup->gNB_cu_up_id = *(gnbParms[GNB_GNB_ID_IDX].uptr);
if (*gnbParms[GNB_GNB_NAME_IDX].strptr)
e1Setup->gNB_cu_up_name = *(gnbParms[GNB_GNB_NAME_IDX].strptr);
......@@ -132,7 +130,11 @@ MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process)
get_NGU_S1U_addr(&e1ap_nc->localAddressN3, &e1ap_nc->localPortN3);
e1ap_nc->remotePortN3 = e1ap_nc->localPortN3 ;
if (separate_CUUP_process) {
AssertFatal(config_isparamset(gnbParms, GNB_GNB_ID_IDX), "%s is not defined in configuration file\n", GNB_CONFIG_STRING_GNB_ID);
uint32_t gnb_id = *gnbParms[GNB_GNB_ID_IDX].uptr;
E1AP_REGISTER_REQ(msgConfig).gnb_id = gnb_id;
if (entity != NULL) {
paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0};
paramdef_t GNBE1Params[] = GNBE1PARAMS_DESC;
config_getlist(config_get_if(), &GNBE1ParamList, GNBE1Params, sizeofArray(GNBE1Params), aprefix);
......@@ -141,6 +143,24 @@ MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process)
e1ap_nc->CUCP_e1_ip_address.ipv4 = 1;
strcpy(e1ap_nc->CUUP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUUP].strptr));
e1ap_nc->CUUP_e1_ip_address.ipv4 = 1;
if (*entity == CPtype) {
// CP needs gNB_ID (although not used, but other parts check it as
// well), and gNB-CU-UP ID should NOT be present as it comes through E1!
AssertFatal(!config_isparamset(gnbParms, GNB_GNB_CU_UP_ID_IDX), "%s must not be defined in configuration file\n", GNB_CONFIG_STRING_GNB_CU_UP_ID);
} else { // UPtype
AssertFatal(config_isparamset(gnbParms, GNB_GNB_CU_UP_ID_IDX), "%s is not be defined in configuration file\n", GNB_CONFIG_STRING_GNB_CU_UP_ID);
e1Setup->gNB_cu_up_id = *gnbParms[GNB_GNB_CU_UP_ID_IDX].u64ptr;
}
} else {
// integrated CU-CP/UP. We don't care about the gNB-CU-UP ID that much,
// but if it's there, check it's the same as gNB ID
uint64_t *gnb_cu_up_id = gnbParms[GNB_GNB_CU_UP_ID_IDX].u64ptr;
AssertFatal(!config_isparamset(gnbParms, GNB_GNB_CU_UP_ID_IDX) || *gnb_cu_up_id == gnb_id,
"%s is different of %s: they need to match or remove %s from config\n",
GNB_CONFIG_STRING_GNB_CU_UP_ID,
GNB_CONFIG_STRING_GNB_ID,
GNB_CONFIG_STRING_GNB_CU_UP_ID);
e1Setup->gNB_cu_up_id = gnb_id;
}
}
return msgConfig;
......
......@@ -146,7 +146,8 @@ void *gNB_app_task(void *args_p)
if (node_type == ngran_gNB_CUCP) {
if (itti_create_task(TASK_CUCP_E1, E1AP_CUCP_task, NULL) < 0)
AssertFatal(false, "Create task for E1AP CP failed\n");
MessageDef *msg = RCconfig_NR_CU_E1(true);
E1_t e1type = CPtype;
MessageDef *msg = RCconfig_NR_CU_E1(&e1type);
AssertFatal(msg != NULL, "Send inti to task for E1AP CP failed\n");
// this sends the E1AP_REGISTER_REQ to CU-CP so it sets up the socket
// it does NOT use the E1AP part
......
......@@ -107,7 +107,7 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i);
int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i);
void wait_f1_setup_response(void);
int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_update_t *gnb_cu_cfg_update);
MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process);
MessageDef *RCconfig_NR_CU_E1(const E1_t *entity);
ngran_node_t get_node_type(void);
#ifdef E2_AGENT
......
......@@ -129,11 +129,13 @@ typedef enum {
#define GNB_CONFIG_STRING_ENABLE_SDAP "enable_sdap"
#define GNB_CONFIG_STRING_DRBS "drbs"
#define GNB_CONFIG_STRING_GNB_DU_ID "gNB_DU_ID"
#define GNB_CONFIG_STRING_GNB_CU_UP_ID "gNB_CU_UP_ID"
#define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n"
#define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support"
#define GNB_CONFIG_HLP_STRING_DRBS "Number of total DRBs to establish, including the mandatory for PDU SEssion (default=1)\n"
#define GNB_CONFIG_HLP_GNB_DU_ID "defines the gNB-DU ID (only applicable for DU)"
#define GNB_CONFIG_HLP_GNB_CU_UP_ID "defines the gNB-CU-UP ID (only applicable for CU-UP)"
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
/* cell configuration parameters */
......@@ -170,6 +172,7 @@ typedef enum {
{GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL,.iptr=NULL, .defintval=0, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_DRBS, GNB_CONFIG_HLP_STRING_DRBS, 0, .iptr=NULL, .defintval=1, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_GNB_DU_ID, GNB_CONFIG_HLP_GNB_DU_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \
{GNB_CONFIG_STRING_GNB_CU_UP_ID, GNB_CONFIG_HLP_GNB_CU_UP_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \
}
// clang-format on
......@@ -203,6 +206,7 @@ typedef enum {
#define GNB_ENABLE_SDAP_IDX 26
#define GNB_DRBS 27
#define GNB_GNB_DU_ID_IDX 28
#define GNB_GNB_CU_UP_ID_IDX 29
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
#define GNBPARAMS_CHECK { \
......
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