From 4852354dac792e743570d3cfc732668e72e78c47 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Oct 2023 21:50:14 +0200 Subject: [PATCH 01/40] Correct banner mail --- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h | 2 +- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 2 +- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 2 +- openair2/RRC/LTE/rrc_defs.h | 2 +- openair2/RRC/NR/cucp_cuup_direct.c | 2 +- openair2/RRC/NR/cucp_cuup_e1ap.c | 2 +- openair2/RRC/NR/cucp_cuup_if.h | 2 +- openair2/RRC/NR/mac_rrc_dl.h | 2 +- openair2/RRC/NR/mac_rrc_dl_direct.c | 2 +- openair2/RRC/NR/mac_rrc_dl_f1ap.c | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h index b90e490302..62a4ae0248 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h @@ -16,7 +16,7 @@ * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: - * conmnc_digit_lengtht@openairinterface.org + * contact@openairinterface.org */ #ifndef MAC_RRC_UL_H diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index 905b9255e4..ab3b7646e7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -16,7 +16,7 @@ * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: - * conmnc_digit_lengtht@openairinterface.org + * contact@openairinterface.org */ #include "nr_mac_gNB.h" diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index b98de08a0d..8ee2913e0c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -16,7 +16,7 @@ * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: - * conmnc_digit_lengtht@openairinterface.org + * contact@openairinterface.org */ #include diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index b233cd502d..8e41bf69d3 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -16,7 +16,7 @@ * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: - * conmnc_digit_lengtht@openairinterface.org + * contact@openairinterface.org */ /*! \file RRC/LTE/defs.h diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 485edc08a4..8b81a3c5dd 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -16,7 +16,7 @@ * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: - * conmnc_digit_lengtht@openairinterface.org + * contact@openairinterface.org */ #include diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index 200729ec11..199c949959 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -16,7 +16,7 @@ * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: - * conmnc_digit_lengtht@openairinterface.org + * contact@openairinterface.org */ #include "cucp_cuup_if.h" diff --git a/openair2/RRC/NR/cucp_cuup_if.h b/openair2/RRC/NR/cucp_cuup_if.h index 079a32e850..8f072eb753 100644 --- a/openair2/RRC/NR/cucp_cuup_if.h +++ b/openair2/RRC/NR/cucp_cuup_if.h @@ -16,7 +16,7 @@ * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: - * conmnc_digit_lengtht@openairinterface.org + * contact@openairinterface.org */ #ifndef CUCP_CUUP_IF_H diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 9fc75b3073..6e43212f5e 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -16,7 +16,7 @@ * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: - * conmnc_digit_lengtht@openairinterface.org + * contact@openairinterface.org */ #ifndef MAC_RRC_DL_H diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index c18a33954c..ee9a29c6ae 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -16,7 +16,7 @@ * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: - * conmnc_digit_lengtht@openairinterface.org + * contact@openairinterface.org */ #include "nr_rrc_defs.h" diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 6ead51e3da..951e9639c5 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -16,7 +16,7 @@ * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: - * conmnc_digit_lengtht@openairinterface.org + * contact@openairinterface.org */ #include From e49608339a41c576aabc7e4c034d1f8cb6c5a49c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 8 Oct 2023 16:41:36 +0200 Subject: [PATCH 02/40] Add TODO regarding E1 & reestablishment For the reestablishment, we need to tell the PDCP it needs to reset the SN counters. This does not work over E1; add a TODO in the code. --- openair2/RRC/NR/rrc_gNB.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index b057d023b3..94d2efb569 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1041,6 +1041,7 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context } } + // TODO: should send E1 UE Bearer Modification with PDCP Reestablishment flag nr_pdcp_reestablishment(ue_p->rrc_ue_id); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); From 453f483c7a4f2f79c5abd6ac30265a4be8a08777 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Oct 2023 19:23:48 +0200 Subject: [PATCH 03/40] bugfix CU: set remote port in GTP-U module --- openair2/F1AP/f1ap_cu_task.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 2d47398d51..3d1f0b6aac 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -45,6 +45,7 @@ static instance_t cu_task_create_gtpu_instance(eth_params_t *IPaddrs) { openAddr_t tmp= {0}; strncpy(tmp.originHost, IPaddrs->my_addr, sizeof(tmp.originHost)-1); sprintf(tmp.originService, "%d", IPaddrs->my_portd); + sprintf(tmp.destinationService, "%d", IPaddrs->remote_portd); return gtpv1Init(tmp); } From d58ebfcaab46b780afd2501e70b01f1526db5881 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Sep 2023 11:22:17 +0200 Subject: [PATCH 04/40] Remove unused RRC variables --- openair2/COMMON/rrc_messages_types.h | 1 - openair2/GNB_APP/gnb_config.c | 3 +-- openair2/RRC/NR/nr_rrc_defs.h | 21 --------------------- 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 465c6c5342..fac23bb942 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -403,7 +403,6 @@ typedef struct NbIoTRrcConfigurationReq_s { // gNB: GNB_APP -> RRC messages typedef struct NRRrcConfigurationReq_s { - uint64_t cell_identity; uint32_t tac; uint16_t mcc[PLMN_LIST_MAX_SIZE]; uint16_t mnc[PLMN_LIST_MAX_SIZE]; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index e190b21748..8f679bf59c 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1523,7 +1523,7 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc) char aprefix[MAX_OPTNAME_SIZE*2 + 8]; sprintf(aprefix,"%s.[%u].%s",GNB_CONFIG_STRING_GNB_LIST,i,GNB_CONFIG_STRING_SCTP_CONFIG); config_get(SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); - rrc->node_id = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr); + rrc->node_id = gnb_id; LOG_I(GNB_APP,"F1AP: gNB_CU_id[%d] %d\n",k,rrc->node_id); rrc->node_name = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr)); LOG_I(GNB_APP,"F1AP: gNB_CU_name[%d] %s\n",k,rrc->node_name); @@ -1575,7 +1575,6 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc) for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); - nrrrc_config.cell_identity = gnb_id; nrrrc_config.tac = *GNBParamList.paramarray[i][GNB_TRACKING_AREA_CODE_IDX].uptr; AssertFatal(!GNBParamList.paramarray[i][GNB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr && !GNBParamList.paramarray[i][GNB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index c37979598a..0bda25a056 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -330,11 +330,6 @@ typedef struct { uint8_t *SIB23; uint8_t sizeof_SIB23; - NR_SIB2_t *sib2; - NR_SIB3_t *sib3; - NR_BCCH_DL_SCH_Message_t systemInformation; // SIB23 - NR_CellGroupConfig_t *secondaryCellGroup[MAX_NR_RRC_UE_CONTEXTS]; - } rrc_gNB_carrier_data_t; //--------------------------------------------------- @@ -396,23 +391,7 @@ typedef struct gNB_RRC_INST_s { // gNB N3 GTPU instance instance_t e1_inst; - // other PLMN parameters - /// Mobile country code - int mcc; - /// Mobile network code - int mnc; - /// number of mnc digits - int mnc_digit_length; - - // other RAN parameters - int srb1_timer_poll_retransmit; - int srb1_poll_pdu; - int srb1_poll_byte; - int srb1_max_retx_threshold; - int srb1_timer_reordering; - int srb1_timer_status_prohibit; int um_on_default_drb; - int srs_enable[MAX_NUM_CCs]; char *uecap_file; From c3f19a4eadcc1e4e473df9886fa23a480c5ecb0c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Sep 2023 11:25:10 +0200 Subject: [PATCH 05/40] Move "UM on default DRB" param to RRC config, make it bool --- openair2/COMMON/rrc_messages_types.h | 1 + openair2/GNB_APP/gnb_config.c | 2 +- openair2/GNB_APP/gnb_paramdef.h | 2 +- openair2/RRC/NR/nr_rrc_defs.h | 2 -- openair2/RRC/NR/rrc_gNB.c | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index fac23bb942..037dfbe86c 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -409,6 +409,7 @@ typedef struct NRRrcConfigurationReq_s { uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; uint8_t num_plmn; + bool um_on_default_drb; bool enable_sdap; int drbs; } gNB_RrcConfigurationReq; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 8f679bf59c..64fa933970 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1541,7 +1541,6 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc) rrc->nr_cellid = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr); - rrc->um_on_default_drb = *(GNBParamList.paramarray[i][GNB_UMONDEFAULTDRB_IDX].uptr); if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) { } else if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "cudu") == 0) { @@ -1605,6 +1604,7 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc) nrrrc_config.enable_sdap = *GNBParamList.paramarray[i][GNB_ENABLE_SDAP_IDX].iptr; LOG_I(GNB_APP, "SDAP layer is %s\n", nrrrc_config.enable_sdap ? "enabled" : "disabled"); nrrrc_config.drbs = *GNBParamList.paramarray[i][GNB_DRBS].iptr; + nrrrc_config.um_on_default_drb = *(GNBParamList.paramarray[i][GNB_UMONDEFAULTDRB_IDX].uptr); LOG_I(GNB_APP, "Data Radio Bearer count %d\n", nrrrc_config.drbs); }// diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index d59ecb9eb3..d78e438217 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -161,7 +161,7 @@ typedef enum { {GNB_CONFIG_STRING_NRCELLID, NULL, 0, .u64ptr=NULL,.defint64val=1, TYPE_UINT64, 0}, \ {GNB_CONFIG_STRING_MINRXTXTIME, NULL, 0, .iptr=NULL, .defintval=2, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_ULPRBBLACKLIST, NULL, 0, .strptr=NULL,.defstrval="", TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_UMONDEFAULTDRB, NULL, 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \ +{GNB_CONFIG_STRING_UMONDEFAULTDRB, NULL, PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ {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}, \ diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 0bda25a056..a31747a415 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -391,8 +391,6 @@ typedef struct gNB_RRC_INST_s { // gNB N3 GTPU instance instance_t e1_inst; - int um_on_default_drb; - char *uecap_file; // security configuration (preferred algorithms) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 94d2efb569..9683804cb0 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2352,7 +2352,7 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex f1ap_drb_to_be_setup_t drbs[nb_drb]; for (int i = 0; i < nb_drb; i++) { drbs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id; - drbs[i].rlc_mode = rrc->um_on_default_drb ? RLC_MODE_UM : RLC_MODE_AM; + drbs[i].rlc_mode = rrc->configuration.um_on_default_drb ? RLC_MODE_UM : RLC_MODE_AM; drbs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress; drbs[i].up_ul_tnl[0].port = rrc->eth_params_s.my_portd; drbs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId; From ed0923c2ec0477dd8bdd0c4b3439ceaf534dce3d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Sep 2023 12:37:28 +0200 Subject: [PATCH 06/40] E1AP messages: Remove DRBList and CN Support fields The DRBLists inside E1AP message are for E-UTRAN. We don't support that with our CU-CP/UP yet, so remove it to reduce ambiguity and complexity. For the same reason, we remove the CN Support, which for us is always "NR". --- openair2/COMMON/e1ap_messages_types.h | 13 ------------- openair2/E1AP/e1ap.c | 9 ++++----- openair2/E1AP/e1ap_setup.c | 1 - openair2/GNB_APP/gnb_paramdef.h | 3 --- 4 files changed, 4 insertions(+), 22 deletions(-) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index fba56ccb14..993a93bb38 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -66,7 +66,6 @@ typedef struct e1ap_setup_req_s { uint16_t default_sctp_stream_id; net_ip_address_t CUUP_e1_ip_address; net_ip_address_t CUCP_e1_ip_address; - long cn_support; uint16_t remotePortF1U; char* localAddressF1U; uint16_t localPortF1U; @@ -165,8 +164,6 @@ typedef struct e1ap_bearer_setup_req_s { long ueDlAggMaxBitRate; PLMN_ID_t servingPLMNid; long activityNotificationLevel; - int numDRBs; - drb_to_setup_t DRBList[E1AP_MAX_NUM_DRBS]; int numPDUSessions; pdu_session_to_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS]; int numPDUSessionsMod; @@ -180,14 +177,6 @@ typedef struct e1ap_bearer_release_cmd_s { long cause; } e1ap_bearer_release_cmd_t; -typedef struct drb_setup_s { - int drbId; - in_addr_t tlAddress; - int teId; - int numUpParam; - up_params_t UpParamList[E1AP_MAX_NUM_UP_PARAM]; -} drb_setup_t; - typedef struct qos_flow_setup_s { long id; } qos_flow_setup_t; @@ -219,8 +208,6 @@ typedef struct pdu_session_setup_s { typedef struct e1ap_bearer_setup_resp_s { uint32_t gNB_cu_cp_ue_id; uint32_t gNB_cu_up_ue_id; - int numDRBs; - drb_setup_t DRBList[E1AP_MAX_NUM_DRBS]; int numPDUSessions; pdu_session_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS]; } e1ap_bearer_setup_resp_t; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 2390b23d2e..6eebf8f7a9 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -191,7 +191,7 @@ static void fill_SETUP_REQUEST(e1ap_setup_req_t *setup, E1AP_E1AP_PDU_t *pdu) ieC4->id = E1AP_ProtocolIE_ID_id_CNSupport; ieC4->criticality = E1AP_Criticality_reject; ieC4->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_CNSupport; - ieC4->value.choice.CNSupport = setup->cn_support; + ieC4->value.choice.CNSupport = E1AP_CNSupport_c_5gc; /* only 5GC supported */ /* mandatory */ /* c5. Supported PLMNs */ @@ -293,8 +293,7 @@ void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, /* CN Support */ F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_CNSupport, true); - req->cn_support = ie->value.choice.CNSupport; - LOG_D(E1AP, "E1ap CN support: %ld\n", req->cn_support); + AssertFatal(ie->value.choice.CNSupport == E1AP_CNSupport_c_5gc, "only 5GC CN Support supported\n"); /* Supported PLMNs */ F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, @@ -676,7 +675,7 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const r ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse; ieC3->criticality = E1AP_Criticality_reject; ieC3->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_System_BearerContextSetupResponse; - if (0) { // EUTRAN + /*if (0) { // EUTRAN ieC3->value.choice.System_BearerContextSetupResponse.present = E1AP_System_BearerContextSetupResponse_PR_e_UTRAN_BearerContextSetupResponse; E1AP_ProtocolIE_Container_4932P21_t *msgEUTRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P21_t)); ieC3->value.choice.System_BearerContextSetupResponse.choice.e_UTRAN_BearerContextSetupResponse = (struct E1AP_ProtocolIE_Container *) msgEUTRAN_list; @@ -703,7 +702,7 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const r INT32_TO_OCTET_STRING(j->teId, &gTPTunnel->gTP_TEID); } } - } else { + } else */{ ieC3->value.choice.System_BearerContextSetupResponse.present = E1AP_System_BearerContextSetupResponse_PR_nG_RAN_BearerContextSetupResponse; E1AP_ProtocolIE_Container_4932P22_t *msgNGRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P22_t)); ieC3->value.choice.System_BearerContextSetupResponse.choice.nG_RAN_BearerContextSetupResponse = (struct E1AP_ProtocolIE_Container *) msgNGRAN_list; diff --git a/openair2/E1AP/e1ap_setup.c b/openair2/E1AP/e1ap_setup.c index da643636fc..324f5b87e2 100644 --- a/openair2/E1AP/e1ap_setup.c +++ b/openair2/E1AP/e1ap_setup.c @@ -122,7 +122,6 @@ MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process) e1Setup->CUCP_e1_ip_address.ipv4 = 1; strcpy(e1Setup->CUUP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUUP].strptr)); e1Setup->CUUP_e1_ip_address.ipv4 = 1; - e1Setup->cn_support = *e1Parms[GNB_CONFIG_E1_CN_SUPPORT].uptr; } } return msgConfig; diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index d78e438217..4ce9da2124 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -376,19 +376,16 @@ typedef enum { #define GNB_CONFIG_E1_CU_TYPE_IDX 0 #define GNB_CONFIG_E1_IPV4_ADDRESS_CUCP 1 #define GNB_CONFIG_E1_IPV4_ADDRESS_CUUP 2 -#define GNB_CONFIG_E1_CN_SUPPORT 3 #define GNB_CONFIG_STRING_E1_CU_TYPE "type" #define GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUCP "ipv4_cucp" #define GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUUP "ipv4_cuup" -#define GNB_CONFIG_STRING_E1_CN_SUPPORT "cn_support" // clang-format off #define GNBE1PARAMS_DESC { \ {GNB_CONFIG_STRING_E1_CU_TYPE, NULL, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUCP, NULL, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUUP, NULL, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \ - {GNB_CONFIG_STRING_E1_CN_SUPPORT, NULL, 0, .uptr =NULL, .defintval=1L, TYPE_UINT, 0} \ } // clang-format on /* L1 configuration section names */ From 6eba6678130667f392b0cad2f7d9c7becbfb6806 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Sep 2023 14:41:57 +0200 Subject: [PATCH 07/40] Delete unused/write-only E1AP variables --- executables/nr-softmodem.c | 2 -- openair2/E1AP/e1ap.c | 1 - openair2/E1AP/e1ap_common.h | 5 ----- 3 files changed, 8 deletions(-) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 553f21a9fb..08e5c1c7f6 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -406,8 +406,6 @@ static int create_gNB_tasks(ngran_node_t node_type) createE1inst(UPtype, inst, &E1AP_SETUP_REQ(msg)); cuup_init_n3(inst); itti_free(TASK_UNKNOWN, msg); - getCxtE1(inst)->same_process = true; - ; RC.nrrrc[gnb_id_start]->e1_inst = inst; // stupid instance !!!*/ } diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 6eebf8f7a9..e8d9807024 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1627,7 +1627,6 @@ void e1_task_handle_sctp_association_ind(E1_t type, instance_t instance, sctp_ne else createE1inst(type, instance, NULL); getCxtE1(instance)->sockState = SCTP_STATE_ESTABLISHED; - getCxtE1(instance)->incoming_sock = true; e1ap_setup_req_t *setup_req = &getCxtE1(instance)->setupReq; setup_req->assoc_id = sctp_new_ind->assoc_id; setup_req->sctp_in_streams = sctp_new_ind->in_streams; diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index cddf5b9ea6..38e7d3ca7c 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -29,17 +29,12 @@ #include "common/ngran_types.h" typedef struct e1ap_upcp_inst_s { - bool incoming_sock; instance_t instance; - bool same_process; E1_t type; enum sctp_state_e sockState; - sctp_assoc_t assoc_id; instance_t gtpInstN3; instance_t gtpInstF1U; e1ap_setup_req_t setupReq; - e1ap_bearer_setup_req_t bearerSetupReq; - e1ap_bearer_setup_resp_t bearerSetupResp; } e1ap_upcp_inst_t; extern int asn1_xer_print; From e37f67ccceed58b64979ec1751336b440e86c5c4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Sep 2023 15:03:20 +0200 Subject: [PATCH 08/40] Make E1AP function check_transac_id() static --- openair2/E1AP/e1ap_common.c | 6 +++--- openair2/E1AP/e1ap_common.h | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index caf97b680d..eaa61330d1 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -59,8 +59,8 @@ void e1ap_common_init() { srand(time(NULL)); } -bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx) { - +static bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx) +{ bool isFreeIdxSet = false; for (int i=0; i < E1AP_MAX_NUM_TRANSAC_IDS; i++) { if (id == transacID[i]) @@ -77,7 +77,7 @@ bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx) { E1AP_TransactionID_t E1AP_get_next_transaction_identifier() { E1AP_TransactionID_t genTransacId; bool isTransacIdValid = false; - int freeIdx; + int freeIdx = 0; while (!isTransacIdValid) { genTransacId = rand() & 255; diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index 38e7d3ca7c..5d66f3cc30 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -47,8 +47,6 @@ E1AP_TransactionID_t E1AP_get_next_transaction_identifier(); void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req); -bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx); - int e1ap_assoc_id(E1_t type, instance_t instance); int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func); From 29212d4e9453696b9a7ae264a8bdc74a12ecb4f8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Sep 2023 15:54:49 +0200 Subject: [PATCH 09/40] E1AP: remove unused functions --- openair2/E1AP/e1ap.c | 7 ------- openair2/E1AP/e1ap_common.c | 5 ----- openair2/E1AP/e1ap_common.h | 2 -- 3 files changed, 14 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index e8d9807024..dd5017dd2c 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -109,13 +109,6 @@ void e1_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_dat AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } -void e1ap_itti_send_sctp_close_association(bool isCu, instance_t instance) { - MessageDef *message = itti_alloc_new_message(TASK_S1AP, 0, SCTP_CLOSE_ASSOCIATION); - sctp_close_association_t *sctp_close_association = &message->ittiMsg.sctp_close_association; - sctp_close_association->assoc_id = e1ap_assoc_id(isCu,instance); - itti_send_msg_to_task(TASK_SCTP, instance, message); -} - int e1ap_send_RESET(bool isCu, e1ap_setup_req_t *setupReq, E1AP_Reset_t *Reset) { AssertFatal(false,"Not implemented yet\n"); diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index eaa61330d1..4fae84d181 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -37,11 +37,6 @@ e1ap_upcp_inst_t *getCxtE1(instance_t instance) return e1ap_inst[instance]; } -int e1ap_assoc_id(E1_t type, instance_t instance) { - AssertFatal(e1ap_inst[instance] != NULL, "Trying to access uninitiated instance of CUCP\n"); - return e1ap_inst[instance]->setupReq.assoc_id; -} - void createE1inst(E1_t type, instance_t instance, 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)); diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index 5d66f3cc30..25b49fa9a1 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -47,8 +47,6 @@ E1AP_TransactionID_t E1AP_get_next_transaction_identifier(); void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req); -int e1ap_assoc_id(E1_t type, instance_t instance); - int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func); void e1ap_common_init(); From 0070bf11fc414201ea460efc5dad5cf7806d6c33 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Sep 2023 16:27:45 +0200 Subject: [PATCH 10/40] Fix fill_BEARER_CONTEXT_SETUP_REQUEST() --- openair2/E1AP/e1ap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index dd5017dd2c..d5d27ac5d8 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -499,7 +499,7 @@ int e1ap_handle_RELEASE_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, BEARER CONTEXT SETUP REQUEST */ -static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_setup_req_t *setup, e1ap_bearer_setup_req_t *const bearerCxt, E1AP_E1AP_PDU_t *pdu) +static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bearerCxt, E1AP_E1AP_PDU_t *pdu) { pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage; asn1cCalloc(pdu->choice.initiatingMessage, msg); @@ -540,7 +540,7 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_setup_req_t *setup, e1ap_beare ieC4->id = E1AP_ProtocolIE_ID_id_Serving_PLMN; ieC4->criticality = E1AP_Criticality_ignore; ieC4->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity; - PLMN_ID_t *servingPLMN = setup->plmns; // First PLMN is serving PLMN. TODO: Remove hard coding here + PLMN_ID_t *servingPLMN = &bearerCxt->servingPLMNid; MCC_MNC_TO_PLMNID(servingPLMN->mcc, servingPLMN->mnc, servingPLMN->mnc_digit_length, &ieC4->value.choice.PLMN_Identity); /* mandatory */ /* Activity Notification Level */ @@ -635,7 +635,7 @@ void e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance, e1ap_bearer E1AP_E1AP_PDU_t pdu = {0}; e1ap_setup_req_t *setupReq = &getCxtE1(instance)->setupReq; - fill_BEARER_CONTEXT_SETUP_REQUEST(setupReq, bearerCxt, &pdu); + fill_BEARER_CONTEXT_SETUP_REQUEST(bearerCxt, &pdu); e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__); } From d1e5ee2bab488cfdcdbe8b58f106d0b447d7401d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 28 Sep 2023 18:39:18 +0200 Subject: [PATCH 11/40] extract_SETUP_REQUEST(): assoc_id: remove comment --- openair2/E1AP/e1ap.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index d5d27ac5d8..1d0d6f7156 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -268,8 +268,6 @@ void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_setup_req_t *req) { E1AP_GNB_CU_UP_E1SetupRequestIEs_t *ie; E1AP_GNB_CU_UP_E1SetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.GNB_CU_UP_E1SetupRequest; - /* assoc_id */ - /* req->assoc_id = assoc_id; */ /* transac_id */ F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, From 5215cc921ffed6688b0b6224eac91351f122c557 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 27 Sep 2023 18:32:37 +0200 Subject: [PATCH 12/40] Lower E1AP log verbosity --- openair2/E1AP/e1ap.c | 18 +++++++++--------- openair2/E1AP/e1ap_common.c | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 1d0d6f7156..7e13a8ad93 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -91,7 +91,7 @@ int e1ap_handle_message(instance_t instance, sctp_assoc_t assoc_id, const uint8_ ret=-1; } else { /* Calling the right handler */ - LOG_I(E1AP, "Calling handler with instance %ld\n",instance); + LOG_D(E1AP, "Calling handler with instance %ld\n",instance); ret = (*e1ap_message_processing[procedureCode][pdu.present - 1])(getCxtE1(instance), &pdu); } @@ -170,7 +170,7 @@ static void fill_SETUP_REQUEST(e1ap_setup_req_t *setup, E1AP_E1AP_PDU_t *pdu) ieC1->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_TransactionID; setup->transac_id = E1AP_get_next_transaction_identifier(); ieC1->value.choice.TransactionID = setup->transac_id; - LOG_I(E1AP, "Transaction ID of setup request %ld\n", setup->transac_id); + LOG_D(E1AP, "Transaction ID of setup request %ld\n", setup->transac_id); /* mandatory */ /* c2. GNB_CU_ID (integer value) */ asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC2); @@ -781,7 +781,7 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, const E1AP_BearerContextSetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest; E1AP_BearerContextSetupRequestIEs_t *ie; - LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); + LOG_D(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); for (int i=0; i < in->protocolIEs.list.count; i++) { ie = in->protocolIEs.list.array[i]; @@ -955,7 +955,7 @@ void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu, const E1AP_BearerContextSetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse; E1AP_BearerContextSetupResponseIEs_t *ie; - LOG_I(E1AP, "Bearer context setup response number of IEs %d\n", in->protocolIEs.list.count); + LOG_D(E1AP, "Bearer context setup response number of IEs %d\n", in->protocolIEs.list.count); for (int i=0; i < in->protocolIEs.list.count; i++) { ie = in->protocolIEs.list.array[i]; @@ -1149,7 +1149,7 @@ void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu, const E1AP_BearerContextModificationRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextModificationRequest; E1AP_BearerContextModificationRequestIEs_t *ie; - LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); + LOG_D(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); for (int i=0; i < in->protocolIEs.list.count; i++) { ie = in->protocolIEs.list.array[i]; @@ -1361,7 +1361,7 @@ void extract_BEARER_CONTEXT_RELEASE_COMMAND(const E1AP_E1AP_PDU_t *pdu, const E1AP_BearerContextReleaseCommand_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextReleaseCommand; E1AP_BearerContextReleaseCommandIEs_t *ie; - LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); + LOG_D(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); for (int i=0; i < in->protocolIEs.list.count; i++) { ie = in->protocolIEs.list.array[i]; @@ -1414,7 +1414,7 @@ void extract_BEARER_CONTEXT_RELEASE_COMPLETE(const E1AP_E1AP_PDU_t *pdu, const E1AP_BearerContextReleaseComplete_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextReleaseComplete; E1AP_BearerContextReleaseCompleteIEs_t *ie; - LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); + LOG_D(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); for (int i=0; i < in->protocolIEs.list.count; i++) { ie = in->protocolIEs.list.array[i]; @@ -1642,7 +1642,7 @@ void *E1AP_CUCP_task(void *arg) { itti_receive_msg(TASK_CUCP_E1, &msg); instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg); const int msgType = ITTI_MSG_ID(msg); - LOG_I(E1AP, "CUCP received %s for instance %ld\n", messages_info[msgType].name, myInstance); + LOG_D(E1AP, "CUCP received %s for instance %ld\n", messages_info[msgType].name, myInstance); switch (ITTI_MSG_ID(msg)) { case SCTP_NEW_ASSOCIATION_IND: @@ -1701,7 +1701,7 @@ void *E1AP_CUUP_task(void *arg) { itti_receive_msg(TASK_CUUP_E1, &msg); const instance_t myInstance = ITTI_MSG_DESTINATION_INSTANCE(msg); const int msgType = ITTI_MSG_ID(msg); - LOG_I(E1AP, "CUUP received %s for instance %ld\n", messages_info[msgType].name, myInstance); + LOG_D(E1AP, "CUUP received %s for instance %ld\n", messages_info[msgType].name, myInstance); switch (msgType) { case E1AP_SETUP_REQ: { e1ap_setup_req_t *msgSetup = &E1AP_SETUP_REQ(msg); diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 4fae84d181..5234ff58e7 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -222,7 +222,7 @@ int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu s->buffer = buffer; s->buffer_length = encoded; s->stream = stream; - LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func); + LOG_D(E1AP, "%s: Sending ITTI message to SCTP Task\n", func); itti_send_msg_to_task(TASK_SCTP, 0 /*unused by callee*/, message); return encoded; From e4a28cfabd4da200688fb1acb7f293b72647ce96 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Sep 2023 18:28:25 +0200 Subject: [PATCH 13/40] Remove unused variables --- openair2/COMMON/e1ap_messages_types.h | 6 ++---- openair2/E1AP/e1ap.c | 8 -------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 993a93bb38..e08660059c 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -57,13 +57,11 @@ typedef struct PLMN_ID_s { typedef struct e1ap_setup_req_s { uint64_t gNB_cu_up_id; char * gNB_cu_up_name; - sctp_assoc_t assoc_id; uint64_t transac_id; int supported_plmns; PLMN_ID_t plmns[E1AP_MAX_NUM_PLMNS]; - uint16_t sctp_in_streams; - uint16_t sctp_out_streams; - uint16_t default_sctp_stream_id; + + sctp_assoc_t assoc_id; net_ip_address_t CUUP_e1_ip_address; net_ip_address_t CUCP_e1_ip_address; uint16_t remotePortF1U; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 7e13a8ad93..d325995f93 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1521,8 +1521,6 @@ static void e1_task_send_sctp_association_req(long task_id, instance_t instance, sctp_new_req->ulp_cnx_id = instance; sctp_new_req->port = E1AP_PORT_NUMBER; sctp_new_req->ppid = E1AP_SCTP_PPID; - sctp_new_req->in_streams = e1ap_setup_req->sctp_in_streams; - sctp_new_req->out_streams = e1ap_setup_req->sctp_out_streams; // remote sctp_new_req->remote_address = e1ap_setup_req->CUCP_e1_ip_address; // local @@ -1554,9 +1552,6 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, if (type == UPtype) { e1ap_setup_req_t *e1ap_cuup_setup_req = &getCxtE1(instance)->setupReq; e1ap_cuup_setup_req->assoc_id = sctp_new_association_resp->assoc_id; - e1ap_cuup_setup_req->sctp_in_streams = sctp_new_association_resp->in_streams; - e1ap_cuup_setup_req->sctp_out_streams = sctp_new_association_resp->out_streams; - e1ap_cuup_setup_req->default_sctp_stream_id = 0; eth_params_t IPaddr; IPaddr.my_addr = e1ap_cuup_setup_req->localAddressF1U; @@ -1620,9 +1615,6 @@ void e1_task_handle_sctp_association_ind(E1_t type, instance_t instance, sctp_ne getCxtE1(instance)->sockState = SCTP_STATE_ESTABLISHED; e1ap_setup_req_t *setup_req = &getCxtE1(instance)->setupReq; setup_req->assoc_id = sctp_new_ind->assoc_id; - setup_req->sctp_in_streams = sctp_new_ind->in_streams; - setup_req->sctp_out_streams = sctp_new_ind->out_streams; - setup_req->default_sctp_stream_id = 0; } void e1apHandleTimer(instance_t myInstance) From 5c07c326ea192be85d9e29813f5e1268311805b5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Sep 2023 15:19:28 +0200 Subject: [PATCH 14/40] E1AP: use assoc_id in instance, do not pass Setup Request around - e1ap_encode_send(): do not use E1AP Setup Request - store assoc_id in the instance, and reuse that --- openair2/COMMON/e1ap_messages_types.h | 1 - openair2/E1AP/e1ap.c | 98 ++++++++++++--------------- openair2/E1AP/e1ap.h | 4 +- openair2/E1AP/e1ap_api.c | 4 +- openair2/E1AP/e1ap_common.c | 5 +- openair2/E1AP/e1ap_common.h | 3 +- 6 files changed, 53 insertions(+), 62 deletions(-) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index e08660059c..0a9cb302d2 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -61,7 +61,6 @@ typedef struct e1ap_setup_req_s { int supported_plmns; PLMN_ID_t plmns[E1AP_MAX_NUM_PLMNS]; - sctp_assoc_t assoc_id; net_ip_address_t CUUP_e1_ip_address; net_ip_address_t CUCP_e1_ip_address; uint16_t remotePortF1U; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index d325995f93..08901b0e04 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -109,11 +109,11 @@ void e1_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_dat AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } -int e1ap_send_RESET(bool isCu, e1ap_setup_req_t *setupReq, E1AP_Reset_t *Reset) +int e1ap_send_RESET(bool isCu, sctp_assoc_t assoc_id, E1AP_Reset_t *Reset) { AssertFatal(false,"Not implemented yet\n"); E1AP_E1AP_PDU_t pdu= {0}; - return e1ap_encode_send(isCu, setupReq, &pdu, 0, __func__); + return e1ap_encode_send(isCu, assoc_id, &pdu, 0, __func__); } int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset) { @@ -221,13 +221,11 @@ static void fill_SETUP_RESPONSE(const e1ap_setup_resp_t *e1ap_setup_resp, E1AP_E ieC1->value.choice.TransactionID = e1ap_setup_resp->transac_id; } -void e1ap_send_SETUP_RESPONSE(instance_t inst, const e1ap_setup_resp_t *e1ap_setup_resp) +void e1ap_send_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1ap_setup_resp_t *e1ap_setup_resp) { - AssertFatal(getCxtE1(inst), ""); - e1ap_setup_req_t *setupReq = &getCxtE1(inst)->setupReq; E1AP_E1AP_PDU_t pdu = {0}; fill_SETUP_RESPONSE(e1ap_setup_resp, &pdu); - e1ap_encode_send(getCxtE1(inst)->type, setupReq, &pdu, 0, __func__); + e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu) @@ -257,11 +255,11 @@ static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu) ieC2->value.choice.Cause.choice.radioNetwork = E1AP_CauseRadioNetwork_unspecified; } -void e1apCUCP_send_SETUP_FAILURE(e1ap_setup_req_t *setupReq, long transac_id) +void e1apCUCP_send_SETUP_FAILURE(sctp_assoc_t assoc_id, long transac_id) { E1AP_E1AP_PDU_t pdu = {0}; fill_SETUP_FAILURE(transac_id, &pdu); - e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__); + e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, @@ -315,7 +313,7 @@ int e1apCUCP_handle_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t if (inst->setupReq.supported_plmns > 0) { itti_send_msg_to_task(TASK_RRC_GNB, 0 /*unused by callee*/, msg_p); } else { - e1apCUCP_send_SETUP_FAILURE(&inst->setupReq, inst->setupReq.transac_id); + e1apCUCP_send_SETUP_FAILURE(inst->assoc_id, inst->setupReq.transac_id); itti_free(TASK_CUCP_E1, msg_p); return -1; } @@ -418,26 +416,26 @@ static void fill_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu) E1 configuration update: can be sent in both ways, to be refined */ -void e1apCUUP_send_CONFIGURATION_UPDATE(e1ap_setup_req_t *setupReq) +void e1apCUUP_send_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id) { E1AP_E1AP_PDU_t pdu = {0}; fill_CONFIGURATION_UPDATE(&pdu); - e1ap_encode_send(UPtype, setupReq, &pdu, 0, __func__); + e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__); } -int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(e1ap_setup_req_t *setupReq) +int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(void) { AssertFatal(false,"Not implemented yet\n"); return -1; } -int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(e1ap_setup_req_t *setupReq) +int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(void) { AssertFatal(false,"Not implemented yet\n"); return -1; } -int e1apCUCP_handle_CONFIGURATION_UPDATE(e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu) +int e1apCUCP_handle_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu) { /* E1AP_GNB_CU_UP_E1SetupRequestIEs_t *ie; @@ -449,8 +447,7 @@ int e1apCUCP_handle_CONFIGURATION_UPDATE(e1ap_setup_req_t *setupReq, E1AP_E1AP_P return -1; } -int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(e1ap_setup_req_t *setupReq, - sctp_assoc_t assoc_id, +int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { @@ -458,8 +455,7 @@ int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(e1ap_setup_req_t *se return -1; } -int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(e1ap_setup_req_t *setupReq, - sctp_assoc_t assoc_id, +int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { @@ -623,18 +619,11 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear return 0; } -void e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance, e1ap_bearer_setup_req_t *const bearerCxt) +void e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const bearerCxt) { - if (!getCxtE1(instance)) { - LOG_E(E1AP, "Received a UE bearer to establish while no CU-UP is connected, response on NGAP to send failure is not developped\n"); - // Fixme: add response on NGAP to send failure - return; - } - E1AP_E1AP_PDU_t pdu = {0}; - e1ap_setup_req_t *setupReq = &getCxtE1(instance)->setupReq; fill_BEARER_CONTEXT_SETUP_REQUEST(bearerCxt, &pdu); - e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__); + e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const resp, E1AP_E1AP_PDU_t *pdu) @@ -764,11 +753,11 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const r } } -void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, e1ap_bearer_setup_resp_t *const resp) +void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_bearer_setup_resp_t *const resp) { E1AP_E1AP_PDU_t pdu = {0}; fill_BEARER_CONTEXT_SETUP_RESPONSE(resp, &pdu); - e1ap_encode_send(UPtype, &inst->setupReq, &pdu, 0, __func__); + e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__); } int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance) { @@ -1063,7 +1052,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E BEARER CONTEXT MODIFICATION REQUEST */ -static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_setup_req_t *setupReq, e1ap_bearer_setup_req_t *const bearerCxt, E1AP_E1AP_PDU_t *pdu) +static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *const bearerCxt, E1AP_E1AP_PDU_t *pdu) { pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage; asn1cCalloc(pdu->choice.initiatingMessage, msg); @@ -1125,13 +1114,11 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_setup_req_t *setupReq, return 0; } -static void e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t inst, e1ap_bearer_setup_req_t *const bearerCxt) +static void e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const bearerCxt) { - AssertFatal(getCxtE1(inst), ""); - e1ap_setup_req_t *setupReq = &getCxtE1(inst)->setupReq; E1AP_E1AP_PDU_t pdu = {0}; - fill_BEARER_CONTEXT_MODIFICATION_REQUEST(setupReq, bearerCxt, &pdu); - e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__); + fill_BEARER_CONTEXT_MODIFICATION_REQUEST(bearerCxt, &pdu); + e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { @@ -1285,7 +1272,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, BEARER CONTEXT RELEASE */ -static int fill_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_setup_req_t *setupReq, e1ap_bearer_release_cmd_t *const cmd, E1AP_E1AP_PDU_t *pdu) +static int fill_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_bearer_release_cmd_t *const cmd, E1AP_E1AP_PDU_t *pdu) { pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage; asn1cCalloc(pdu->choice.initiatingMessage, msg); @@ -1311,14 +1298,14 @@ static int fill_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_setup_req_t *setupReq, e1ap_ return 0; } -int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_setup_req_t *setupReq, e1ap_bearer_release_cmd_t *const cmd) +int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_bearer_release_cmd_t *const cmd) { E1AP_E1AP_PDU_t pdu = {0}; - fill_BEARER_CONTEXT_RELEASE_COMMAND(setupReq, cmd, &pdu); - return e1ap_encode_send(CPtype, setupReq, &pdu, 0, __func__); + fill_BEARER_CONTEXT_RELEASE_COMMAND(cmd, &pdu); + return e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } -int fill_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_setup_req_t *setupReq, e1ap_bearer_release_cmd_t *const cmd, E1AP_E1AP_PDU_t *pdu) +static int fill_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_bearer_release_cmd_t *const cmd, E1AP_E1AP_PDU_t *pdu) { pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome; asn1cCalloc(pdu->choice.successfulOutcome, msg); @@ -1344,11 +1331,11 @@ int fill_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_setup_req_t *setupReq, e1ap_bearer return 0; } -int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, e1ap_bearer_release_cmd_t *const cmd) +int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_bearer_release_cmd_t *const cmd) { E1AP_E1AP_PDU_t pdu = {0}; - fill_BEARER_CONTEXT_RELEASE_COMPLETE(&inst->setupReq, cmd, &pdu); - return e1ap_encode_send(CPtype, &inst->setupReq, &pdu, 0, __func__); + fill_BEARER_CONTEXT_RELEASE_COMPLETE(cmd, &pdu); + return e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance) { @@ -1528,11 +1515,11 @@ static void e1_task_send_sctp_association_req(long task_id, instance_t instance, itti_send_msg_to_task(TASK_SCTP, instance, message_p); } -static void e1apCUUP_send_SETUP_REQUEST(e1ap_setup_req_t *setup) +static void e1apCUUP_send_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_setup_req_t *setup) { E1AP_E1AP_PDU_t pdu = {0}; fill_SETUP_REQUEST(setup, &pdu); - e1ap_encode_send(UPtype, setup, &pdu, 0, __func__); + e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__); } static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) @@ -1550,9 +1537,10 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, } if (type == UPtype) { - e1ap_setup_req_t *e1ap_cuup_setup_req = &getCxtE1(instance)->setupReq; - e1ap_cuup_setup_req->assoc_id = sctp_new_association_resp->assoc_id; + e1ap_upcp_inst_t *inst = getCxtE1(instance); + inst->assoc_id = sctp_new_association_resp->assoc_id; + e1ap_setup_req_t *e1ap_cuup_setup_req = &inst->setupReq; eth_params_t IPaddr; IPaddr.my_addr = e1ap_cuup_setup_req->localAddressF1U; IPaddr.my_portd = e1ap_cuup_setup_req->localPortF1U; @@ -1563,7 +1551,7 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, extern instance_t CUuniqInstance; CUuniqInstance = getCxtE1(instance)->gtpInstF1U; cuup_init_n3(instance); - e1apCUUP_send_SETUP_REQUEST(&getCxtE1(instance)->setupReq); + e1apCUUP_send_SETUP_REQUEST(inst->assoc_id, e1ap_cuup_setup_req); } } @@ -1612,9 +1600,9 @@ void e1_task_handle_sctp_association_ind(E1_t type, instance_t instance, sctp_ne LOG_W(E1AP, "CUCP incoming call, re-use older socket context, finish implementation required\n"); else createE1inst(type, instance, NULL); - getCxtE1(instance)->sockState = SCTP_STATE_ESTABLISHED; - e1ap_setup_req_t *setup_req = &getCxtE1(instance)->setupReq; - setup_req->assoc_id = sctp_new_ind->assoc_id; + e1ap_upcp_inst_t *inst = getCxtE1(instance); + inst->sockState = SCTP_STATE_ESTABLISHED; + inst->assoc_id = sctp_new_ind->assoc_id; } void e1apHandleTimer(instance_t myInstance) @@ -1635,6 +1623,8 @@ void *E1AP_CUCP_task(void *arg) { instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg); const int msgType = ITTI_MSG_ID(msg); LOG_D(E1AP, "CUCP received %s for instance %ld\n", messages_info[msgType].name, myInstance); + /* TODO get the assoc ID through the ITTI message to address multiple CU-UPs */ + e1ap_upcp_inst_t *inst = getCxtE1(myInstance); switch (ITTI_MSG_ID(msg)) { case SCTP_NEW_ASSOCIATION_IND: @@ -1659,15 +1649,15 @@ void *E1AP_CUCP_task(void *arg) { break; case E1AP_SETUP_RESP: - e1ap_send_SETUP_RESPONSE(myInstance, &E1AP_SETUP_RESP(msg)); + e1ap_send_SETUP_RESPONSE(inst->assoc_id, &E1AP_SETUP_RESP(msg)); break; case E1AP_BEARER_CONTEXT_SETUP_REQ: - e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(myInstance, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); + e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(inst->assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); break; case E1AP_BEARER_CONTEXT_MODIFICATION_REQ: - e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(myInstance, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); + e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(inst->assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); break; default: diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h index af1dcae363..f5ba9350d7 100644 --- a/openair2/E1AP/e1ap.h +++ b/openair2/E1AP/e1ap.h @@ -42,13 +42,13 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, e1ap_bearer_setup_resp_t *const resp); +void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_bearer_setup_resp_t *const resp); int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, e1ap_bearer_release_cmd_t *const cmd); +int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_bearer_release_cmd_t *const cmd); void *E1AP_CUUP_task(void *arg); diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index 9cec6b69f3..b6fb023780 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -172,7 +172,7 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_ pduSetup->numDRBFailed = 0; } - e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst, resp); + e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst->assoc_id, resp); } void CUUP_process_bearer_context_mod_req(instance_t instance, e1ap_bearer_setup_req_t *const req) @@ -190,5 +190,5 @@ void CUUP_process_bearer_release_command(instance_t instance, e1ap_bearer_releas AssertFatal(inst, ""); newGtpuDeleteAllTunnels(inst->gtpInstN3, cmd->gNB_cu_up_ue_id); newGtpuDeleteAllTunnels(inst->gtpInstF1U, cmd->gNB_cu_up_ue_id); - e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst, cmd); + e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst->assoc_id, cmd); } diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 5234ff58e7..51ff6744c2 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -42,6 +42,7 @@ void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req) { e1ap_inst[instance] = calloc(1, sizeof(e1ap_upcp_inst_t)); e1ap_inst[instance]->type = type; e1ap_inst[instance]->instance = instance; + e1ap_inst[instance]->assoc_id = -1; if (req) memcpy(&e1ap_inst[instance]->setupReq, req, sizeof(*req)); e1ap_inst[instance]->gtpInstN3 = -1; @@ -190,7 +191,7 @@ int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t return -1; } -int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func) +int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func) { DevAssert(pdu != NULL); @@ -218,7 +219,7 @@ int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu } MessageDef *message = itti_alloc_new_message((type == CPtype) ? TASK_CUCP_E1 : TASK_CUUP_E1, 0, SCTP_DATA_REQ); sctp_data_req_t *s = &message->ittiMsg.sctp_data_req; - s->assoc_id = setupReq->assoc_id; + s->assoc_id = assoc_id; s->buffer = buffer; s->buffer_length = encoded; s->stream = stream; diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index 25b49fa9a1..82f5c8cd57 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -32,6 +32,7 @@ typedef struct e1ap_upcp_inst_s { instance_t instance; E1_t type; enum sctp_state_e sockState; + sctp_assoc_t assoc_id; instance_t gtpInstN3; instance_t gtpInstF1U; e1ap_setup_req_t setupReq; @@ -47,7 +48,7 @@ E1AP_TransactionID_t E1AP_get_next_transaction_identifier(); void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req); -int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func); +int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func); void e1ap_common_init(); From a23984c7aef8a431b04696a430511eae633b60cb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 27 Sep 2023 09:00:11 +0200 Subject: [PATCH 15/40] Split out E1AP net config from Setup Request The E1AP Setup Request contained the network configuration (IP address, ports) as well as the actual E1AP Setup Request application data (Supported PLMNs, ...). This has the drawbacks that - The E1AP Setup Request is stored to retrieve IP addresses in the E1AP module, which is confusing as the Setup Request, per standard, has no IP info - The CU-CP received an E1 Setup Request for configuration during start up, but it did not actually receive such Setup Request, but merely the IP configuration to set up the socket This commit splits the E1AP Setup Request into a "real" Setup Request for application data, and creates a new type e1ap_net_config_t to group all IP configuration data. Further, a new ITTI message type E1AP_REGISTER_REQ is introduced to group both types. What happens is - RCconfig_NR_CU_E1() reads both E1AP application-level data and IP configuration, as previously - The data is sent to the CU-CP. It discards the E1AP Setup Request data, and only uses the network configuration to set up the socket - The data is sent to the CU-UP. It uses the network configuration to connect to the CU-CP, and then sends the E1AP Setup Request to the CU-CP. Currently, the CU-CP still stores the Setup Request locally, which will be changed in the next commit to send it to the RRC. --- executables/nr-softmodem.c | 2 +- openair2/COMMON/e1ap_messages_def.h | 3 ++ openair2/COMMON/e1ap_messages_types.h | 22 +++++++---- openair2/E1AP/e1ap.c | 55 ++++++++++++++------------- openair2/E1AP/e1ap_api.c | 10 ++--- openair2/E1AP/e1ap_common.c | 5 ++- openair2/E1AP/e1ap_common.h | 3 +- openair2/E1AP/e1ap_setup.c | 24 ++++++------ openair2/GNB_APP/gnb_app.c | 8 ++-- 9 files changed, 76 insertions(+), 56 deletions(-) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 08e5c1c7f6..a1a97373e8 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -403,7 +403,7 @@ static int create_gNB_tasks(ngran_node_t node_type) if (node_type == ngran_gNB_CU || node_type == ngran_gNB) { MessageDef *msg = RCconfig_NR_CU_E1(false); instance_t inst = 0; - createE1inst(UPtype, inst, &E1AP_SETUP_REQ(msg)); + createE1inst(UPtype, inst, &E1AP_REGISTER_REQ(msg).net_config, NULL); cuup_init_n3(inst); itti_free(TASK_UNKNOWN, msg); RC.nrrrc[gnb_id_start]->e1_inst = inst; // stupid instance !!!*/ diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h index 70533f8add..fdfa071a7f 100644 --- a/openair2/COMMON/e1ap_messages_def.h +++ b/openair2/COMMON/e1ap_messages_def.h @@ -20,6 +20,9 @@ */ /* gNB_CUUP application layer -> E1AP messages */ +MESSAGE_DEF(E1AP_REGISTER_REQ, MESSAGE_PRIORITY_MED, e1ap_register_req_t, e1ap_register_req) + +/* E1AP messages -> RRC (CU-CP) */ MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_setup_req) /* E1AP -> eNB_DU or eNB_CU_RRC -> E1AP application layer messages */ diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 0a9cb302d2..0fe07ea910 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -40,6 +40,7 @@ #define E1AP_MAX_NUM_DRBS 4 #define E1AP_MAX_NUM_UP_PARAM 4 +#define E1AP_REGISTER_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_register_req #define E1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_req #define E1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_resp #define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req @@ -54,13 +55,7 @@ typedef struct PLMN_ID_s { int mnc_digit_length; } PLMN_ID_t; -typedef struct e1ap_setup_req_s { - uint64_t gNB_cu_up_id; - char * gNB_cu_up_name; - uint64_t transac_id; - int supported_plmns; - PLMN_ID_t plmns[E1AP_MAX_NUM_PLMNS]; - +typedef struct e1ap_net_config_t { net_ip_address_t CUUP_e1_ip_address; net_ip_address_t CUCP_e1_ip_address; uint16_t remotePortF1U; @@ -69,8 +64,21 @@ typedef struct e1ap_setup_req_s { char* localAddressN3; uint16_t localPortN3; uint16_t remotePortN3; +} e1ap_net_config_t; + +typedef struct e1ap_setup_req_s { + uint64_t gNB_cu_up_id; + char * gNB_cu_up_name; + uint64_t transac_id; + int supported_plmns; + PLMN_ID_t plmns[E1AP_MAX_NUM_PLMNS]; } e1ap_setup_req_t; +typedef struct e1ap_register_req_t { + e1ap_setup_req_t setup_req; + e1ap_net_config_t net_config; +} e1ap_register_req_t; + typedef struct e1ap_setup_resp_s { long transac_id; } e1ap_setup_resp_t; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 08901b0e04..73b804cddf 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1499,9 +1499,9 @@ static instance_t cuup_task_create_gtpu_instance_to_du(eth_params_t *IPaddrs) { return gtpv1Init(tmp); } -static void e1_task_send_sctp_association_req(long task_id, instance_t instance, e1ap_setup_req_t *e1ap_setup_req) +static void e1_task_send_sctp_association_req(long task_id, instance_t instance, e1ap_net_config_t *e1ap_nc) { - DevAssert(e1ap_setup_req != NULL); + DevAssert(e1ap_nc != NULL); getCxtE1(instance)->sockState = SCTP_STATE_CLOSED; MessageDef *message_p = itti_alloc_new_message(task_id, 0, SCTP_NEW_ASSOCIATION_REQ); sctp_new_association_req_t *sctp_new_req = &message_p->ittiMsg.sctp_new_association_req; @@ -1509,9 +1509,9 @@ static void e1_task_send_sctp_association_req(long task_id, instance_t instance, sctp_new_req->port = E1AP_PORT_NUMBER; sctp_new_req->ppid = E1AP_SCTP_PPID; // remote - sctp_new_req->remote_address = e1ap_setup_req->CUCP_e1_ip_address; + sctp_new_req->remote_address = e1ap_nc->CUCP_e1_ip_address; // local - sctp_new_req->local_address = e1ap_setup_req->CUUP_e1_ip_address; + sctp_new_req->local_address = e1ap_nc->CUUP_e1_ip_address; itti_send_msg_to_task(TASK_SCTP, instance, message_p); } @@ -1540,10 +1540,10 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, e1ap_upcp_inst_t *inst = getCxtE1(instance); inst->assoc_id = sctp_new_association_resp->assoc_id; - e1ap_setup_req_t *e1ap_cuup_setup_req = &inst->setupReq; + e1ap_net_config_t *nc = &inst->net_config; eth_params_t IPaddr; - IPaddr.my_addr = e1ap_cuup_setup_req->localAddressF1U; - IPaddr.my_portd = e1ap_cuup_setup_req->localPortF1U; + IPaddr.my_addr = nc->localAddressF1U; + IPaddr.my_portd = nc->localPortF1U; if (getCxtE1(instance)->gtpInstF1U < 0) getCxtE1(instance)->gtpInstF1U = cuup_task_create_gtpu_instance_to_du(&IPaddr); if (getCxtE1(instance)->gtpInstF1U < 0) @@ -1551,18 +1551,18 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, extern instance_t CUuniqInstance; CUuniqInstance = getCxtE1(instance)->gtpInstF1U; cuup_init_n3(instance); - e1apCUUP_send_SETUP_REQUEST(inst->assoc_id, e1ap_cuup_setup_req); + e1apCUUP_send_SETUP_REQUEST(inst->assoc_id, &inst->setupReq); } } void cuup_init_n3(instance_t instance) { if (getCxtE1(instance)->gtpInstN3 < 0) { - e1ap_setup_req_t *setup = &getCxtE1(instance)->setupReq; + e1ap_net_config_t *nc = &getCxtE1(instance)->net_config; openAddr_t tmp = {0}; - strcpy(tmp.originHost, setup->localAddressN3); - sprintf(tmp.originService, "%d", setup->localPortN3); - sprintf(tmp.destinationService, "%d", setup->remotePortN3); + strcpy(tmp.originHost, nc->localAddressN3); + sprintf(tmp.originService, "%d", nc->localPortN3); + sprintf(tmp.destinationService, "%d", nc->remotePortN3); LOG_I(GTPU, "Configuring GTPu address : %s, port : %s\n", tmp.originHost, tmp.originService); // Fixme: fully inconsistent instances management // dirty global var is a bad fix @@ -1599,7 +1599,7 @@ void e1_task_handle_sctp_association_ind(E1_t type, instance_t instance, sctp_ne if (getCxtE1(instance)) LOG_W(E1AP, "CUCP incoming call, re-use older socket context, finish implementation required\n"); else - createE1inst(type, instance, NULL); + createE1inst(type, instance, NULL, NULL); e1ap_upcp_inst_t *inst = getCxtE1(instance); inst->sockState = SCTP_STATE_ESTABLISHED; inst->assoc_id = sctp_new_ind->assoc_id; @@ -1609,7 +1609,7 @@ void e1apHandleTimer(instance_t myInstance) { LOG_W(E1AP, "Try to reconnect to CP\n"); if (getCxtE1(myInstance)->sockState != SCTP_STATE_ESTABLISHED) - e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, &getCxtE1(myInstance)->setupReq); + e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, &getCxtE1(myInstance)->net_config); } void *E1AP_CUCP_task(void *arg) { @@ -1635,15 +1635,19 @@ void *E1AP_CUCP_task(void *arg) { e1_task_handle_sctp_association_resp(CPtype, ITTI_MSG_ORIGIN_INSTANCE(msg), &msg->ittiMsg.sctp_new_association_resp); break; - case E1AP_SETUP_REQ: { - e1ap_setup_req_t *req = &E1AP_SETUP_REQ(msg); - if (req->CUCP_e1_ip_address.ipv4 == 0) { - LOG_E(E1AP, "No IPv4 address configured\n"); - return NULL; - } - cucp_task_send_sctp_init_req(0, req->CUCP_e1_ip_address.ipv4_address); + case E1AP_REGISTER_REQ: { + // note: we use E1AP_REGISTER_REQ only to set up sockets, the + // E1AP_SETUP_REQ is not used and comes through the socket from the + // CU-UP later! + e1ap_net_config_t *nc = &E1AP_REGISTER_REQ(msg).net_config; + AssertFatal(nc->CUCP_e1_ip_address.ipv4 != 0, "No IPv4 address configured\n"); + cucp_task_send_sctp_init_req(0, nc->CUCP_e1_ip_address.ipv4_address); } break; + case E1AP_SETUP_REQ: + AssertFatal(false, "should not receive E1AP_SETUP_REQ in CU-CP!\n"); + break; + case SCTP_DATA_IND: e1_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind); break; @@ -1685,11 +1689,10 @@ void *E1AP_CUUP_task(void *arg) { const int msgType = ITTI_MSG_ID(msg); LOG_D(E1AP, "CUUP received %s for instance %ld\n", messages_info[msgType].name, myInstance); switch (msgType) { - case E1AP_SETUP_REQ: { - e1ap_setup_req_t *msgSetup = &E1AP_SETUP_REQ(msg); - createE1inst(UPtype, myInstance, msgSetup); - - e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, msgSetup); + case E1AP_REGISTER_REQ: { + e1ap_register_req_t *reg_req = &E1AP_REGISTER_REQ(msg); + createE1inst(UPtype, myInstance, ®_req->net_config, ®_req->setup_req); + e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, ®_req->net_config); } break; case SCTP_NEW_ASSOCIATION_RESP: diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index b6fb023780..9096a9faf7 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -149,9 +149,9 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_ e1ap_bearer_setup_resp_t *resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg); in_addr_t my_addr; - if (inet_pton(AF_INET, inst->setupReq.localAddressF1U, &my_addr) != 1) - LOG_E(E1AP, "can't use the F1-U local interface: %s\n", inst->setupReq.localAddressF1U); - fill_e1ap_bearer_setup_resp(resp, req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id, inst->setupReq.remotePortF1U, my_addr); + if (inet_pton(AF_INET, inst->net_config.localAddressF1U, &my_addr) != 1) + LOG_E(E1AP, "can't use the F1-U local interface: %s\n", inst->net_config.localAddressF1U); + fill_e1ap_bearer_setup_resp(resp, req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id, inst->net_config.remotePortF1U, my_addr); resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id; resp->gNB_cu_up_ue_id = gNB_cu_up_ue_id; @@ -161,8 +161,8 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_ pdu_session_to_setup_t *pdu2Setup = req->pduSession + i; pduSetup->id = pdu2Setup->sessionId; - if (inet_pton(AF_INET, inst->setupReq.localAddressN3, &pduSetup->tlAddress) != 1) - LOG_E(E1AP, "can't use the N3 local interface: %s\n", inst->setupReq.localAddressN3); + if (inet_pton(AF_INET, inst->net_config.localAddressN3, &pduSetup->tlAddress) != 1) + LOG_E(E1AP, "can't use the N3 local interface: %s\n", inst->net_config.localAddressN3); pduSetup->teId = create_tunnel_resp_N3.gnb_NGu_teid[i]; pduSetup->numDRBSetup = pdu2Setup->numDRB2Setup; diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 51ff6744c2..71e93221ab 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -37,12 +37,15 @@ e1ap_upcp_inst_t *getCxtE1(instance_t instance) return e1ap_inst[instance]; } -void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req) { +void createE1inst(E1_t type, instance_t instance, 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]->assoc_id = -1; + if (nc) + memcpy(&e1ap_inst[instance]->net_config, nc, sizeof(*nc)); if (req) memcpy(&e1ap_inst[instance]->setupReq, req, sizeof(*req)); e1ap_inst[instance]->gtpInstN3 = -1; diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index 82f5c8cd57..0159b92a97 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -36,6 +36,7 @@ typedef struct e1ap_upcp_inst_s { instance_t gtpInstN3; instance_t gtpInstF1U; e1ap_setup_req_t setupReq; + e1ap_net_config_t net_config; } e1ap_upcp_inst_t; extern int asn1_xer_print; @@ -46,7 +47,7 @@ e1ap_upcp_inst_t *getCxtE1(instance_t instance); E1AP_TransactionID_t E1AP_get_next_transaction_identifier(); -void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req); +void createE1inst(E1_t type, instance_t instance, e1ap_net_config_t *nc, e1ap_setup_req_t *req); int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func); diff --git a/openair2/E1AP/e1ap_setup.c b/openair2/E1AP/e1ap_setup.c index 324f5b87e2..64b9ebab80 100644 --- a/openair2/E1AP/e1ap_setup.c +++ b/openair2/E1AP/e1ap_setup.c @@ -68,7 +68,7 @@ static void get_NGU_S1U_addr(char **addr, uint16_t *port) MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process) { - MessageDef *msgConfig = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ); + MessageDef *msgConfig = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_REGISTER_REQ); if (!msgConfig) return NULL; @@ -85,7 +85,7 @@ MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process) config_getlist(&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_SETUP_REQ(msgConfig); + 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); @@ -106,22 +106,24 @@ MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process) e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MOBILE_NETWORK_CODE_IDX].uptr; e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MNC_DIGIT_LENGTH].u8ptr; } + /* TODO add NSSAIs */ - e1Setup->remotePortF1U = *(GNBParamList.paramarray[0][GNB_REMOTE_S_PORTD_IDX].uptr); - e1Setup->localAddressF1U = strdup(*(GNBParamList.paramarray[0][GNB_LOCAL_S_ADDRESS_IDX].strptr)); - e1Setup->localPortF1U = *(GNBParamList.paramarray[0][GNB_LOCAL_S_PORTD_IDX].uptr); - get_NGU_S1U_addr(&e1Setup->localAddressN3, &e1Setup->localPortN3); - e1Setup->remotePortN3 = e1Setup->localPortN3 ; + e1ap_net_config_t *e1ap_nc = &E1AP_REGISTER_REQ(msgConfig).net_config; + e1ap_nc->remotePortF1U = *(GNBParamList.paramarray[0][GNB_REMOTE_S_PORTD_IDX].uptr); + e1ap_nc->localAddressF1U = strdup(*(GNBParamList.paramarray[0][GNB_LOCAL_S_ADDRESS_IDX].strptr)); + e1ap_nc->localPortF1U = *(GNBParamList.paramarray[0][GNB_LOCAL_S_PORTD_IDX].uptr); + get_NGU_S1U_addr(&e1ap_nc->localAddressN3, &e1ap_nc->localPortN3); + e1ap_nc->remotePortN3 = e1ap_nc->localPortN3 ; if (separate_CUUP_process) { paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0}; paramdef_t GNBE1Params[] = GNBE1PARAMS_DESC; config_getlist(&GNBE1ParamList, GNBE1Params, sizeofArray(GNBE1Params), aprefix); paramdef_t *e1Parms = GNBE1ParamList.paramarray[0]; - strcpy(e1Setup->CUCP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUCP].strptr)); - e1Setup->CUCP_e1_ip_address.ipv4 = 1; - strcpy(e1Setup->CUUP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUUP].strptr)); - e1Setup->CUUP_e1_ip_address.ipv4 = 1; + strcpy(e1ap_nc->CUCP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUCP].strptr)); + 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; } } return msgConfig; diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index cd701f01f5..74a8a997bd 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -147,10 +147,10 @@ void *gNB_app_task(void *args_p) 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); - if (msg) - itti_send_msg_to_task(TASK_CUCP_E1, 0, msg); - else - AssertFatal(false, "Send inti to task for E1AP CP failed\n"); + 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 + itti_send_msg_to_task(TASK_CUCP_E1, 0, msg); } if (node_type == ngran_gNB_CUUP) { From c3927fa6b76cf9f896e606bdd360cf660033cbfb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 27 Sep 2023 15:58:08 +0200 Subject: [PATCH 16/40] Fix bug: correct PLMN in check in E1AP Setup Req handler --- openair2/E1AP/e1ap_setup.c | 1 - openair2/RRC/NR/rrc_gNB.c | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/openair2/E1AP/e1ap_setup.c b/openair2/E1AP/e1ap_setup.c index 64b9ebab80..97a3bcb627 100644 --- a/openair2/E1AP/e1ap_setup.c +++ b/openair2/E1AP/e1ap_setup.c @@ -104,7 +104,6 @@ MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process) for (int I = 0; I < numPLMNs; I++) { e1Setup->plmns[I].mcc = *PLMNParamList.paramarray[I][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MOBILE_NETWORK_CODE_IDX].uptr; - e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MNC_DIGIT_LENGTH].u8ptr; } /* TODO add NSSAIs */ diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 9683804cb0..bd8548dc04 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2325,8 +2325,8 @@ int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) { resp->transac_id = req->transac_id; for (int i=0; i < req->supported_plmns; i++) { - if (rrc->configuration.mcc[i] == req->plmns[i].mcc && - rrc->configuration.mnc[i] == req->plmns[i].mnc) { + if (rrc->configuration.mcc[i] != req->plmns[i].mcc || + rrc->configuration.mnc[i] != req->plmns[i].mnc) { LOG_E(NR_RRC, "PLMNs received from CUUP (mcc:%d, mnc:%d) did not match with PLMNs in RRC (mcc:%d, mnc:%d)\n", req->plmns[i].mcc, req->plmns[i].mnc, rrc->configuration.mcc[i], rrc->configuration.mnc[i]); return -1; From f721b1398266245fda7a76c4d50d79d0e7a6cb2e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 28 Sep 2023 08:20:49 +0200 Subject: [PATCH 17/40] Fix: E1 PDU Session has NSSAI, not only SST --- openair2/COMMON/e1ap_messages_types.h | 7 ++++++- openair2/E1AP/e1ap.c | 12 ++++++++++-- openair2/RRC/NR/rrc_gNB_NGAP.c | 6 +++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 0fe07ea910..11a27635d5 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -55,6 +55,11 @@ typedef struct PLMN_ID_s { int mnc_digit_length; } PLMN_ID_t; +typedef struct e1ap_nssai_t { + uint8_t sst; + uint32_t sd; // optional: "No SD" is 0xffffff, see 23.003 Sec 28.4.2 +} e1ap_nssai_t; + typedef struct e1ap_net_config_t { net_ip_address_t CUUP_e1_ip_address; net_ip_address_t CUCP_e1_ip_address; @@ -144,7 +149,7 @@ typedef struct DRB_nGRAN_to_setup_s { typedef struct pdu_session_to_setup_s { long sessionId; long sessionType; - int8_t sst; + e1ap_nssai_t nssai; long integrityProtectionIndication; long confidentialityProtectionIndication; in_addr_t tlAddress; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 73b804cddf..6d4b539ffb 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -562,7 +562,12 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear ieC6_1->pDU_Session_ID = i->sessionId; ieC6_1->pDU_Session_Type = i->sessionType; - INT8_TO_OCTET_STRING(i->sst, &ieC6_1->sNSSAI.sST); + INT8_TO_OCTET_STRING(i->nssai.sst, &ieC6_1->sNSSAI.sST); + if (i->nssai.sd != 0xffffff) { + ieC6_1->sNSSAI.sD = malloc(sizeof(*ieC6_1->sNSSAI.sD)); + AssertFatal(ieC6_1->sNSSAI.sD != NULL, "out of memory\n"); + INT24_TO_OCTET_STRING(i->nssai.sd, ieC6_1->sNSSAI.sD); + } ieC6_1->securityIndication.integrityProtectionIndication = i->integrityProtectionIndication; ieC6_1->securityIndication.confidentialityProtectionIndication = i->confidentialityProtectionIndication; @@ -841,7 +846,10 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, pdu_session->sessionId = pdu2Setup->pDU_Session_ID; pdu_session->sessionType = pdu2Setup->pDU_Session_Type; - OCTET_STRING_TO_INT8(&pdu2Setup->sNSSAI.sST, pdu_session->sst); + OCTET_STRING_TO_INT8(&pdu2Setup->sNSSAI.sST, pdu_session->nssai.sst); + pdu_session->nssai.sd = 0xffffff; + if (pdu2Setup->sNSSAI.sD != NULL) + OCTET_STRING_TO_INT24(pdu2Setup->sNSSAI.sD, pdu_session->nssai.sd); pdu_session->integrityProtectionIndication = pdu2Setup->securityIndication.integrityProtectionIndication; pdu_session->confidentialityProtectionIndication = pdu2Setup->securityIndication.confidentialityProtectionIndication; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index cac6884631..214382767f 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -775,7 +775,11 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins pdu_session_to_setup_t *pdu = bearer_req.pduSession + bearer_req.numPDUSessions; bearer_req.numPDUSessions++; pdu->sessionId = session->pdusession_id; - pdu->sst = msg->allowed_nssai[i].sST; + ngap_allowed_NSSAI_t *nssai = &msg->allowed_nssai[i]; + pdu->nssai.sst = nssai->sST; + pdu->nssai.sd = 0xffffff; + if (nssai->sD_flag) + pdu->nssai.sd = nssai->sD[0] << 16 | nssai->sD[1] << 8 | nssai->sD[0]; pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed; pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed; From 23eaea4b8da5b47acf2a2d06562c12cb5e6798ff Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 27 Sep 2023 16:33:59 +0200 Subject: [PATCH 18/40] Move CU-UP related processing to separate file A later commit will introduce an RB tree to manage multiple CU-UPs. The RB tree implementation relies on some macros that generate RB tree functions. Functions using the RB tree implementation will be grouped in this file. --- CMakeLists.txt | 1 + openair2/RRC/NR/nr_rrc_proto.h | 2 ++ openair2/RRC/NR/rrc_gNB.c | 25 +---------------- openair2/RRC/NR/rrc_gNB_cuup.c | 51 ++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 openair2/RRC/NR/rrc_gNB_cuup.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c2baa4de3..8504704280 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1277,6 +1277,7 @@ set(L2_NR_SRC ${NR_RRC_DIR}/rrc_gNB_UE_context.c ${NR_RRC_DIR}/rrc_gNB_NGAP.c ${NR_RRC_DIR}/rrc_gNB_radio_bearers.c + ${NR_RRC_DIR}/rrc_gNB_cuup.c ) set(L2_SRC_UE diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 510e058495..13f8efce50 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -132,6 +132,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP); +int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req); + void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, instance_t instance); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index bd8548dc04..8360152375 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2315,29 +2315,6 @@ static int get_dl_mimo_layers(const f1ap_served_cell_info_t *cell_info, const NR return(1); } -int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) { - - AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n"); - gNB_RRC_INST *rrc = RC.nrrrc[0]; //TODO: remove hardcoding of RC index here - MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, instance, E1AP_SETUP_RESP); - - e1ap_setup_resp_t *resp = &E1AP_SETUP_RESP(msg_p); - resp->transac_id = req->transac_id; - - for (int i=0; i < req->supported_plmns; i++) { - if (rrc->configuration.mcc[i] != req->plmns[i].mcc || - rrc->configuration.mnc[i] != req->plmns[i].mnc) { - LOG_E(NR_RRC, "PLMNs received from CUUP (mcc:%d, mnc:%d) did not match with PLMNs in RRC (mcc:%d, mnc:%d)\n", - req->plmns[i].mcc, req->plmns[i].mnc, rrc->configuration.mcc[i], rrc->configuration.mnc[i]); - return -1; - } - } - - itti_send_msg_to_task(TASK_CUCP_E1, instance, msg_p); - - return 0; -} - void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp) { /* Generate a UE context modification request message towards the DU to @@ -2699,7 +2676,7 @@ void *rrc_gnb_task(void *args_p) { break; case E1AP_SETUP_REQ: - rrc_gNB_process_e1_setup_req(&E1AP_SETUP_REQ(msg_p), instance); + rrc_gNB_process_e1_setup_req(&E1AP_SETUP_REQ(msg_p)); break; case E1AP_BEARER_CONTEXT_SETUP_RESP: diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c new file mode 100644 index 0000000000..aaf28c9025 --- /dev/null +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -0,0 +1,51 @@ +/* + * 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 "common/ran_context.h" +#include "nr_rrc_defs.h" + +int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req) +{ + AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n"); + gNB_RRC_INST *rrc = RC.nrrrc[0]; + + + for (int i = 0; i < req->supported_plmns; i++) { + PLMN_ID_t *id = &req->plmns[i]; + if (rrc->configuration.mcc[i] != id->mcc || rrc->configuration.mnc[i] != id->mnc) { + LOG_E(NR_RRC, + "PLMNs received from CUUP (mcc:%d, mnc:%d) did not match with PLMNs in RRC (mcc:%d, mnc:%d)\n", + id->mcc, + id->mnc, + rrc->configuration.mcc[i], + rrc->configuration.mnc[i]); + return -1; + } + } + + + MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, E1AP_SETUP_RESP); + e1ap_setup_resp_t *resp = &E1AP_SETUP_RESP(msg_p); + resp->transac_id = req->transac_id; + itti_send_msg_to_task(TASK_CUCP_E1, 0, msg_p); + + return 0; +} From b26dcc1ee5c8309c0929ca4bdb82491b45e5b59e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 26 Sep 2023 15:55:40 +0200 Subject: [PATCH 19/40] Store E1 Setup Request at RRC --- executables/nr-softmodem.c | 7 ++++++- openair2/E1AP/e1ap.c | 7 +++---- openair2/RRC/NR/nr_rrc_defs.h | 5 +++++ openair2/RRC/NR/rrc_gNB_cuup.c | 6 ++++++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index a1a97373e8..392ff166da 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -405,8 +405,13 @@ static int create_gNB_tasks(ngran_node_t node_type) instance_t inst = 0; createE1inst(UPtype, inst, &E1AP_REGISTER_REQ(msg).net_config, NULL); cuup_init_n3(inst); - itti_free(TASK_UNKNOWN, msg); RC.nrrrc[gnb_id_start]->e1_inst = inst; // stupid instance !!!*/ + + /* send E1 Setup Request to RRC */ + MessageDef *new_msg = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ); + E1AP_SETUP_REQ(new_msg) = E1AP_REGISTER_REQ(msg).setup_req; + itti_send_msg_to_task(TASK_RRC_GNB, 0 /*unused by callee*/, new_msg); + itti_free(TASK_UNKNOWN, msg); } //Use check on x2ap to consider the NSA scenario diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 6d4b539ffb..a9dacd9ac2 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -305,15 +305,14 @@ void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, int e1apCUCP_handle_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) { DevAssert(pdu != NULL); - extract_SETUP_REQUEST(pdu, &inst->setupReq); /* Create ITTI message and send to queue */ MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, 0 /*unused by callee*/, E1AP_SETUP_REQ); - memcpy(&E1AP_SETUP_REQ(msg_p), &inst->setupReq, sizeof(e1ap_setup_req_t)); + extract_SETUP_REQUEST(pdu, &E1AP_SETUP_REQ(msg_p)); - if (inst->setupReq.supported_plmns > 0) { + if (E1AP_SETUP_REQ(msg_p).supported_plmns > 0) { itti_send_msg_to_task(TASK_RRC_GNB, 0 /*unused by callee*/, msg_p); } else { - e1apCUCP_send_SETUP_FAILURE(inst->assoc_id, inst->setupReq.transac_id); + e1apCUCP_send_SETUP_FAILURE(inst->assoc_id, E1AP_SETUP_REQ(msg_p).transac_id); itti_free(TASK_CUCP_E1, msg_p); return -1; } diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index a31747a415..845e4337aa 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -371,6 +371,10 @@ typedef struct nr_rrc_du_container_t { NR_SIB1_t *sib1; } nr_rrc_du_container_t; +typedef struct nr_rrc_cuup_container_t { + e1ap_setup_req_t *setup_req; +} nr_rrc_cuup_container_t; + //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -400,6 +404,7 @@ typedef struct gNB_RRC_INST_s { cucp_cuup_if_t cucp_cuup; nr_rrc_du_container_t *du; + nr_rrc_cuup_container_t *cuup; } gNB_RRC_INST; diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index aaf28c9025..ace4a5f62d 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -26,6 +26,7 @@ int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req) { AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n"); gNB_RRC_INST *rrc = RC.nrrrc[0]; + AssertFatal(rrc->cuup == NULL, "cannot handle multiple CU-UPs\n"); for (int i = 0; i < req->supported_plmns; i++) { @@ -41,6 +42,11 @@ int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req) } } + LOG_I(RRC, "Accepting new CU-UP ID %ld name %s\n", req->gNB_cu_up_id, req->gNB_cu_up_name); + rrc->cuup = malloc(sizeof(*rrc->cuup)); + AssertFatal(rrc->cuup, "out of memory\n"); + rrc->cuup->setup_req = malloc(sizeof(*rrc->cuup->setup_req)); + *rrc->cuup->setup_req = *req; MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, E1AP_SETUP_RESP); e1ap_setup_resp_t *resp = &E1AP_SETUP_RESP(msg_p); From 75b055711ad76cc666f30e41659e875ae68e228b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 27 Sep 2023 14:11:28 +0200 Subject: [PATCH 20/40] Setup Request: store in E1 only for CU-UP --- openair2/E1AP/e1ap.c | 4 ++-- openair2/E1AP/e1ap_common.c | 6 ++++-- openair2/E1AP/e1ap_common.h | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index a9dacd9ac2..e7503874a3 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -332,7 +332,7 @@ int e1apCUUP_handle_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t /* transac_id */ long transaction_id; - long old_transaction_id = inst->setupReq.transac_id; + long old_transaction_id = inst->cuup.setupReq.transac_id; F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupResponseIEs_t, ie, in, E1AP_ProtocolIE_ID_id_TransactionID, true); transaction_id = ie->value.choice.TransactionID; @@ -1558,7 +1558,7 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, extern instance_t CUuniqInstance; CUuniqInstance = getCxtE1(instance)->gtpInstF1U; cuup_init_n3(instance); - e1apCUUP_send_SETUP_REQUEST(inst->assoc_id, &inst->setupReq); + e1apCUUP_send_SETUP_REQUEST(inst->assoc_id, &inst->cuup.setupReq); } } diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 71e93221ab..366d2b82e6 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -46,8 +46,10 @@ void createE1inst(E1_t type, instance_t instance, e1ap_net_config_t *nc, e1ap_se e1ap_inst[instance]->assoc_id = -1; if (nc) memcpy(&e1ap_inst[instance]->net_config, nc, sizeof(*nc)); - if (req) - memcpy(&e1ap_inst[instance]->setupReq, req, sizeof(*req)); + if (req) { + AssertFatal(type == UPtype, "E1 setup request only to be stored for CU-UP\n"); + memcpy(&e1ap_inst[instance]->cuup.setupReq, req, sizeof(*req)); + } e1ap_inst[instance]->gtpInstN3 = -1; e1ap_inst[instance]->gtpInstF1U = -1; } diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index 0159b92a97..bcd3d3b936 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -33,9 +33,11 @@ typedef struct e1ap_upcp_inst_s { E1_t type; enum sctp_state_e sockState; sctp_assoc_t assoc_id; + struct { + e1ap_setup_req_t setupReq; + } cuup; instance_t gtpInstN3; instance_t gtpInstF1U; - e1ap_setup_req_t setupReq; e1ap_net_config_t net_config; } e1ap_upcp_inst_t; From 7d37143bac46034430d7e5ba7fc3336c5426d067 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 28 Sep 2023 20:02:20 +0200 Subject: [PATCH 21/40] Read and forward NSSAI in E1AP Setup Request --- openair2/COMMON/e1ap_messages_types.h | 7 ++++- openair2/E1AP/e1ap.c | 44 +++++++++++++++++++++++---- openair2/E1AP/e1ap_asnc.h | 2 ++ openair2/E1AP/e1ap_setup.c | 20 ++++++++++-- openair2/RRC/NR/rrc_gNB_cuup.c | 2 +- 5 files changed, 64 insertions(+), 11 deletions(-) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 11a27635d5..67f5a883e2 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -32,6 +32,7 @@ #define E1AP_MAX_NUM_TRANSAC_IDS 4 #define E1AP_MAX_NUM_PLMNS 4 +#define E1AP_MAX_NUM_SLICES 1024 #define E1AP_MAX_NUM_CELL_GROUPS 4 #define E1AP_MAX_NUM_QOS_FLOWS 4 #define E1AP_MAX_NUM_NGRAN_DRB 4 @@ -76,7 +77,11 @@ typedef struct e1ap_setup_req_s { char * gNB_cu_up_name; uint64_t transac_id; int supported_plmns; - PLMN_ID_t plmns[E1AP_MAX_NUM_PLMNS]; + struct { + PLMN_ID_t id; + int supported_slices; + e1ap_nssai_t *slice; + } plmn[E1AP_MAX_NUM_PLMNS]; } e1ap_setup_req_t; typedef struct e1ap_register_req_t { diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index e7503874a3..690810bbe8 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -198,7 +198,24 @@ static void fill_SETUP_REQUEST(e1ap_setup_req_t *setup, E1AP_E1AP_PDU_t *pdu) for (int i=0; i < numSupportedPLMNs; i++) { asn1cSequenceAdd(ieC5->value.choice.SupportedPLMNs_List.list, E1AP_SupportedPLMNs_Item_t, supportedPLMN); /* 5.1 PLMN Identity */ - MCC_MNC_TO_PLMNID(setup->plmns[i].mcc, setup->plmns[i].mnc, setup->plmns[i].mnc_digit_length, &supportedPLMN->pLMN_Identity); + PLMN_ID_t *id = &setup->plmn[i].id; + MCC_MNC_TO_PLMNID(id->mcc, id->mnc, id->mnc_digit_length, &supportedPLMN->pLMN_Identity); + + int n = setup->plmn[i].supported_slices; + if (setup->plmn[i].slice != NULL && n > 0) { + supportedPLMN->slice_Support_List = calloc(1, sizeof(*supportedPLMN->slice_Support_List)); + AssertFatal(supportedPLMN->slice_Support_List != NULL, "out of memory\n"); + for (int s = 0; s < n; ++s) { + asn1cSequenceAdd(supportedPLMN->slice_Support_List->list, E1AP_Slice_Support_Item_t, slice); + e1ap_nssai_t *nssai = &setup->plmn[i].slice[s]; + INT8_TO_OCTET_STRING(nssai->sst, &slice->sNSSAI.sST); + if (nssai->sd != 0xffffff) { + slice->sNSSAI.sD = malloc(sizeof(*slice->sNSSAI.sD)); + AssertFatal(slice->sNSSAI.sD != NULL, "out of memory\n"); + INT24_TO_OCTET_STRING(nssai->sd, slice->sNSSAI.sD); + } + } + } } } @@ -294,11 +311,26 @@ void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, E1AP_SupportedPLMNs_Item_t *supported_plmn_item = (E1AP_SupportedPLMNs_Item_t *)(ie->value.choice.SupportedPLMNs_List.list.array[i]); /* PLMN Identity */ - PLMNID_TO_MCC_MNC(&supported_plmn_item->pLMN_Identity, - req->plmns[i].mcc, - req->plmns[i].mnc, - req->plmns[i].mnc_digit_length); - LOG_D(E1AP, "MCC: %d\nMNC: %d\n", req->plmns[i].mcc, req->plmns[i].mnc); + PLMN_ID_t *id = &req->plmn[i].id; + PLMNID_TO_MCC_MNC(&supported_plmn_item->pLMN_Identity, id->mcc, id->mnc, id->mnc_digit_length); + LOG_D(E1AP, "MCC %d MNC %d\n", id->mcc, id->mnc); + + /* NSSAI */ + if (supported_plmn_item->slice_Support_List) { + int n = supported_plmn_item->slice_Support_List->list.count; + req->plmn[i].supported_slices = n; + req->plmn[i].slice = calloc(n, sizeof(*req->plmn[i].slice)); + AssertFatal(req->plmn[i].slice != NULL, "out of memory\n"); + for (int s = 0; s < n; ++s) { + e1ap_nssai_t *slice = &req->plmn[i].slice[s]; + const E1AP_SNSSAI_t *es = &supported_plmn_item->slice_Support_List->list.array[s]->sNSSAI; + OCTET_STRING_TO_INT8(&es->sST, slice->sst); + slice->sd = 0xffffff; + if (es->sD != NULL) + OCTET_STRING_TO_INT24(es->sD, slice->sd); + LOG_D(E1AP, "SST %d SD %06x\n", slice->sst, slice->sd); + } + } } } diff --git a/openair2/E1AP/e1ap_asnc.h b/openair2/E1AP/e1ap_asnc.h index 00dbcc13f3..3916f4aeb7 100644 --- a/openair2/E1AP/e1ap_asnc.h +++ b/openair2/E1AP/e1ap_asnc.h @@ -61,5 +61,7 @@ #include #include #include +#include +#include #endif diff --git a/openair2/E1AP/e1ap_setup.c b/openair2/E1AP/e1ap_setup.c index 97a3bcb627..97a8b93700 100644 --- a/openair2/E1AP/e1ap_setup.c +++ b/openair2/E1AP/e1ap_setup.c @@ -102,10 +102,24 @@ MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process) e1Setup->supported_plmns = numPLMNs; for (int I = 0; I < numPLMNs; I++) { - e1Setup->plmns[I].mcc = *PLMNParamList.paramarray[I][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; - e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MOBILE_NETWORK_CODE_IDX].uptr; + e1Setup->plmn[I].id.mcc = *PLMNParamList.paramarray[I][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; + e1Setup->plmn[I].id.mnc = *PLMNParamList.paramarray[I][GNB_MOBILE_NETWORK_CODE_IDX].uptr; + e1Setup->plmn[I].id.mnc_digit_length = *PLMNParamList.paramarray[I][GNB_MNC_DIGIT_LENGTH].uptr; + + char snssaistr[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(snssaistr, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0, GNB_CONFIG_STRING_PLMN_LIST, I); + paramlist_def_t SNSSAIParamList = {GNB_CONFIG_STRING_SNSSAI_LIST, NULL, 0}; + paramdef_t SNSSAIParams[] = GNBSNSSAIPARAMS_DESC; + config_getlist(&SNSSAIParamList, SNSSAIParams, sizeof(SNSSAIParams)/sizeof(paramdef_t), snssaistr); + e1Setup->plmn[I].supported_slices = SNSSAIParamList.numelt; + e1Setup->plmn[I].slice = calloc(SNSSAIParamList.numelt, sizeof(*e1Setup->plmn[I].slice)); + AssertFatal(e1Setup->plmn[I].slice != NULL, "out of memory\n"); + for (int s = 0; s < SNSSAIParamList.numelt; ++s) { + e1ap_nssai_t *slice = &e1Setup->plmn[I].slice[s]; + slice->sst = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr; + slice->sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr; + } } - /* TODO add NSSAIs */ e1ap_net_config_t *e1ap_nc = &E1AP_REGISTER_REQ(msgConfig).net_config; e1ap_nc->remotePortF1U = *(GNBParamList.paramarray[0][GNB_REMOTE_S_PORTD_IDX].uptr); diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index ace4a5f62d..56ee7d59ca 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -30,7 +30,7 @@ int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req) for (int i = 0; i < req->supported_plmns; i++) { - PLMN_ID_t *id = &req->plmns[i]; + PLMN_ID_t *id = &req->plmn[i].id; if (rrc->configuration.mcc[i] != id->mcc || rrc->configuration.mnc[i] != id->mnc) { LOG_E(NR_RRC, "PLMNs received from CUUP (mcc:%d, mnc:%d) did not match with PLMNs in RRC (mcc:%d, mnc:%d)\n", From 1d3127bb999c7e0082a529b96c05df4f1c1a63d0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 8 Oct 2023 16:44:37 +0200 Subject: [PATCH 22/40] Read and forward CU UP name in E1AP Setup Request --- openair2/E1AP/e1ap.c | 21 +++++++++++++++++++++ openair2/E1AP/e1ap_setup.c | 2 ++ 2 files changed, 23 insertions(+) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 690810bbe8..b51576ad05 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -178,6 +178,16 @@ static void fill_SETUP_REQUEST(e1ap_setup_req_t *setup, E1AP_E1AP_PDU_t *pdu) ieC2->criticality = E1AP_Criticality_reject; ieC2->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_GNB_CU_UP_ID; asn_int642INTEGER(&ieC2->value.choice.GNB_CU_UP_ID, setup->gNB_cu_up_id); + + /* optional */ + if (setup->gNB_cu_up_name) { + asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC3); + ieC3->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_Name; + ieC3->criticality = E1AP_Criticality_ignore; + ieC3->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_GNB_CU_UP_Name; + OCTET_STRING_fromBuf(&ieC3->value.choice.GNB_CU_UP_Name, setup->gNB_cu_up_name, strlen(setup->gNB_cu_up_name)); + } + /* mandatory */ /* c4. CN Support */ asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC4); @@ -296,6 +306,17 @@ void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, asn_INTEGER2ulong(&ie->value.choice.GNB_CU_UP_ID, &req->gNB_cu_up_id); LOG_D(E1AP, "gNB CU UP ID: %ld\n", req->gNB_cu_up_id); + /* gNB CU UP name */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_gNB_CU_UP_Name, false); + req->gNB_cu_up_name = NULL; + if (ie != NULL) { + req->gNB_cu_up_name = calloc(ie->value.choice.GNB_CU_UP_Name.size + 1, sizeof(char)); + AssertFatal(req->gNB_cu_up_name != NULL, "out of memory\n"); + memcpy(req->gNB_cu_up_name, ie->value.choice.GNB_CU_UP_Name.buf, ie->value.choice.GNB_CU_UP_Name.size); + LOG_D(E1AP, "req->gNB_cu_up_name %s\n", req->gNB_cu_up_name); + } + /* CN Support */ F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_CNSupport, true); diff --git a/openair2/E1AP/e1ap_setup.c b/openair2/E1AP/e1ap_setup.c index 97a8b93700..f2b9d05503 100644 --- a/openair2/E1AP/e1ap_setup.c +++ b/openair2/E1AP/e1ap_setup.c @@ -88,6 +88,8 @@ MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process) 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); paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC; paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0}; From b08ce59bc284dde8f510b5053bcc89ff6c6b4032 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 27 Sep 2023 13:51:18 +0200 Subject: [PATCH 23/40] Pass assoc_id to RRC and use when sending E1AP messages --- executables/nr-softmodem.c | 1 + openair2/E1AP/e1ap.c | 42 ++++++++++++++++-------------- openair2/E1AP/e1ap.h | 18 ++++++------- openair2/E1AP/e1ap_api.c | 4 +-- openair2/E1AP/e1ap_common.c | 2 +- openair2/E1AP/e1ap_common.h | 2 +- openair2/F1AP/f1ap_ids.h | 5 +++- openair2/RRC/NR/cucp_cuup_direct.c | 12 +++++---- openair2/RRC/NR/cucp_cuup_e1ap.c | 16 +++++++----- openair2/RRC/NR/cucp_cuup_if.h | 5 +++- openair2/RRC/NR/nr_rrc_defs.h | 1 + openair2/RRC/NR/nr_rrc_proto.h | 4 ++- openair2/RRC/NR/rrc_gNB.c | 8 +++--- openair2/RRC/NR/rrc_gNB_NGAP.c | 3 ++- openair2/RRC/NR/rrc_gNB_cuup.c | 41 +++++++++++++++++++++++++++-- 15 files changed, 111 insertions(+), 53 deletions(-) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 392ff166da..cbb36dc580 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -410,6 +410,7 @@ static int create_gNB_tasks(ngran_node_t node_type) /* send E1 Setup Request to RRC */ MessageDef *new_msg = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ); E1AP_SETUP_REQ(new_msg) = E1AP_REGISTER_REQ(msg).setup_req; + new_msg->ittiMsgHeader.originInstance = -1; /* meaning, it is local */ itti_send_msg_to_task(TASK_RRC_GNB, 0 /*unused by callee*/, new_msg); itti_free(TASK_UNKNOWN, msg); } diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index b51576ad05..f7ca3c379b 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -35,7 +35,7 @@ #include "gtp_itf.h" #define E1AP_NUM_MSG_HANDLERS 14 -typedef int (*e1ap_message_processing_t)(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *message_p); +typedef int (*e1ap_message_processing_t)(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *message_p); const e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3] = { {0, 0, 0}, /* Reset */ @@ -92,7 +92,7 @@ int e1ap_handle_message(instance_t instance, sctp_assoc_t assoc_id, const uint8_ } else { /* Calling the right handler */ LOG_D(E1AP, "Calling handler with instance %ld\n",instance); - ret = (*e1ap_message_processing[procedureCode][pdu.present - 1])(getCxtE1(instance), &pdu); + ret = (*e1ap_message_processing[procedureCode][pdu.present - 1])(assoc_id, getCxtE1(instance), &pdu); } ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_E1AP_E1AP_PDU, &pdu); @@ -355,17 +355,18 @@ void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, } } -int e1apCUCP_handle_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) +int e1apCUCP_handle_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) { DevAssert(pdu != NULL); /* Create ITTI message and send to queue */ MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, 0 /*unused by callee*/, E1AP_SETUP_REQ); extract_SETUP_REQUEST(pdu, &E1AP_SETUP_REQ(msg_p)); + msg_p->ittiMsgHeader.originInstance = assoc_id; if (E1AP_SETUP_REQ(msg_p).supported_plmns > 0) { itti_send_msg_to_task(TASK_RRC_GNB, 0 /*unused by callee*/, msg_p); } else { - e1apCUCP_send_SETUP_FAILURE(inst->assoc_id, E1AP_SETUP_REQ(msg_p).transac_id); + e1apCUCP_send_SETUP_FAILURE(assoc_id, E1AP_SETUP_REQ(msg_p).transac_id); itti_free(TASK_CUCP_E1, msg_p); return -1; } @@ -373,7 +374,7 @@ int e1apCUCP_handle_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t return 0; } -int e1apCUUP_handle_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) +int e1apCUUP_handle_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) { LOG_D(E1AP, "%s\n", __func__); DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome); @@ -401,7 +402,7 @@ int e1apCUUP_handle_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t return 0; } -int e1apCUUP_handle_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) +int e1apCUUP_handle_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) { E1AP_GNB_CU_UP_E1SetupFailureIEs_t *ie; DevAssert(pdu != NULL); @@ -985,7 +986,7 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, } -int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) +int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) { DevAssert(pdu != NULL); DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage); @@ -1085,7 +1086,7 @@ void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu, } } -int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) +int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) { DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome); DevAssert(pdu->choice.successfulOutcome->procedureCode == E1AP_ProcedureCode_id_bearerContextSetup); @@ -1095,6 +1096,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_RESP); e1ap_bearer_setup_resp_t *bearerCxt = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg); extract_BEARER_CONTEXT_SETUP_RESPONSE(pdu, bearerCxt); + msg->ittiMsgHeader.originInstance = assoc_id; // Fixme: instance is the NGAP instance, no good way to set it here instance_t instance = 0; itti_send_msg_to_task(TASK_RRC_GNB, instance, msg); @@ -1102,7 +1104,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const return 0; } -int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) +int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) { AssertFatal(false,"Not implemented yet\n"); return -1; @@ -1269,7 +1271,7 @@ void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu, } } -int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) +int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) { DevAssert(pdu != NULL); DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage); @@ -1442,7 +1444,7 @@ void extract_BEARER_CONTEXT_RELEASE_COMMAND(const E1AP_E1AP_PDU_t *pdu, } } -int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) +int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) { DevAssert(pdu != NULL); DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage); @@ -1486,7 +1488,7 @@ void extract_BEARER_CONTEXT_RELEASE_COMPLETE(const E1AP_E1AP_PDU_t *pdu, } } -int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) +int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) { DevAssert(pdu != NULL); DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome); @@ -1598,7 +1600,7 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, if (type == UPtype) { e1ap_upcp_inst_t *inst = getCxtE1(instance); - inst->assoc_id = sctp_new_association_resp->assoc_id; + inst->cuup.assoc_id = sctp_new_association_resp->assoc_id; e1ap_net_config_t *nc = &inst->net_config; eth_params_t IPaddr; @@ -1611,7 +1613,7 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, extern instance_t CUuniqInstance; CUuniqInstance = getCxtE1(instance)->gtpInstF1U; cuup_init_n3(instance); - e1apCUUP_send_SETUP_REQUEST(inst->assoc_id, &inst->cuup.setupReq); + e1apCUUP_send_SETUP_REQUEST(inst->cuup.assoc_id, &inst->cuup.setupReq); } } @@ -1662,7 +1664,8 @@ void e1_task_handle_sctp_association_ind(E1_t type, instance_t instance, sctp_ne createE1inst(type, instance, NULL, NULL); e1ap_upcp_inst_t *inst = getCxtE1(instance); inst->sockState = SCTP_STATE_ESTABLISHED; - inst->assoc_id = sctp_new_ind->assoc_id; + if (type == UPtype) + inst->cuup.assoc_id = sctp_new_ind->assoc_id; } void e1apHandleTimer(instance_t myInstance) @@ -1683,8 +1686,7 @@ void *E1AP_CUCP_task(void *arg) { instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg); const int msgType = ITTI_MSG_ID(msg); LOG_D(E1AP, "CUCP received %s for instance %ld\n", messages_info[msgType].name, myInstance); - /* TODO get the assoc ID through the ITTI message to address multiple CU-UPs */ - e1ap_upcp_inst_t *inst = getCxtE1(myInstance); + sctp_assoc_t assoc_id = msg->ittiMsgHeader.originInstance; switch (ITTI_MSG_ID(msg)) { case SCTP_NEW_ASSOCIATION_IND: @@ -1713,15 +1715,15 @@ void *E1AP_CUCP_task(void *arg) { break; case E1AP_SETUP_RESP: - e1ap_send_SETUP_RESPONSE(inst->assoc_id, &E1AP_SETUP_RESP(msg)); + e1ap_send_SETUP_RESPONSE(assoc_id, &E1AP_SETUP_RESP(msg)); break; case E1AP_BEARER_CONTEXT_SETUP_REQ: - e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(inst->assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); + e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); break; case E1AP_BEARER_CONTEXT_MODIFICATION_REQ: - e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(inst->assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); + e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); break; default: diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h index f5ba9350d7..8a7c6ba2df 100644 --- a/openair2/E1AP/e1ap.h +++ b/openair2/E1AP/e1ap.h @@ -28,25 +28,25 @@ #include "e1ap_asnc.h" #include "openair2/E1AP/e1ap_common.h" -int e1apCUCP_handle_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); +int e1apCUCP_handle_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -int e1apCUUP_handle_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); +int e1apCUUP_handle_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -int e1apCUUP_handle_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); +int e1apCUUP_handle_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); +int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); +int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); +int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); +int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_bearer_setup_resp_t *const resp); -int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); +int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); +int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_bearer_release_cmd_t *const cmd); diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index 9096a9faf7..cf3fe14de1 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -172,7 +172,7 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_ pduSetup->numDRBFailed = 0; } - e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst->assoc_id, resp); + e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst->cuup.assoc_id, resp); } void CUUP_process_bearer_context_mod_req(instance_t instance, e1ap_bearer_setup_req_t *const req) @@ -190,5 +190,5 @@ void CUUP_process_bearer_release_command(instance_t instance, e1ap_bearer_releas AssertFatal(inst, ""); newGtpuDeleteAllTunnels(inst->gtpInstN3, cmd->gNB_cu_up_ue_id); newGtpuDeleteAllTunnels(inst->gtpInstF1U, cmd->gNB_cu_up_ue_id); - e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst->assoc_id, cmd); + e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst->cuup.assoc_id, cmd); } diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 366d2b82e6..28764b5dec 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -43,7 +43,7 @@ void createE1inst(E1_t type, instance_t instance, e1ap_net_config_t *nc, e1ap_se e1ap_inst[instance] = calloc(1, sizeof(e1ap_upcp_inst_t)); e1ap_inst[instance]->type = type; e1ap_inst[instance]->instance = instance; - e1ap_inst[instance]->assoc_id = -1; + e1ap_inst[instance]->cuup.assoc_id = -1; if (nc) memcpy(&e1ap_inst[instance]->net_config, nc, sizeof(*nc)); if (req) { diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index bcd3d3b936..dc615d75b3 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -32,8 +32,8 @@ typedef struct e1ap_upcp_inst_s { instance_t instance; E1_t type; enum sctp_state_e sockState; - sctp_assoc_t assoc_id; struct { + sctp_assoc_t assoc_id; e1ap_setup_req_t setupReq; } cuup; instance_t gtpInstN3; diff --git a/openair2/F1AP/f1ap_ids.h b/openair2/F1AP/f1ap_ids.h index 96b146f6ba..60d35de737 100644 --- a/openair2/F1AP/f1ap_ids.h +++ b/openair2/F1AP/f1ap_ids.h @@ -27,10 +27,13 @@ #include #include +#include +#include +#include typedef struct f1_ue_data_t { uint32_t secondary_ue; - /* can be extended with F1-specific data also relevant for monolithic */ + sctp_assoc_t e1_assoc_id; } f1_ue_data_t; void cu_init_f1_ue_data(void); diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 8b81a3c5dd..a62f576c72 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -159,9 +159,10 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, return ret; } -static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) +static void cucp_cuup_bearer_context_setup_direct(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const req) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_cu_cp_ue_id); + AssertFatal(assoc_id == -1, "illegal assoc_id %d, impossible for integrated CU\n", assoc_id); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[0], req->gNB_cu_cp_ue_id); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; protocol_ctxt_t ctxt = {0}; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0, 0); @@ -194,7 +195,7 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const } else { int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd; in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); - instance_t gtpInst = getCxt(instance)->gtpInst; + instance_t gtpInst = getCxt(0)->gtpInst; // GTP tunnel for DL fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rrc_ue_id, remote_port, my_addr); } @@ -204,12 +205,13 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const prepare_and_send_ue_context_modification_f1(ue_context_p, &resp); } -static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) +static void cucp_cuup_bearer_context_mod_direct(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const req) { + AssertFatal(assoc_id == -1, "illegal assoc_id %d, impossible for integrated CU\n", assoc_id); // only update GTP tunnels if it is really a CU if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) return; - instance_t gtpInst = getCxt(instance)->gtpInst; + instance_t gtpInst = getCxt(0)->gtpInst; CU_update_UP_DL_tunnel(req, gtpInst, req->gNB_cu_cp_ue_id); } diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index 199c949959..7604cabf14 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -36,21 +36,25 @@ extern RAN_CONTEXT_t RC; -static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) +static void cucp_cuup_bearer_context_setup_e1ap(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const req) { - MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_SETUP_REQ); + AssertFatal(assoc_id > 0, "illegal assoc_id %d\n", assoc_id); + MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_REQ); + msg_p->ittiMsgHeader.originInstance = assoc_id; e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p); memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t)); - itti_send_msg_to_task (TASK_CUCP_E1, instance, msg_p); + itti_send_msg_to_task (TASK_CUCP_E1, 0, msg_p); } -static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) +static void cucp_cuup_bearer_context_mod_e1ap(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const req) { - MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_MODIFICATION_REQ); + AssertFatal(assoc_id > 0, "illegal assoc_id %d\n", assoc_id); + MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_MODIFICATION_REQ); + msg->ittiMsgHeader.originInstance = assoc_id; e1ap_bearer_setup_req_t *req_msg = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg); memcpy(req_msg, req, sizeof(*req)); - itti_send_msg_to_task(TASK_CUCP_E1, instance, msg); + itti_send_msg_to_task(TASK_CUCP_E1, 0, msg); } void cucp_cuup_message_transfer_e1ap_init(gNB_RRC_INST *rrc) { diff --git a/openair2/RRC/NR/cucp_cuup_if.h b/openair2/RRC/NR/cucp_cuup_if.h index 8f072eb753..3a3fb7948a 100644 --- a/openair2/RRC/NR/cucp_cuup_if.h +++ b/openair2/RRC/NR/cucp_cuup_if.h @@ -23,11 +23,14 @@ #define CUCP_CUUP_IF_H #include +#include +#include +#include #include "platform_types.h" struct e1ap_bearer_setup_req_s; struct e1ap_bearer_setup_resp_s; -typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *const req, instance_t instance); +typedef void (*cucp_cuup_bearer_context_setup_func_t)(sctp_assoc_t assoc_id, struct e1ap_bearer_setup_req_s *const req); struct gNB_RRC_INST_s; void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 845e4337aa..a1952de7a7 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -373,6 +373,7 @@ typedef struct nr_rrc_du_container_t { typedef struct nr_rrc_cuup_container_t { e1ap_setup_req_t *setup_req; + sctp_assoc_t assoc_id; } nr_rrc_cuup_container_t; //---NR---(completely change)--------------------- diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 13f8efce50..c85aada0b9 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -132,7 +132,9 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP); -int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req); +sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue); +sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue); +int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req); void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, instance_t instance); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 8360152375..d92360f40b 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2074,7 +2074,8 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i // send the F1 response message up to update F1-U tunnel info // it seems the rrc transaction id (xid) is not needed here - rrc->cucp_cuup.bearer_context_mod(&req, instance); + sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE); + rrc->cucp_cuup.bearer_context_mod(assoc_id, &req); } if (resp->du_to_cu_rrc_information != NULL && resp->du_to_cu_rrc_information->cellGroupConfig != NULL) { @@ -2676,7 +2677,7 @@ void *rrc_gnb_task(void *args_p) { break; case E1AP_SETUP_REQ: - rrc_gNB_process_e1_setup_req(&E1AP_SETUP_REQ(msg_p)); + rrc_gNB_process_e1_setup_req(msg_p->ittiMsgHeader.originInstance, &E1AP_SETUP_REQ(msg_p)); break; case E1AP_BEARER_CONTEXT_SETUP_RESP: @@ -2914,7 +2915,8 @@ void rrc_gNB_trigger_new_bearer(int rnti) ue->xids[xid] = RRC_PDUSESSION_MODIFY; ue->pduSession[0].xid = xid; // hack: fake xid for ongoing PDU session LOG_W(RRC, "trigger new bearer %ld for UE %04x xid %d\n", drb->id, ue->rnti, xid); - rrc->cucp_cuup.bearer_context_setup(&bearer_req, 0); + sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, ue); + rrc->cucp_cuup.bearer_context_setup(assoc_id, &bearer_req); } void rrc_gNB_trigger_release_bearer(int rnti) diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 214382767f..553cf9ecf1 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -827,7 +827,8 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins } int xid = rrc_gNB_get_next_transaction_identifier(instance); UE->xids[xid] = RRC_PDUSESSION_ESTABLISH; - rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance); + sctp_assoc_t assoc_id = get_new_cuup_for_ue(rrc, UE); + rrc->cucp_cuup.bearer_context_setup(assoc_id, &bearer_req); return; } diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index 56ee7d59ca..a612ebe8b0 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -21,8 +21,43 @@ #include "common/ran_context.h" #include "nr_rrc_defs.h" +#include "openair2/F1AP/f1ap_ids.h" -int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req) +sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue) +{ + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id); + if (ue_data.e1_assoc_id == 0) { + LOG_W(RRC, "UE %d should be associated to CU-UP, but is not\n", ue->rrc_ue_id); + return get_new_cuup_for_ue(rrc, ue); + } + LOG_D(RRC, "UE %d using CU-UP assoc_id %d\n", ue->rrc_ue_id, ue_data.e1_assoc_id); + return ue_data.e1_assoc_id; +} + +sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue) +{ + /* check if there is already a UE associated */ + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id); + if (ue_data.e1_assoc_id != 0) { + LOG_D(RRC, "UE %d using CU-UP assoc_id %d\n", ue->rrc_ue_id, ue_data.e1_assoc_id); + return ue_data.e1_assoc_id; + } + + /* it is zero -> no CUUP for this UE yet, get the (only) CU-UP that is + * connected */ + if (!rrc->cuup) + return 0; /* no CUUP connected */ + + /* update the association for the UE so it will be picked up later */ + ue_data.e1_assoc_id = rrc->cuup->assoc_id; + cu_remove_f1_ue_data(ue->rrc_ue_id); + cu_add_f1_ue_data(ue->rrc_ue_id, &ue_data); + LOG_I(RRC, "UE %d associating to CU-UP assoc_id %d\n", ue->rrc_ue_id, ue_data.e1_assoc_id); + + return ue_data.e1_assoc_id; +} + +int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req) { AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n"); gNB_RRC_INST *rrc = RC.nrrrc[0]; @@ -42,13 +77,15 @@ int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req) } } - LOG_I(RRC, "Accepting new CU-UP ID %ld name %s\n", req->gNB_cu_up_id, req->gNB_cu_up_name); + LOG_I(RRC, "Accepting new CU-UP ID %ld name %s (assoc_id %d)\n", req->gNB_cu_up_id, req->gNB_cu_up_name, assoc_id); rrc->cuup = malloc(sizeof(*rrc->cuup)); AssertFatal(rrc->cuup, "out of memory\n"); rrc->cuup->setup_req = malloc(sizeof(*rrc->cuup->setup_req)); *rrc->cuup->setup_req = *req; + rrc->cuup->assoc_id = assoc_id; MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, E1AP_SETUP_RESP); + msg_p->ittiMsgHeader.originInstance = assoc_id; e1ap_setup_resp_t *resp = &E1AP_SETUP_RESP(msg_p); resp->transac_id = req->transac_id; itti_send_msg_to_task(TASK_CUCP_E1, 0, msg_p); From e07a741ee09a19155351fea1b5a1cf395e758c11 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 27 Sep 2023 18:32:57 +0200 Subject: [PATCH 24/40] Handle multiple CU-UPs in one CU-CP This commit introduces the capability to handle multiple CU-UPs. It uses a RB tree and puts the CU-UPs into the tree. Upon the connection, it associates UEs to CU-UPs in a round-robin fashion. --- openair2/E1AP/e1ap.c | 4 +- openair2/RRC/NR/nr_rrc_defs.h | 6 ++- openair2/RRC/NR/rrc_gNB.c | 1 + openair2/RRC/NR/rrc_gNB_cuup.c | 67 +++++++++++++++++++++++++++++----- 4 files changed, 65 insertions(+), 13 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index f7ca3c379b..b88fa843ef 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1658,9 +1658,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)) - LOG_W(E1AP, "CUCP incoming call, re-use older socket context, finish implementation required\n"); - else + if (!getCxtE1(instance)) createE1inst(type, instance, NULL, NULL); e1ap_upcp_inst_t *inst = getCxtE1(instance); inst->sockState = SCTP_STATE_ESTABLISHED; diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index a1952de7a7..92b521cf69 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -372,6 +372,9 @@ typedef struct nr_rrc_du_container_t { } nr_rrc_du_container_t; typedef struct nr_rrc_cuup_container_t { + /* Tree-related data */ + RB_ENTRY(nr_rrc_cuup_container_t) entries; + e1ap_setup_req_t *setup_req; sctp_assoc_t assoc_id; } nr_rrc_cuup_container_t; @@ -405,7 +408,8 @@ typedef struct gNB_RRC_INST_s { cucp_cuup_if_t cucp_cuup; nr_rrc_du_container_t *du; - nr_rrc_cuup_container_t *cuup; + RB_HEAD(rrc_cuup_tree, nr_rrc_cuup_container_t) cuups; // CU-UPs, indexed by assoc_id + size_t num_cuups; } gNB_RRC_INST; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d92360f40b..7a8916181b 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -337,6 +337,7 @@ void openair_rrc_gNB_configuration(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *c rrc_gNB_CU_DU_init(rrc); uid_linear_allocator_init(&rrc->uid_allocator); RB_INIT(&rrc->rrc_ue_head); + RB_INIT(&rrc->cuups); rrc->configuration = *configuration; /// System Information INIT init_NR_SI(rrc); diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index a612ebe8b0..29761491ed 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -23,6 +23,33 @@ #include "nr_rrc_defs.h" #include "openair2/F1AP/f1ap_ids.h" +static int cuup_compare(const nr_rrc_cuup_container_t *a, const nr_rrc_cuup_container_t *b) +{ + if (a->assoc_id > b->assoc_id) + return 1; + if (a->assoc_id == b->assoc_id) + return 0; + return -1; /* a->assoc_id < b->assoc_id */ +} + +/* Tree management functions */ +RB_GENERATE/*_STATIC*/(rrc_cuup_tree, nr_rrc_cuup_container_t, entries, cuup_compare); + +static const nr_rrc_cuup_container_t *select_cuup_round_robin(size_t n_t, const struct rrc_cuup_tree *t, const gNB_RRC_UE_t *ue) +{ + /* pick the CU-UP following a "round-robin" fashion: select CU-UP M = RRC UE + * ID % N with N number of CU-UPs */ + int m = (ue->rrc_ue_id - 1) % n_t; + nr_rrc_cuup_container_t *cuup = NULL; + RB_FOREACH(cuup, rrc_cuup_tree, (struct rrc_cuup_tree *)&t) { + if (m == 0) + return cuup; + m--; + } + /* this should not happen: no CU-UP available? */ + return NULL; +} + sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue) { f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id); @@ -45,14 +72,21 @@ sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue /* it is zero -> no CUUP for this UE yet, get the (only) CU-UP that is * connected */ - if (!rrc->cuup) + if (RB_EMPTY(&rrc->cuups)) { + LOG_W(RRC, "no CU-UPs connected: UE %d cannot have a DRB\n", ue->rrc_ue_id); return 0; /* no CUUP connected */ + } + + const nr_rrc_cuup_container_t *selected = select_cuup_round_robin(rrc->num_cuups, &rrc->cuups, ue); + if (selected == NULL) + selected = RB_ROOT(&rrc->cuups); + AssertFatal(selected != NULL, "logic error: could not select CU-UP\n"); /* update the association for the UE so it will be picked up later */ - ue_data.e1_assoc_id = rrc->cuup->assoc_id; + ue_data.e1_assoc_id = selected->assoc_id; cu_remove_f1_ue_data(ue->rrc_ue_id); cu_add_f1_ue_data(ue->rrc_ue_id, &ue_data); - LOG_I(RRC, "UE %d associating to CU-UP assoc_id %d\n", ue->rrc_ue_id, ue_data.e1_assoc_id); + LOG_I(RRC, "UE %d associating to CU-UP assoc_id %d out of %ld CU-UPs\n", ue->rrc_ue_id, ue_data.e1_assoc_id, rrc->num_cuups); return ue_data.e1_assoc_id; } @@ -61,8 +95,21 @@ int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req) { AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n"); gNB_RRC_INST *rrc = RC.nrrrc[0]; - AssertFatal(rrc->cuup == NULL, "cannot handle multiple CU-UPs\n"); + nr_rrc_cuup_container_t *c = NULL; + RB_FOREACH(c, rrc_cuup_tree, &rrc->cuups) { + if (req->gNB_cu_up_id == c->setup_req->gNB_cu_up_id) { + LOG_E(NR_RRC, + "Connecting CU-UP ID %ld name %s (assoc_id %d) has same ID as existing CU-UP ID %ld name %s (assoc_id %d)\n", + req->gNB_cu_up_id, + req->gNB_cu_up_name, + assoc_id, + c->setup_req->gNB_cu_up_id, + c->setup_req->gNB_cu_up_name, + c->assoc_id); + return -1; + } + } for (int i = 0; i < req->supported_plmns; i++) { PLMN_ID_t *id = &req->plmn[i].id; @@ -78,11 +125,13 @@ int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req) } LOG_I(RRC, "Accepting new CU-UP ID %ld name %s (assoc_id %d)\n", req->gNB_cu_up_id, req->gNB_cu_up_name, assoc_id); - rrc->cuup = malloc(sizeof(*rrc->cuup)); - AssertFatal(rrc->cuup, "out of memory\n"); - rrc->cuup->setup_req = malloc(sizeof(*rrc->cuup->setup_req)); - *rrc->cuup->setup_req = *req; - rrc->cuup->assoc_id = assoc_id; + nr_rrc_cuup_container_t *cuup = malloc(sizeof(*cuup)); + AssertFatal(cuup, "out of memory\n"); + cuup->setup_req = malloc(sizeof(*cuup->setup_req)); + *cuup->setup_req = *req; + cuup->assoc_id = assoc_id; + RB_INSERT(rrc_cuup_tree, &rrc->cuups, cuup); + rrc->num_cuups++; MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, E1AP_SETUP_RESP); msg_p->ittiMsgHeader.originInstance = assoc_id; From 0a6998db4b6639a22c67e6048a2b8a02d8fe9b00 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 28 Sep 2023 20:53:21 +0200 Subject: [PATCH 25/40] Select CU-UP based on slice --- openair2/RRC/NR/nr_rrc_proto.h | 2 +- openair2/RRC/NR/rrc_gNB_NGAP.c | 11 ++++++++- openair2/RRC/NR/rrc_gNB_cuup.c | 45 ++++++++++++++++++++++++++++------ 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index c85aada0b9..96f5b0e28b 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -133,7 +133,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP); sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue); -sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue); +sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue, int sst, int sd); int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req); void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 553cf9ecf1..0e7f01fd8e 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -757,6 +757,8 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins UE->amf_ue_ngap_id = msg->amf_ue_ngap_id; e1ap_bearer_setup_req_t bearer_req = {0}; + + e1ap_nssai_t cuup_nssai = {0}; for (int i = 0; i < msg->nb_pdusessions_tosetup; i++) { rrc_pdu_session_param_t *pduSession = find_pduSession(UE, msg->pdusession_setup_params[i].pdusession_id, true); pdusession_t *session = &pduSession->param; @@ -780,6 +782,8 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins pdu->nssai.sd = 0xffffff; if (nssai->sD_flag) pdu->nssai.sd = nssai->sD[0] << 16 | nssai->sD[1] << 8 | nssai->sD[0]; + if (cuup_nssai.sst == 0) + cuup_nssai = pdu->nssai; /* for CU-UP selection below */ pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed; pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed; @@ -827,7 +831,12 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins } int xid = rrc_gNB_get_next_transaction_identifier(instance); UE->xids[xid] = RRC_PDUSESSION_ESTABLISH; - sctp_assoc_t assoc_id = get_new_cuup_for_ue(rrc, UE); + /* Limitation: we assume one fixed CU-UP per UE. We base the selection on + * NSSAI, but the UE might have multiple PDU sessions with differing slices, + * in which we might need to select different CU-UPs. In this case, we would + * actually need to group the E1 bearer context setup for the different + * CU-UPs, and send them to the different CU-UPs. */ + sctp_assoc_t assoc_id = get_new_cuup_for_ue(rrc, UE, cuup_nssai.sst, cuup_nssai.sd); rrc->cucp_cuup.bearer_context_setup(assoc_id, &bearer_req); return; } diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index 29761491ed..3ab6dfe7bb 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -35,6 +35,29 @@ static int cuup_compare(const nr_rrc_cuup_container_t *a, const nr_rrc_cuup_cont /* Tree management functions */ RB_GENERATE/*_STATIC*/(rrc_cuup_tree, nr_rrc_cuup_container_t, entries, cuup_compare); +static const nr_rrc_cuup_container_t *select_cuup_slice(const struct rrc_cuup_tree *t, const gNB_RRC_UE_t *ue, int sst, int sd) +{ + nr_rrc_cuup_container_t *second_best_match = NULL; /* if no NSSAI matches exactly */ + nr_rrc_cuup_container_t *cuup = NULL; + RB_FOREACH(cuup, rrc_cuup_tree, (struct rrc_cuup_tree *)&t) { + e1ap_setup_req_t *sr = cuup->setup_req; + for (int p = 0; p < sr->supported_plmns; ++p) { + /* actually we should also check that the PLMN selected by the UE matches */ + for (int s = 0; s < sr->plmn[p].supported_slices; ++s) { + e1ap_nssai_t *nssai = &sr->plmn[p].slice[s]; + if (nssai->sst == sst && nssai->sd == sd) { + LOG_I(RRC, "selecting CU-UP ID %ld based on exact NSSAI match (%d:0x%06x)\n", sr->gNB_cu_up_id, sst, sd); + return cuup; /* exact match */ + } else if (nssai->sst == sst && second_best_match == NULL) { + LOG_I(RRC, "second best match: CU-UP ID %ld matches SST %d\n", sr->gNB_cu_up_id, sst); + second_best_match = cuup; /* only the SST matches -> "good enough" */ + } + } + } + } + return second_best_match; +} + static const nr_rrc_cuup_container_t *select_cuup_round_robin(size_t n_t, const struct rrc_cuup_tree *t, const gNB_RRC_UE_t *ue) { /* pick the CU-UP following a "round-robin" fashion: select CU-UP M = RRC UE @@ -42,8 +65,10 @@ static const nr_rrc_cuup_container_t *select_cuup_round_robin(size_t n_t, const int m = (ue->rrc_ue_id - 1) % n_t; nr_rrc_cuup_container_t *cuup = NULL; RB_FOREACH(cuup, rrc_cuup_tree, (struct rrc_cuup_tree *)&t) { - if (m == 0) + if (m == 0) { + LOG_I(RRC, "round-robin match: select CU-UP ID %ld (no NSSAI match)\n", cuup->setup_req->gNB_cu_up_id); return cuup; + } m--; } /* this should not happen: no CU-UP available? */ @@ -55,18 +80,19 @@ sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id); if (ue_data.e1_assoc_id == 0) { LOG_W(RRC, "UE %d should be associated to CU-UP, but is not\n", ue->rrc_ue_id); - return get_new_cuup_for_ue(rrc, ue); + /* we could possibly check the SST/SD from the PDU session */ + return get_new_cuup_for_ue(rrc, ue, 0, 0); } LOG_D(RRC, "UE %d using CU-UP assoc_id %d\n", ue->rrc_ue_id, ue_data.e1_assoc_id); return ue_data.e1_assoc_id; } -sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue) +sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue, int sst, int sd) { /* check if there is already a UE associated */ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id); if (ue_data.e1_assoc_id != 0) { - LOG_D(RRC, "UE %d using CU-UP assoc_id %d\n", ue->rrc_ue_id, ue_data.e1_assoc_id); + LOG_I(RRC, "UE %d using CU-UP assoc_id %d\n", ue->rrc_ue_id, ue_data.e1_assoc_id); return ue_data.e1_assoc_id; } @@ -77,10 +103,15 @@ sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue return 0; /* no CUUP connected */ } - const nr_rrc_cuup_container_t *selected = select_cuup_round_robin(rrc->num_cuups, &rrc->cuups, ue); - if (selected == NULL) + const nr_rrc_cuup_container_t *selected = NULL; + if (sst != 0) /* only do if there is slice information */ + selected = select_cuup_slice(&rrc->cuups, ue, sst, sd); + if (selected == NULL) /* nothing found yet */ + selected = select_cuup_round_robin(rrc->num_cuups, &rrc->cuups, ue); + if (selected == NULL) { selected = RB_ROOT(&rrc->cuups); - AssertFatal(selected != NULL, "logic error: could not select CU-UP\n"); + } + AssertFatal(selected != NULL, "logic error: could not select CU-UP, is one connected?\n"); /* update the association for the UE so it will be picked up later */ ue_data.e1_assoc_id = selected->assoc_id; From 2136ceec0d3ea5b605df42059bc9602c94018297 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 29 Sep 2023 16:56:31 +0200 Subject: [PATCH 26/40] Do not bind on remote address in GTP This allows to communicate with multiple remote hosts. A further improvement would be to refactor this piece of code into a function and call it only when necessary, i.e., when we know the remote host, or want to add one to a list of hosts. --- openair3/ocp-gtpu/gtp_itf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 4367222404..d542dd4b30 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -510,7 +510,7 @@ static int udpServerSocket(openAddr_s addr) { freeaddrinfo(servinfo); // all done with this structure - if (strlen(addr.destinationHost)>1) { + if (false) { struct addrinfo hints; memset(&hints,0,sizeof(hints)); hints.ai_family=AF_UNSPEC; From c5006cf4edd5213bc9ed31f16842da40c8603aa7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Oct 2023 17:52:44 +0200 Subject: [PATCH 27/40] e1ap_common.h without E1AP ASN dependency --- openair2/E1AP/e1ap_common.c | 4 ++-- openair2/E1AP/e1ap_common.h | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 28764b5dec..154468fb66 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -75,7 +75,7 @@ static bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx) return true; } -E1AP_TransactionID_t E1AP_get_next_transaction_identifier() { +long E1AP_get_next_transaction_identifier() { E1AP_TransactionID_t genTransacId; bool isTransacIdValid = false; int freeIdx = 0; @@ -90,7 +90,7 @@ E1AP_TransactionID_t E1AP_get_next_transaction_identifier() { return genTransacId; } -void E1AP_free_transaction_identifier(E1AP_TransactionID_t id) { +void E1AP_free_transaction_identifier(long id) { for (int i=0; i < E1AP_MAX_NUM_TRANSAC_IDS; i++) { if (id == transacID[i]) { diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index dc615d75b3..ed6dd2606c 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -24,7 +24,6 @@ #ifndef E1AP_COMMON_H_ #define E1AP_COMMON_H_ #include "openair2/COMMON/e1ap_messages_types.h" -#include "e1ap_asnc.h" #include "openair2/COMMON/sctp_messages_types.h" #include "common/ngran_types.h" @@ -43,17 +42,20 @@ typedef struct e1ap_upcp_inst_s { extern int asn1_xer_print; -int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length); +// forward declaration so we don't require E1AP ASN.1 when including this +// header +struct E1AP_E1AP_PDU; +int e1ap_decode_pdu(struct E1AP_E1AP_PDU *pdu, const uint8_t *const buffer, uint32_t length); e1ap_upcp_inst_t *getCxtE1(instance_t instance); -E1AP_TransactionID_t E1AP_get_next_transaction_identifier(); +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); -int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func); +int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, struct E1AP_E1AP_PDU *pdu, uint16_t stream, const char *func); void e1ap_common_init(); -void E1AP_free_transaction_identifier(E1AP_TransactionID_t id); #endif /* E1AP_COMMON_H_ */ From 70ddc0e7fbf533fcf737bc39327e3f0450603de1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 9 Oct 2023 11:20:04 +0200 Subject: [PATCH 28/40] CUUP: set F1-U remote port for GTP module --- openair2/E1AP/e1ap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index b88fa843ef..459f1b4e98 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1558,6 +1558,7 @@ static instance_t cuup_task_create_gtpu_instance_to_du(eth_params_t *IPaddrs) { openAddr_t tmp= {0}; strncpy(tmp.originHost, IPaddrs->my_addr, sizeof(tmp.originHost)-1); sprintf(tmp.originService, "%d", IPaddrs->my_portd); + sprintf(tmp.destinationService, "%d", IPaddrs->remote_portd); return gtpv1Init(tmp); } @@ -1603,9 +1604,10 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, inst->cuup.assoc_id = sctp_new_association_resp->assoc_id; e1ap_net_config_t *nc = &inst->net_config; - eth_params_t IPaddr; + eth_params_t IPaddr = {0}; IPaddr.my_addr = nc->localAddressF1U; IPaddr.my_portd = nc->localPortF1U; + IPaddr.remote_portd = nc->remotePortF1U; if (getCxtE1(instance)->gtpInstF1U < 0) getCxtE1(instance)->gtpInstF1U = cuup_task_create_gtpu_instance_to_du(&IPaddr); if (getCxtE1(instance)->gtpInstF1U < 0) From 9546166ebcce393708be0b3dd274a18097a90d2c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Oct 2023 09:50:30 +0200 Subject: [PATCH 29/40] Create files to handle E1AP messages at CU-UP --- CMakeLists.txt | 4 +++ executables/nr-cuup.c | 2 +- executables/nr-softmodem.c | 2 +- executables/nr-uesoftmodem.c | 2 +- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 2 +- openair2/LAYER2/NR_MAC_gNB/main.c | 2 +- openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c | 22 ++++++++++++ openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h | 29 ++++++++++++++++ openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c | 27 +++++++++++++++ openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c | 27 +++++++++++++++ openair2/LAYER2/nr_pdcp/cuup_cucp_if.c | 37 +++++++++++++++++++++ openair2/LAYER2/nr_pdcp/cuup_cucp_if.h | 36 ++++++++++++++++++++ openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 4 ++- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h | 2 +- 14 files changed, 191 insertions(+), 7 deletions(-) create mode 100644 openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c create mode 100644 openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h create mode 100644 openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c create mode 100644 openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c create mode 100644 openair2/LAYER2/nr_pdcp/cuup_cucp_if.c create mode 100644 openair2/LAYER2/nr_pdcp/cuup_cucp_if.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8504704280..53fed85709 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1216,6 +1216,10 @@ set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c + openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c + openair2/LAYER2/nr_pdcp/cuup_cucp_if.c + openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c + openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c ) set(NR_SDAP_SRC diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c index 2992953ef0..95348dcf19 100644 --- a/executables/nr-cuup.c +++ b/executables/nr-cuup.c @@ -134,7 +134,7 @@ int main(int argc, char **argv) AssertFatal(rc >= 0, "Create task for GTPV1U failed\n"); rc = itti_create_task(TASK_CUUP_E1, E1AP_CUUP_task, NULL); AssertFatal(rc >= 0, "Create task for CUUP E1 failed\n"); - nr_pdcp_layer_init(); + 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); AssertFatal(msg != NULL, "Send init to task for E1AP UP failed\n"); diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index cbb36dc580..47e2289f36 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -566,7 +566,7 @@ void init_pdcp(void) { LINK_ENB_PDCP_TO_GTPV1U_BIT; if (!NODE_IS_DU(get_node_type())) { - nr_pdcp_layer_init(); + nr_pdcp_layer_init(get_node_type() == ngran_gNB_CUCP); nr_pdcp_module_init(pdcp_initmask, 0); } } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index e5332e8e5e..a267211ce5 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -380,7 +380,7 @@ static void init_pdcp(int ue_id) { if (get_softmodem_params()->nsa && rlc_module_init(0) != 0) { LOG_I(RLC, "Problem at RLC initiation \n"); } - nr_pdcp_layer_init(); + nr_pdcp_layer_init(false); nr_pdcp_module_init(pdcp_initmask, ue_id); pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index b4ec1cb9eb..77c6fd6c8d 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -96,7 +96,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { fill_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig); // set up PDCP, RLC, MAC - nr_pdcp_layer_init(); + nr_pdcp_layer_init(false); nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList, 0, NULL, NULL); nr_rlc_add_drb(nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); struct NR_CellGroupConfig__rlc_BearerToAddModList rlc_toadd_list; diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index d0ee9587ef..fba6dde507 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -271,7 +271,7 @@ void mac_top_init_gNB(ngran_node_t node_type, AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n"); // These should be out of here later - if (get_softmodem_params()->usim_test == 0 ) nr_pdcp_layer_init(); + if (get_softmodem_params()->usim_test == 0 ) nr_pdcp_layer_init(false); if(IS_SOFTMODEM_NOS1 && get_softmodem_params()->phy_test) { // get default noS1 configuration diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c new file mode 100644 index 0000000000..76575e65d9 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -0,0 +1,22 @@ +/* + * 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 "cucp_cuup_handler.h" diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h new file mode 100644 index 0000000000..ea75eb366e --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h @@ -0,0 +1,29 @@ +/* + * 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 CUCP_CUUP_HANDLER_H +#define CUCP_CUUP_HANDLER_H + +#include + +void nr_pdcp_e1_if_init(bool uses_e1); + +#endif /* CUCP_CUUP_HANDLER_H */ diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c b/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c new file mode 100644 index 0000000000..2741b473c0 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c @@ -0,0 +1,27 @@ +/* + * 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 "cuup_cucp_if.h" + +void cuup_cucp_init_direct(e1_if_t *iface) +{ + (void) iface; +} diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c b/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c new file mode 100644 index 0000000000..48dc148473 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c @@ -0,0 +1,27 @@ +/* + * 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 "cuup_cucp_if.h" + +void cuup_cucp_init_e1ap(e1_if_t *iface) +{ + (void) iface; +} diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_if.c b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.c new file mode 100644 index 0000000000..ddeb59205e --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.c @@ -0,0 +1,37 @@ +/* + * 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 "cuup_cucp_if.h" + +static e1_if_t e1_if; + +e1_if_t *get_e1_if(void) +{ + return &e1_if; +} + +void nr_pdcp_e1_if_init(bool uses_e1) +{ + if (uses_e1) + cuup_cucp_init_e1ap(&e1_if); + else + cuup_cucp_init_direct(&e1_if); +} diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h new file mode 100644 index 0000000000..a816853958 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h @@ -0,0 +1,36 @@ +/* + * 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 CUUP_CUCP_IF_H +#define CUUP_CUCP_IF_H + +#include + +typedef struct e1_if_t { +} e1_if_t; + +e1_if_t *get_e1_if(void); +void nr_pdcp_e1_if_init(bool uses_e1); + +void cuup_cucp_init_direct(e1_if_t *iface); +void cuup_cucp_init_e1ap(e1_if_t *iface); + +#endif /* CUUP_CUCP_IF_H */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 21331ee607..b7b9949036 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -42,6 +42,7 @@ #include "nr_pdcp_e1_api.h" #include "gnb_config.h" #include "executables/softmodem-common.h" +#include "cuup_cucp_if.h" #define TODO do { \ printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \ @@ -538,7 +539,7 @@ void pdcp_layer_init(void) abort(); } -void nr_pdcp_layer_init(void) +void nr_pdcp_layer_init(bool uses_e1) { /* hack: be sure to initialize only once */ static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; @@ -559,6 +560,7 @@ void nr_pdcp_layer_init(void) init_nr_rlc_data_req_queue(); } + nr_pdcp_e1_if_init(uses_e1); init_nr_pdcp_data_ind_queue(); nr_pdcp_init_timer_thread(nr_pdcp_ue_manager); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 6035e34bf4..85e2c4b46b 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -25,7 +25,7 @@ #include "pdcp.h" #include "nr_pdcp_ue_manager.h" -void nr_pdcp_layer_init(void); +void nr_pdcp_layer_init(bool uses_e1); uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id); void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP, From 380151faa7c50e8bea14b0cc0f0b2b2586c72863 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Oct 2023 15:03:51 +0200 Subject: [PATCH 30/40] E1 Bearer Context Setup Request: harmonize code - harmonize monolithic and E1AP case - use ITTI message to send bearer context setup response to RRC --- CMakeLists.txt | 8 +- executables/nr-cuup.c | 22 +-- openair1/SIMULATION/NR_PHY/dlsim.c | 2 + openair1/SIMULATION/NR_PHY/ulsim.c | 2 + openair2/E1AP/CMakeLists.txt | 2 +- openair2/E1AP/e1ap.c | 25 ++- openair2/E1AP/e1ap.h | 2 +- openair2/E1AP/e1ap_api.c | 141 -------------- openair2/E1AP/e1ap_api.h | 1 - openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c | 199 ++++++++++++++++++++ openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h | 3 + openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c | 12 +- openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c | 12 +- openair2/LAYER2/nr_pdcp/cuup_cucp_if.h | 4 + openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c | 54 ------ openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h | 53 ------ openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 1 - openair2/RRC/NR/cucp_cuup_direct.c | 150 +-------------- openair2/RRC/NR/cucp_cuup_e1ap.c | 9 +- openair2/RRC/NR/cucp_cuup_if.h | 2 +- openair2/RRC/NR/nr_rrc_proto.h | 2 - openair2/RRC/NR/rrc_gNB.c | 71 +++---- openair2/RRC/NR/rrc_gNB_GTPV1U.c | 32 ---- openair2/RRC/NR/rrc_gNB_GTPV1U.h | 2 - openair2/RRC/NR/rrc_gNB_NGAP.c | 4 + 25 files changed, 300 insertions(+), 515 deletions(-) delete mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c delete mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 53fed85709..27a7c471d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1450,12 +1450,6 @@ add_library(e1_if target_link_libraries(e1_if PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap SECURITY ${OPENSSL_LIBRARIES} e1ap GTPV1U) -add_library(e1_pdcp_if - ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_e1_api.c - ) - -target_link_libraries(e1_pdcp_if PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) - target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap nr_rlc) if(E2_AGENT) target_link_libraries(L2_NR PUBLIC e2_agent e2_ran_func) @@ -2111,7 +2105,7 @@ add_executable(nr-cuup target_link_libraries(nr-cuup PRIVATE CONFIG_LIB ITTI SCTP_CLIENT - GTPV1U e1ap e1_pdcp_if f1ap SIMU_ETH + GTPV1U e1ap f1ap SIMU_ETH z sctp dl pthread shlib_loader ${T_LIB}) target_link_libraries(nr-cuup PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c index 95348dcf19..d83137c328 100644 --- a/executables/nr-cuup.c +++ b/executables/nr-cuup.c @@ -95,12 +95,6 @@ void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Beare abort(); } -int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_p, int offset) -{ - abort(); - return 0; -} - void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp) { abort(); @@ -108,14 +102,14 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex f1ap_cudu_inst_t *getCxt(instance_t instanceP) { - abort(); - return NULL; -} - -NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue) -{ - abort(); - return NULL; + // the E1 module uses F1's getCxt() to decide whether there is F1-U and if + // so, what is the GTP instance. In the CU-UP, we don't start the F1 module, + // and instead, E1 handles the GTP-U endpoint. In the following, we fake the + // instance and put the right GTP-U instance number in. + const e1ap_upcp_inst_t *e1inst = getCxtE1(instanceP); + static f1ap_cudu_inst_t fake = {0}; + fake.gtpInst = e1inst->gtpInstF1U; + return &fake; } int main(int argc, char **argv) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 6d80ac619c..8a5ede9159 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -108,6 +108,8 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB return; } +void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } + int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; } diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 77a1d6d821..7307575bdb 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -104,6 +104,8 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB return; } +void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } + int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; } diff --git a/openair2/E1AP/CMakeLists.txt b/openair2/E1AP/CMakeLists.txt index 01a969de7e..0384c2860b 100644 --- a/openair2/E1AP/CMakeLists.txt +++ b/openair2/E1AP/CMakeLists.txt @@ -3,5 +3,5 @@ add_subdirectory(MESSAGES) add_library(e1ap e1ap.c e1ap_common.c e1ap_api.c) target_link_libraries(e1ap PUBLIC asn1_e1ap f1ap - PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap UTIL e1_pdcp_if e1_if) + PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap UTIL e1_if) target_include_directories(e1ap PUBLIC ${CMAKE_CURRENT_DIR}) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 459f1b4e98..45f3c4cd17 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -33,6 +33,7 @@ #include "openair2/F1AP/f1ap_common.h" #include "e1ap_default_values.h" #include "gtp_itf.h" +#include "openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h" #define E1AP_NUM_MSG_HANDLERS 14 typedef int (*e1ap_message_processing_t)(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *message_p); @@ -684,7 +685,7 @@ void e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_bear e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } -static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const resp, E1AP_E1AP_PDU_t *pdu) +static void fill_BEARER_CONTEXT_SETUP_RESPONSE(const e1ap_bearer_setup_resp_t *resp, E1AP_E1AP_PDU_t *pdu) { /* Create */ /* 0. pdu Type */ @@ -750,7 +751,7 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const r msgNGRAN->value.present = E1AP_NG_RAN_BearerContextSetupResponse__value_PR_PDU_Session_Resource_Setup_List; E1AP_PDU_Session_Resource_Setup_List_t *pduSetup = &msgNGRAN->value.choice.PDU_Session_Resource_Setup_List; - for (pdu_session_setup_t *i=resp->pduSession; i < resp->pduSession+resp->numPDUSessions; i++) { + for (const pdu_session_setup_t *i=resp->pduSession; i < resp->pduSession+resp->numPDUSessions; i++) { asn1cSequenceAdd(pduSetup->list, E1AP_PDU_Session_Resource_Setup_Item_t, ieC3_1); ieC3_1->pDU_Session_ID = i->id; @@ -759,11 +760,11 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const r TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress); INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID); - for (DRB_nGRAN_setup_t *j=i->DRBnGRanList; j < i->DRBnGRanList+i->numDRBSetup; j++) { + for (const DRB_nGRAN_setup_t *j=i->DRBnGRanList; j < i->DRBnGRanList+i->numDRBSetup; j++) { asn1cSequenceAdd(ieC3_1->dRB_Setup_List_NG_RAN.list, E1AP_DRB_Setup_Item_NG_RAN_t, ieC3_1_1); ieC3_1_1->dRB_ID = j->id; - for (up_params_t *k=j->UpParamList; k < j->UpParamList+j->numUpParam; k++) { + for (const up_params_t *k=j->UpParamList; k < j->UpParamList+j->numUpParam; k++) { asn1cSequenceAdd(ieC3_1_1->uL_UP_Transport_Parameters.list, E1AP_UP_Parameters_Item_t, ieC3_1_1_1); ieC3_1_1_1->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel; asn1cCalloc(ieC3_1_1_1->uP_TNL_Information.choice.gTPTunnel, gTPTunnel); @@ -771,7 +772,7 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const r INT32_TO_OCTET_STRING(k->teId, &gTPTunnel->gTP_TEID); } - for (qos_flow_setup_t *k=j->qosFlows; k < j->qosFlows+j->numQosFlowSetup; k++) { + for (const qos_flow_setup_t *k=j->qosFlows; k < j->qosFlows+j->numQosFlowSetup; k++) { asn1cSequenceAdd(ieC3_1_1->flow_Setup_List.list, E1AP_QoS_Flow_Item_t, ieC3_1_1_1); ieC3_1_1_1->qoS_Flow_Identifier = k->id; } @@ -780,7 +781,7 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const r if (i->numDRBFailed > 0) ieC3_1->dRB_Failed_List_NG_RAN = calloc(1, sizeof(E1AP_DRB_Failed_List_NG_RAN_t)); - for (DRB_nGRAN_failed_t *j=i->DRBnGRanFailedList; j < i->DRBnGRanFailedList+i->numDRBFailed; j++) { + for (const DRB_nGRAN_failed_t *j=i->DRBnGRanFailedList; j < i->DRBnGRanFailedList+i->numDRBFailed; j++) { asn1cSequenceAdd(ieC3_1->dRB_Failed_List_NG_RAN->list, E1AP_DRB_Failed_Item_NG_RAN_t, ieC3_1_1); ieC3_1_1->dRB_ID = j->id; @@ -811,7 +812,7 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(e1ap_bearer_setup_resp_t *const r } } -void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_bearer_setup_resp_t *const resp) +void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1ap_bearer_setup_resp_t *resp) { E1AP_E1AP_PDU_t pdu = {0}; fill_BEARER_CONTEXT_SETUP_RESPONSE(resp, &pdu); @@ -996,7 +997,8 @@ int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_upc e1ap_bearer_setup_req_t bearerCxt = {0}; extract_BEARER_CONTEXT_SETUP_REQUEST(pdu, &bearerCxt); - process_e1_bearer_context_setup_req(e1_inst->instance, &bearerCxt); + + e1_bearer_context_setup(&bearerCxt); return 0; } @@ -1769,6 +1771,13 @@ void *E1AP_CUUP_task(void *arg) { e1apHandleTimer(myInstance); break; + case E1AP_BEARER_CONTEXT_SETUP_RESP: { + const e1ap_bearer_setup_resp_t *resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg); + const e1ap_upcp_inst_t *inst = getCxtE1(myInstance); + AssertFatal(inst != NULL, "no E1 instance found for instance %ld\n", myInstance); + e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst->cuup.assoc_id, resp); + } break; + default: LOG_E(E1AP, "Unknown message received in TASK_CUUP_E1\n"); break; diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h index 8a7c6ba2df..c9d6345318 100644 --- a/openair2/E1AP/e1ap.h +++ b/openair2/E1AP/e1ap.h @@ -42,7 +42,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upc int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_bearer_setup_resp_t *const resp); +void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1ap_bearer_setup_resp_t *resp); int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index cf3fe14de1..816867a6ab 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -25,7 +25,6 @@ #include "e1ap_api.h" #include "nr_pdcp/nr_pdcp_entity.h" -#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" #include "openair2/RRC/NR/cucp_cuup_if.h" #include "openair2/RRC/LTE/MESSAGES/asn1_msg.h" #include "openair3/SECU/key_nas_deriver.h" @@ -35,146 +34,6 @@ #include "e1ap_common.h" #include "e1ap.h" -struct NR_DRB_ToAddMod; -static void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, pdu_session_to_setup_t *pdu) { - - for (int i=0; i < pdu->numDRB2Setup; i++) { - DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + i; - asn1cSequenceAdd(DRB_configList->list, struct NR_DRB_ToAddMod, ie); - ie->drb_Identity = drb->id; - ie->cnAssociation = CALLOC(1, sizeof(*ie->cnAssociation)); - ie->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; - - // sdap_Config - asn1cCalloc(ie->cnAssociation->choice.sdap_Config, sdap_config); - sdap_config->pdu_Session = pdu->sessionId; - sdap_config->sdap_HeaderDL = drb->sDAP_Header_DL; - sdap_config->sdap_HeaderUL = drb->sDAP_Header_UL; - sdap_config->defaultDRB = drb->defaultDRB; - - asn1cCalloc(sdap_config->mappedQoS_FlowsToAdd, FlowsToAdd); - for (int j=0; j < drb->numQosFlow2Setup; j++) { - asn1cSequenceAdd(FlowsToAdd->list, NR_QFI_t, qfi); - *qfi = drb->qosFlows[j].fiveQI; - } - sdap_config->mappedQoS_FlowsToRelease = NULL; - - // pdcp_Config - ie->reestablishPDCP = NULL; - ie->recoverPDCP = NULL; - asn1cCalloc(ie->pdcp_Config, pdcp_config); - asn1cCalloc(pdcp_config->drb, drbCfg); - asn1cCallocOne(drbCfg->discardTimer, drb->discardTimer); - asn1cCallocOne(drbCfg->pdcp_SN_SizeUL, drb->pDCP_SN_Size_UL); - asn1cCallocOne(drbCfg->pdcp_SN_SizeDL, drb->pDCP_SN_Size_DL); - drbCfg->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; - drbCfg->headerCompression.choice.notUsed = 0; - - drbCfg->integrityProtection = NULL; - drbCfg->statusReportRequired = NULL; - drbCfg->outOfOrderDelivery = NULL; - pdcp_config->moreThanOneRLC = NULL; - - pdcp_config->t_Reordering = calloc(1, sizeof(*pdcp_config->t_Reordering)); - *pdcp_config->t_Reordering = drb->reorderingTimer; - pdcp_config->ext1 = NULL; - - if (pdu->integrityProtectionIndication == 0 || // Required - pdu->integrityProtectionIndication == 1) { // Preferred - asn1cCallocOne(drbCfg->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled); - } - - if (pdu->confidentialityProtectionIndication == 2) { // Not Needed - asn1cCalloc(pdcp_config->ext1, ext1); - asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true); - } - } -} - -static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req, - gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp, - instance_t instance) { - - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; - - NR_DRB_ToAddModList_t DRB_configList = {0}; - for (int i=0; i < req->numPDUSessions; i++) { - pdu_session_to_setup_t *const pdu = &req->pduSession[i]; - create_tunnel_req.pdusession_id[i] = pdu->sessionId; - create_tunnel_req.incoming_rb_id[i] = pdu->DRBnGRanList[0].id; // taking only the first DRB. TODO:change this - memcpy(&create_tunnel_req.dst_addr[i].buffer, - &pdu->tlAddress, - sizeof(uint8_t)*4); - create_tunnel_req.dst_addr[i].length = 32; // 8bits * 4bytes - create_tunnel_req.outgoing_teid[i] = pdu->teId; - fill_DRB_configList_e1(&DRB_configList, pdu); - } - create_tunnel_req.num_tunnels = req->numPDUSessions; - create_tunnel_req.ue_id = req->gNB_cu_cp_ue_id; - - // Create N3 tunnel - int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req); - if (ret != 0) { - LOG_E(NR_RRC, - "drb_config_N3gtpu_create=>gtpv1u_create_ngu_tunnel failed, cannot set up GTP tunnel for data transmissions of UE %ld\n", - create_tunnel_req.ue_id); - return ret; - } - - // Configure DRBs - nr_pdcp_e1_add_drbs(true, // set this to notify PDCP that his not UE - create_tunnel_req.ue_id, - &DRB_configList, - (req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm, - (uint8_t *)req->encryptionKey, - (uint8_t *)req->integrityProtectionKey); - return ret; -} - -void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_req_t *const req) -{ - e1ap_upcp_inst_t *inst = getCxtE1(instance); - AssertFatal(inst, ""); - gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0}; - - uint32_t gNB_cu_up_ue_id = req ->gNB_cu_cp_ue_id; - LOG_I(E1AP, "adding UE with CU-CP UE ID %d and CU-UP UE ID %d\n", req->gNB_cu_cp_ue_id, gNB_cu_up_ue_id); - f1_ue_data_t ue_data = {.secondary_ue = req->gNB_cu_cp_ue_id}; - cu_add_f1_ue_data(gNB_cu_up_ue_id, &ue_data); - - // GTP tunnel for UL - drb_config_N3gtpu_create(req, &create_tunnel_resp_N3, inst->gtpInstN3); - - MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_RESP); - e1ap_bearer_setup_resp_t *resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg); - - in_addr_t my_addr; - if (inet_pton(AF_INET, inst->net_config.localAddressF1U, &my_addr) != 1) - LOG_E(E1AP, "can't use the F1-U local interface: %s\n", inst->net_config.localAddressF1U); - fill_e1ap_bearer_setup_resp(resp, req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id, inst->net_config.remotePortF1U, my_addr); - - resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id; - resp->gNB_cu_up_ue_id = gNB_cu_up_ue_id; - resp->numPDUSessions = req->numPDUSessions; - for (int i=0; i < req->numPDUSessions; i++) { - pdu_session_setup_t *pduSetup = resp->pduSession + i; - pdu_session_to_setup_t *pdu2Setup = req->pduSession + i; - - pduSetup->id = pdu2Setup->sessionId; - if (inet_pton(AF_INET, inst->net_config.localAddressN3, &pduSetup->tlAddress) != 1) - LOG_E(E1AP, "can't use the N3 local interface: %s\n", inst->net_config.localAddressN3); - pduSetup->teId = create_tunnel_resp_N3.gnb_NGu_teid[i]; - pduSetup->numDRBSetup = pdu2Setup->numDRB2Setup; - - // At this point we don't have a way to know the DRBs that failed to setup - // We assume all DRBs to setup have are setup successfully so we always send successful outcome in response - // TODO: Modify nr_pdcp_add_drbs() to return DRB list that failed to setup to support E1AP - pduSetup->numDRBFailed = 0; - } - - e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst->cuup.assoc_id, resp); -} - void CUUP_process_bearer_context_mod_req(instance_t instance, e1ap_bearer_setup_req_t *const req) { e1ap_upcp_inst_t *inst = getCxtE1(instance); diff --git a/openair2/E1AP/e1ap_api.h b/openair2/E1AP/e1ap_api.h index 1b9f219fcc..a6cbe228d1 100644 --- a/openair2/E1AP/e1ap_api.h +++ b/openair2/E1AP/e1ap_api.h @@ -28,7 +28,6 @@ #include "openair2/COMMON/e1ap_messages_types.h" #include "openair2/E1AP/e1ap_common.h" void cuup_init_n3(instance_t instance); -void process_e1_bearer_context_setup_req(instance_t, e1ap_bearer_setup_req_t *const req); void CUUP_process_bearer_context_mod_req(instance_t, e1ap_bearer_setup_req_t *const req); void CUUP_process_bearer_release_command(instance_t, e1ap_bearer_release_cmd_t *const cmd); diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index 76575e65d9..29ccb6bf32 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -20,3 +20,202 @@ */ #include "cucp_cuup_handler.h" + +#include "NR_DRB-ToAddModList.h" + +#include "platform_types.h" +#include "intertask_interface.h" +#include "openair2/COMMON/e1ap_messages_types.h" +#include "openair3/ocp-gtpu/gtp_itf.h" +#include "openair2/F1AP/f1ap_ids.h" +#include "nr_pdcp_oai_api.h" +#include "cuup_cucp_if.h" +#include "common/utils/oai_asn1.h" +#include "openair2/SDAP/nr_sdap/nr_sdap.h" +#include "openair2/E1AP/e1ap_common.h" +#include "openair2/F1AP/f1ap_common.h" + +static void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, const pdu_session_to_setup_t *pdu) +{ + for (int i=0; i < pdu->numDRB2Setup; i++) { + const DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + i; + asn1cSequenceAdd(DRB_configList->list, struct NR_DRB_ToAddMod, ie); + ie->drb_Identity = drb->id; + ie->cnAssociation = CALLOC(1, sizeof(*ie->cnAssociation)); + ie->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; + + // sdap_Config + asn1cCalloc(ie->cnAssociation->choice.sdap_Config, sdap_config); + sdap_config->pdu_Session = pdu->sessionId; + sdap_config->sdap_HeaderDL = drb->sDAP_Header_DL; + sdap_config->sdap_HeaderUL = drb->sDAP_Header_UL; + sdap_config->defaultDRB = drb->defaultDRB; + + asn1cCalloc(sdap_config->mappedQoS_FlowsToAdd, FlowsToAdd); + for (int j=0; j < drb->numQosFlow2Setup; j++) { + asn1cSequenceAdd(FlowsToAdd->list, NR_QFI_t, qfi); + *qfi = drb->qosFlows[j].fiveQI; + } + sdap_config->mappedQoS_FlowsToRelease = NULL; + + // pdcp_Config + ie->reestablishPDCP = NULL; + ie->recoverPDCP = NULL; + asn1cCalloc(ie->pdcp_Config, pdcp_config); + asn1cCalloc(pdcp_config->drb, drbCfg); + asn1cCallocOne(drbCfg->discardTimer, drb->discardTimer); + asn1cCallocOne(drbCfg->pdcp_SN_SizeUL, drb->pDCP_SN_Size_UL); + asn1cCallocOne(drbCfg->pdcp_SN_SizeDL, drb->pDCP_SN_Size_DL); + drbCfg->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; + drbCfg->headerCompression.choice.notUsed = 0; + + drbCfg->integrityProtection = NULL; + drbCfg->statusReportRequired = NULL; + drbCfg->outOfOrderDelivery = NULL; + pdcp_config->moreThanOneRLC = NULL; + + pdcp_config->t_Reordering = calloc(1, sizeof(*pdcp_config->t_Reordering)); + *pdcp_config->t_Reordering = drb->reorderingTimer; + pdcp_config->ext1 = NULL; + + if (pdu->integrityProtectionIndication == 0 || // Required + pdu->integrityProtectionIndication == 1) { // Preferred + asn1cCallocOne(drbCfg->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled); + } + + if (pdu->confidentialityProtectionIndication == 2) { // Not Needed + asn1cCalloc(pdcp_config->ext1, ext1); + asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true); + } + } +} + +static int drb_gtpu_create(instance_t instance, + uint32_t ue_id, + int incoming_id, + int outgoing_id, + int qfi, + in_addr_t tlAddress, // only IPv4 now + teid_t outgoing_teid, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP, + gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp) +{ + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0}; + create_tunnel_req.incoming_rb_id[0] = incoming_id; + create_tunnel_req.pdusession_id[0] = outgoing_id; + memcpy(&create_tunnel_req.dst_addr[0].buffer, &tlAddress, sizeof(uint8_t) * 4); + create_tunnel_req.dst_addr[0].length = 32; + create_tunnel_req.outgoing_teid[0] = outgoing_teid; + create_tunnel_req.outgoing_qfi[0] = qfi; + create_tunnel_req.num_tunnels = 1; + create_tunnel_req.ue_id = ue_id; + + // we use gtpv1u_create_ngu_tunnel because it returns the interface + // address and port of the interface; apart from that, we also might call + // newGtpuCreateTunnel() directly + return gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, callBack, callBackSDAP); +} + +static instance_t get_n3_gtp_instance(void) +{ + const e1ap_upcp_inst_t *inst = getCxtE1(0); + AssertFatal(inst != NULL, "need to have E1 instance\n"); + return inst->gtpInstN3; +} + +static instance_t get_f1_gtp_instance(void) +{ + const f1ap_cudu_inst_t *inst = getCxt(0); + if (!inst) + return -1; // means no F1 + return inst->gtpInst; +} + +void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) +{ + /* mirror the CU-CP UE ID for CU-UP */ + uint32_t cu_up_ue_id = req->gNB_cu_cp_ue_id; + f1_ue_data_t ued = {.secondary_ue = req->gNB_cu_cp_ue_id}; + cu_add_f1_ue_data(cu_up_ue_id, &ued); + LOG_I(E1AP, "adding UE with CU-CP UE ID %d and CU-UP UE ID %d\n", req->gNB_cu_cp_ue_id, cu_up_ue_id); + + instance_t n3inst = get_n3_gtp_instance(); + instance_t f1inst = get_f1_gtp_instance(); + + e1ap_bearer_setup_resp_t resp = { + .gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id, + .gNB_cu_up_ue_id = cu_up_ue_id, + }; + resp.numPDUSessions = req->numPDUSessions; + for (int i = 0; i < resp.numPDUSessions; ++i) { + pdu_session_setup_t *resp_pdu = resp.pduSession + i; + const pdu_session_to_setup_t *req_pdu = req->pduSession + i; + resp_pdu->id = req_pdu->sessionId; + + AssertFatal(req_pdu->numDRB2Modify == 0, "DRB modification not implemented\n"); + AssertFatal(req_pdu->numDRB2Setup == 1, "can only handle one DRB per PDU session\n"); + resp_pdu->numDRBSetup = req_pdu->numDRB2Setup; + const DRB_nGRAN_to_setup_t *req_drb = &req_pdu->DRBnGRanList[0]; + DRB_nGRAN_setup_t *resp_drb = &resp_pdu->DRBnGRanList[0]; + resp_drb->id = req_drb->id; + resp_drb->numQosFlowSetup = req_drb->numQosFlow2Setup; + for (int k = 0; k < resp_drb->numQosFlowSetup; k++) + resp_drb->qosFlows[k].id = req_drb->qosFlows[k].id; + + // GTP tunnel for N3/to core + gtpv1u_gnb_create_tunnel_resp_t resp_n3 = {0}; + int qfi = 0; // put PDU session marker + int ret = drb_gtpu_create(n3inst, + cu_up_ue_id, + req_drb->id, + req_pdu->sessionId, + qfi, + req_pdu->tlAddress, + req_pdu->teId, + nr_pdcp_data_req_drb, + sdap_data_req, + &resp_n3); + AssertFatal(ret >= 0, "Unable to create GTP Tunnel for NG-U\n"); + AssertFatal(resp_n3.num_tunnels == req->numPDUSessions, "could not create all tunnels\n"); + resp_pdu->teId = resp_n3.gnb_NGu_teid[i]; + memcpy(&resp_pdu->tlAddress, &resp_n3.gnb_addr.buffer, 4); + + // create PDCP bearers. This will also create SDAP bearers + NR_DRB_ToAddModList_t DRB_configList = {0}; + fill_DRB_configList_e1(&DRB_configList, req_pdu); + nr_pdcp_add_drbs(true, // set this to notify PDCP that his not UE + cu_up_ue_id, + &DRB_configList, + (req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm, + (uint8_t *)req->encryptionKey, + (uint8_t *)req->integrityProtectionKey); + + if (f1inst >= 0) { /* we have F1(-U) */ + teid_t dummy_teid = 0xffff; // we will update later with answer from DU + in_addr_t dummy_address = {0}; // IPv4, updated later with answer from DU + gtpv1u_gnb_create_tunnel_resp_t resp_f1 = {0}; + int qfi = -1; // don't put PDU session marker in GTP + int ret = drb_gtpu_create(f1inst, + cu_up_ue_id, + req_drb->id, + req_drb->id, + qfi, + dummy_address, + dummy_teid, + cu_f1u_data_req, + NULL, + &resp_f1); + resp_drb->numUpParam = 1; + AssertFatal(ret >= 0, "Unable to create GTP Tunnel for F1-U\n"); + memcpy(&resp_drb->UpParamList[0].tlAddress, &resp_f1.gnb_addr.buffer, 4); + resp_drb->UpParamList[0].teId = resp_f1.gnb_NGu_teid[0]; + } + + // We assume all DRBs to setup have been setup successfully, so we always + // send successful outcome in response and no failed DRBs + resp_pdu->numDRBFailed = 0; + } + + get_e1_if()->bearer_setup_response(&resp); +} diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h index ea75eb366e..ec220876f5 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h @@ -26,4 +26,7 @@ void nr_pdcp_e1_if_init(bool uses_e1); +struct e1ap_bearer_setup_req_s; +void e1_bearer_context_setup(const struct e1ap_bearer_setup_req_s *req); + #endif /* CUCP_CUUP_HANDLER_H */ diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c b/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c index 2741b473c0..dd87e56b5d 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c @@ -20,8 +20,18 @@ */ #include "cuup_cucp_if.h" +#include "e1ap_messages_types.h" +#include "intertask_interface.h" + +static void bearer_setup_response_direct(const e1ap_bearer_setup_resp_t *resp) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, E1AP_BEARER_CONTEXT_SETUP_RESP); + e1ap_bearer_setup_resp_t *msg_resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg); + *msg_resp = *resp; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); +} void cuup_cucp_init_direct(e1_if_t *iface) { - (void) iface; + iface->bearer_setup_response = bearer_setup_response_direct; } diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c b/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c index 48dc148473..8db854786b 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c @@ -20,8 +20,18 @@ */ #include "cuup_cucp_if.h" +#include "intertask_interface.h" +#include "e1ap_messages_types.h" + +static void bearer_setup_response_e1ap(const e1ap_bearer_setup_resp_t *resp) +{ + MessageDef *msg_p = itti_alloc_new_message(TASK_CUUP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_RESP); + e1ap_bearer_setup_resp_t *bearer_resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p); + *bearer_resp = *resp; + itti_send_msg_to_task (TASK_CUUP_E1, 0, msg_p); +} void cuup_cucp_init_e1ap(e1_if_t *iface) { - (void) iface; + iface->bearer_setup_response = bearer_setup_response_e1ap; } diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h index a816853958..5ec064ba03 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h @@ -24,7 +24,11 @@ #include +struct e1ap_bearer_setup_resp_s; +typedef void (*e1_bearer_setup_response_func_t)(const struct e1ap_bearer_setup_resp_s *resp); + typedef struct e1_if_t { + e1_bearer_setup_response_func_t bearer_setup_response; } e1_if_t; e1_if_t *get_e1_if(void); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c deleted file mode 100644 index c7c91a38a0..0000000000 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include "nr_pdcp_e1_api.h" - -void e1_add_drb(int is_gnb, - uint64_t ue_id, - struct NR_DRB_ToAddMod *s, - int ciphering_algorithm, - int integrity_algorithm, - unsigned char *ciphering_key, - unsigned char *integrity_key) -{ - add_drb(is_gnb, ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); - LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID %ld\n", __FILE__, __FUNCTION__, __LINE__, ue_id); -} - -void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag, - uint64_t ue_id, - NR_DRB_ToAddModList_t *const drb2add_list, - const uint8_t security_modeP, - uint8_t *const kUPenc, - uint8_t *const kUPint) { - - if (drb2add_list != NULL) { - for (int i = 0; i < drb2add_list->list.count; i++) { - e1_add_drb(enb_flag, ue_id, drb2add_list->list.array[i], - security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, - kUPenc, kUPint); - } - } else - LOG_W(PDCP, "%s with void list\n", __FUNCTION__); -} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h deleted file mode 100644 index 3c16996126..0000000000 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include "common/utils/oai_asn1.h" -#include "NR_RadioBearerConfig.h" - -#include "nr_pdcp_oai_api.h" -#include "LAYER2/nr_rlc/nr_rlc_oai_api.h" -#include -#include "openair2/SDAP/nr_sdap/nr_sdap.h" - -void e1_add_drb(int is_gnb, - uint64_t ue_id, - struct NR_DRB_ToAddMod *s, - int ciphering_algorithm, - int integrity_algorithm, - unsigned char *ciphering_key, - unsigned char *integrity_key); - -void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag, - uint64_t ue_id, - NR_DRB_ToAddModList_t *const drb2add_list, - const uint8_t security_modeP, - uint8_t *const kUPenc, - uint8_t *const kUPint); - -void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, - int ciphering_algorithm, - int integrity_algorithm, - unsigned char *ciphering_key, - unsigned char *integrity_key); - diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index b7b9949036..eb1367c724 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -39,7 +39,6 @@ #include "openair2/F1AP/f1ap_ids.h" #include #include "openair2/SDAP/nr_sdap/nr_sdap.h" -#include "nr_pdcp_e1_api.h" #include "gnb_config.h" #include "executables/softmodem-common.h" #include "cuup_cucp_if.h" diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index a62f576c72..8806718915 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -32,7 +32,7 @@ #include "openair3/SECU/key_nas_deriver.h" #include "nr_pdcp/nr_pdcp_entity.h" -#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" +#include "openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h" #include #include "openair3/ocp-gtpu/gtp_itf.h" #include "rrc_gNB_GTPV1U.h" @@ -42,42 +42,10 @@ extern RAN_CONTEXT_t RC; -void fill_e1ap_bearer_setup_resp(e1ap_bearer_setup_resp_t *resp, - e1ap_bearer_setup_req_t *const req, - instance_t gtpInst, - ue_id_t ue_id, - int remote_port, - in_addr_t my_addr) { - - resp->numPDUSessions = req->numPDUSessions; - transport_layer_addr_t dummy_address = {0}; - dummy_address.length = 32; // IPv4 - for (int i=0; i < req->numPDUSessions; i++) { - resp->pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup; - for (int j=0; j < req->pduSession[i].numDRB2Setup; j++) { - DRB_nGRAN_to_setup_t *drb2Setup = req->pduSession[i].DRBnGRanList + j; - DRB_nGRAN_setup_t *drbSetup = resp->pduSession[i].DRBnGRanList + j; - - drbSetup->numUpParam = 1; - drbSetup->UpParamList[0].tlAddress = my_addr; - drbSetup->UpParamList[0].teId = newGtpuCreateTunnel(gtpInst, - ue_id, - drb2Setup->id, - drb2Setup->id, - 0xFFFF, // We will set the right value from DU answer - -1, // no qfi - dummy_address, // We will set the right value from DU answer - remote_port, - cu_f1u_data_req, - NULL); - drbSetup->id = drb2Setup->id; - - drbSetup->numQosFlowSetup = drb2Setup->numQosFlow2Setup; - for (int k=0; k < drbSetup->numQosFlowSetup; k++) { - drbSetup->qosFlows[k].id = drb2Setup->qosFlows[k].id; - } - } - } +static void cucp_cuup_bearer_context_setup_direct(sctp_assoc_t assoc_id, const e1ap_bearer_setup_req_t *req) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d, impossible for integrated CU\n", assoc_id); + e1_bearer_context_setup(req); } void CU_update_UP_DL_tunnel(e1ap_bearer_setup_req_t *const req, instance_t instance, ue_id_t ue_id) { @@ -97,114 +65,6 @@ void CU_update_UP_DL_tunnel(e1ap_bearer_setup_req_t *const req, instance_t insta } } -static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, - rrc_gNB_ue_context_t *ue_context_p, - e1ap_bearer_setup_req_t *const req, - NR_DRB_ToAddModList_t *DRB_configList, - instance_t instance) -{ - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; - gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0}; - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - LOG_W(NR_RRC, "recreate existing tunnels, while adding new ones\n"); - for (int i = 0; i < UE->nb_of_pdusessions; i++) { - rrc_pdu_session_param_t *pdu = UE->pduSession + i; - create_tunnel_req.pdusession_id[i] = pdu->param.pdusession_id; - create_tunnel_req.incoming_rb_id[i] = i + 1; - create_tunnel_req.outgoing_qfi[i] = req->pduSession[i].DRBnGRanList[0].qosFlows[0].id; - memcpy(&create_tunnel_req.dst_addr[i].buffer, &pdu->param.upf_addr.buffer, sizeof(create_tunnel_req.dst_addr[0].buffer)); - create_tunnel_req.dst_addr[i].length = pdu->param.upf_addr.length; - create_tunnel_req.outgoing_teid[i] = pdu->param.gtp_teid; - } - create_tunnel_req.num_tunnels = UE->nb_of_pdusessions; - create_tunnel_req.ue_id = UE->rrc_ue_id; - int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3, - &create_tunnel_req, - &create_tunnel_resp, - nr_pdcp_data_req_drb, - sdap_data_req); - - if (ret != 0) { - LOG_E(NR_RRC, - "drb_config_gtpu_create=>gtpv1u_create_ngu_tunnel failed, cannot set up GTP tunnel for data transmissions of UE %ld\n", - create_tunnel_req.ue_id); - return ret; - } - - nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_p, &create_tunnel_resp, 0); - - uint8_t kRRCenc[16] = {0}; - uint8_t kRRCint[16] = {0}; - uint8_t kUPenc[16] = {0}; - uint8_t kUPint[16] = {0}; - /* Derive the keys from kgnb */ - if (DRB_configList != NULL) { - nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc); - nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, kUPint); - } - - nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc); - nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint); - - /* Refresh SRBs/DRBs */ - - LOG_D(NR_RRC, "Configuring PDCP DRBs for UE %x\n", UE->rnti); - nr_pdcp_add_drbs(ctxt_p->enb_flag, - UE->rrc_ue_id, - DRB_configList, - (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, - kUPenc, - kUPint); - - return ret; -} - -static void cucp_cuup_bearer_context_setup_direct(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const req) -{ - AssertFatal(assoc_id == -1, "illegal assoc_id %d, impossible for integrated CU\n", assoc_id); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[0], req->gNB_cu_cp_ue_id); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0, 0); - - e1ap_bearer_setup_resp_t resp = {0}; - resp.numPDUSessions = req->numPDUSessions; - for (int i = 0; i < resp.numPDUSessions; ++i) { - resp.pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup; - for (int j = 0; j < req->pduSession[i].numDRB2Setup; j++) { - DRB_nGRAN_to_setup_t *req_drb = req->pduSession[i].DRBnGRanList + j; - DRB_nGRAN_setup_t *resp_drb = resp.pduSession[i].DRBnGRanList + j; - resp_drb->id = req_drb->id; - resp_drb->numQosFlowSetup = req_drb->numQosFlow2Setup; - for (int k = 0; k < resp_drb->numQosFlowSetup; k++) - resp_drb->qosFlows[k].id = req_drb->qosFlows[k].id; - } - } - - gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - // GTP tunnel for UL - NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(UE); - int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, DRB_configList, rrc->e1_inst); - if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n"); - // the code is very badly organized, it is not possible here to call freeDRBlist() - ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList,DRB_configList ); - - // Used to store teids: if monolithic, will simply be NULL - if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) { - // intentionally empty - } else { - int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd; - in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); - instance_t gtpInst = getCxt(0)->gtpInst; - // GTP tunnel for DL - fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rrc_ue_id, remote_port, my_addr); - } - // actually, we should receive the corresponding context setup response - // message at the RRC and always react to this one. So in the following, we - // just call the corresponding message handler - prepare_and_send_ue_context_modification_f1(ue_context_p, &resp); -} - static void cucp_cuup_bearer_context_mod_direct(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const req) { AssertFatal(assoc_id == -1, "illegal assoc_id %d, impossible for integrated CU\n", assoc_id); diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index 7604cabf14..2b933e3bae 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -28,15 +28,8 @@ #include "nr_rrc_proto.h" #include "nr_rrc_extern.h" #include "cucp_cuup_if.h" -#include "openair2/COMMON/e1ap_messages_types.h" -#include "openair3/SECU/secu_defs.h" -#include -#include "common/ran_context.h" - -extern RAN_CONTEXT_t RC; - -static void cucp_cuup_bearer_context_setup_e1ap(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const req) +static void cucp_cuup_bearer_context_setup_e1ap(sctp_assoc_t assoc_id, const e1ap_bearer_setup_req_t *req) { AssertFatal(assoc_id > 0, "illegal assoc_id %d\n", assoc_id); MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_REQ); diff --git a/openair2/RRC/NR/cucp_cuup_if.h b/openair2/RRC/NR/cucp_cuup_if.h index 3a3fb7948a..a298bdfe96 100644 --- a/openair2/RRC/NR/cucp_cuup_if.h +++ b/openair2/RRC/NR/cucp_cuup_if.h @@ -30,7 +30,7 @@ struct e1ap_bearer_setup_req_s; struct e1ap_bearer_setup_resp_s; -typedef void (*cucp_cuup_bearer_context_setup_func_t)(sctp_assoc_t assoc_id, struct e1ap_bearer_setup_req_s *const req); +typedef void (*cucp_cuup_bearer_context_setup_func_t)(sctp_assoc_t assoc_id, const struct e1ap_bearer_setup_req_s *req); struct gNB_RRC_INST_s; void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc); diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 96f5b0e28b..2bbbe5ab36 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -148,8 +148,6 @@ void ue_cxt_mod_send_e1ap(MessageDef *msg, void ue_cxt_mod_direct(MessageDef *msg, instance_t instance); -NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue); - void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp); void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddModList_t *const srb2add_list, const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kUPint); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 7a8916181b..d744cb11c2 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -93,7 +93,6 @@ #include #include #include -#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" #include "openair2/F1AP/f1ap_common.h" #include "openair2/F1AP/f1ap_ids.h" #include "openair2/SDAP/nr_sdap/nr_sdap_entity.h" @@ -2317,24 +2316,42 @@ static int get_dl_mimo_layers(const f1ap_served_cell_info_t *cell_info, const NR return(1); } -void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp) +void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { - /* Generate a UE context modification request message towards the DU to - * instruct the DU for SRB2 and DRB configuration and get the updates on - * master cell group config from the DU*/ - gNB_RRC_INST *rrc = RC.nrrrc[0]; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, resp->gNB_cu_cp_ue_id); + AssertFatal(ue_context_p != NULL, "did not find UE with CU UE ID %d\n", resp->gNB_cu_cp_ue_id); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + // currently: we don't have "infrastructure" to save the CU-UP UE ID, so we + // assume (and below check) that CU-UP UE ID == CU-CP UE ID + AssertFatal(resp->gNB_cu_cp_ue_id == resp->gNB_cu_up_ue_id, + "cannot handle CU-UP UE ID different from CU-CP UE ID (%d vs %d)\n", + resp->gNB_cu_cp_ue_id, + resp->gNB_cu_up_ue_id); + + // save the tunnel address for the PDU sessions + for (int i=0; i < resp->numPDUSessions; i++) { + pdu_session_setup_t *e1_pdu = &resp->pduSession[i]; + rrc_pdu_session_param_t *rrc_pdu = find_pduSession(UE, e1_pdu->id, false); + if (rrc_pdu == NULL) { + LOG_W(RRC, "E1: received setup for PDU session %ld, but has not been requested\n", e1_pdu->id); + continue; + } + rrc_pdu->param.gNB_teid_N3 = e1_pdu->teId; + memcpy(&rrc_pdu->param.gNB_addr_N3.buffer, &e1_pdu->tlAddress, sizeof(uint8_t) * 4); + rrc_pdu->param.gNB_addr_N3.length = sizeof(in_addr_t); + } + /* Instruction towards the DU for DRB configuration and tunnel creation */ - int nb_drb = e1ap_resp->pduSession[0].numDRBSetup; + int nb_drb = resp->pduSession[0].numDRBSetup; f1ap_drb_to_be_setup_t drbs[nb_drb]; for (int i = 0; i < nb_drb; i++) { - drbs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id; + drbs[i].drb_id = resp->pduSession[0].DRBnGRanList[i].id; drbs[i].rlc_mode = rrc->configuration.um_on_default_drb ? RLC_MODE_UM : RLC_MODE_AM; - drbs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress; + drbs[i].up_ul_tnl[0].tl_address = resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress; drbs[i].up_ul_tnl[0].port = rrc->eth_params_s.my_portd; - drbs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId; + drbs[i].up_ul_tnl[0].teid = resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId; drbs[i].up_ul_tnl_length = 1; } @@ -2348,6 +2365,7 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex srbs[0].lcid = 2; } + /* Gather UE capability if present */ cu_to_du_rrc_information_t cu2du = {0}; cu_to_du_rrc_information_t *cu2du_p = NULL; if (UE->ue_cap_buffer.len > 0 && UE->ue_cap_buffer.buf != NULL) { @@ -2374,38 +2392,6 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); } -void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { - // Find the UE context from UE ID and send ITTI message to F1AP to send UE context modification message to DU - - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], resp->gNB_cu_cp_ue_id); - AssertFatal(ue_context_p != NULL, "did not find UE with CU UE ID %d\n", resp->gNB_cu_cp_ue_id); - protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, resp->gNB_cu_cp_ue_id, 0, 0, 0); - - // currently: we don't have "infrastructure" to save the CU-UP UE ID, so we - // assume (and below check) that CU-UP UE ID == CU-CP UE ID - AssertFatal(resp->gNB_cu_cp_ue_id == resp->gNB_cu_up_ue_id, - "cannot handle CU-UP UE ID different from CU-CP UE ID (%d vs %d)\n", - resp->gNB_cu_cp_ue_id, - resp->gNB_cu_up_ue_id); - - gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0}; - create_tunnel_resp.num_tunnels = resp->numPDUSessions; - for (int i=0; i < resp->numPDUSessions; i++) { - create_tunnel_resp.pdusession_id[i] = resp->pduSession[i].id; - create_tunnel_resp.gnb_NGu_teid[i] = resp->pduSession[i].teId; - memcpy(create_tunnel_resp.gnb_addr.buffer, - &resp->pduSession[i].tlAddress, - sizeof(in_addr_t)); - create_tunnel_resp.gnb_addr.length = sizeof(in_addr_t); // IPv4 byte length - } - - nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt, &create_tunnel_resp, 0); - - // TODO: SV: combine e1ap_bearer_setup_req_t and e1ap_bearer_setup_resp_t and minimize assignments - prepare_and_send_ue_context_modification_f1(ue_context_p, resp); -} - static void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) { AssertFatal(rrc->du != NULL, "no DU connected, cannot received F1 lost connection\n"); @@ -2683,6 +2669,7 @@ void *rrc_gnb_task(void *args_p) { case E1AP_BEARER_CONTEXT_SETUP_RESP: rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance); + break; case NGAP_PAGING_IND: rrc_gNB_process_PAGING_IND(msg_p, instance); diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.c b/openair2/RRC/NR/rrc_gNB_GTPV1U.c index 3ef3e62d51..6c8627aa09 100644 --- a/openair2/RRC/NR/rrc_gNB_GTPV1U.c +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.c @@ -75,35 +75,3 @@ int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_ return 0; } - -int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, int offset) -{ - if (!create_tunnel_resp_pP) { - LOG_E(NR_RRC, "create_tunnel_resp_pP error\n"); - return -1; - } - - LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels); - /* we look up by CU UE ID! Do NOT change back to RNTI! */ - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); - if (!ue_context_p) { - LOG_E(NR_RRC, "UE table error\n"); - return -1; - } - - for (int i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) { - ue_context_p->ue_context.pduSession[i + offset].param.gNB_teid_N3 = create_tunnel_resp_pP->gnb_NGu_teid[i]; - ue_context_p->ue_context.pduSession[i + offset].param.gNB_addr_N3 = create_tunnel_resp_pP->gnb_addr; - AssertFatal(ue_context_p->ue_context.pduSession[i + offset].param.pdusession_id == create_tunnel_resp_pP->pdusession_id[i], ""); - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT - " nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u) bearer UE context index %u, id %u, gtp addr len %d \n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - create_tunnel_resp_pP->gnb_NGu_teid[i], - i, - create_tunnel_resp_pP->pdusession_id[i], - create_tunnel_resp_pP->gnb_addr.length); - } - - return 0; -} diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.h b/openair2/RRC/NR/rrc_gNB_GTPV1U.h index d538127d76..d7d1013db8 100644 --- a/openair2/RRC/NR/rrc_gNB_GTPV1U.h +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.h @@ -38,6 +38,4 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( uint8_t *inde_list ); -int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, int offset_in_rrc); - #endif diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 0e7f01fd8e..40d96fe527 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -378,6 +378,9 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions; if (nb_pdusessions_tosetup) { AssertFatal(false, "PDU sessions in Initial context setup request not handled by E1 yet\n"); + /* this code should pass by E1: commenting here for future reference, but + * already handled in E1 for the "normal case" of a separate request for + * PDU session setup. gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0}; for (int i = 0; i < nb_pdusessions_tosetup; i++) { UE->nb_of_pdusessions++; @@ -404,6 +407,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t } nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt, &create_tunnel_resp, 0); + */ } /* NAS PDU */ From ec60fd8157a9f8d0c0b03602d5ab49d2df229b9d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Oct 2023 21:51:56 +0200 Subject: [PATCH 31/40] E1 bearer modification: harmonize code --- openair1/SIMULATION/NR_PHY/dlsim.c | 1 + openair1/SIMULATION/NR_PHY/ulsim.c | 1 + openair2/COMMON/e1ap_messages_def.h | 2 +- openair2/COMMON/e1ap_messages_types.h | 19 +++++++++ openair2/E1AP/e1ap.c | 11 ++++- openair2/E1AP/e1ap_api.c | 9 ---- openair2/E1AP/e1ap_api.h | 1 - openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c | 38 +++++++++++++++++ openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h | 1 + openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c | 9 ++++ openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c | 9 ++++ openair2/LAYER2/nr_pdcp/cuup_cucp_if.h | 3 ++ openair2/RRC/NR/cucp_cuup_direct.c | 46 ++------------------- openair2/RRC/NR/cucp_cuup_e1ap.c | 5 +-- openair2/RRC/NR/cucp_cuup_if.h | 8 +--- openair2/RRC/NR/rrc_gNB.c | 23 +++++++++++ 16 files changed, 121 insertions(+), 65 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 8a5ede9159..163107bf84 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -109,6 +109,7 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB } void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } +void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); } int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 7307575bdb..7a7058f2f1 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -105,6 +105,7 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB } void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } +void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); } int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h index fdfa071a7f..2759c655ef 100644 --- a/openair2/COMMON/e1ap_messages_def.h +++ b/openair2/COMMON/e1ap_messages_def.h @@ -33,4 +33,4 @@ MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_s MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_RESP , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_resp_t , e1ap_bearer_setup_resp) MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_mod_req) - +MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, e1ap_bearer_modif_resp_t, e1ap_bearer_modif_resp) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 67f5a883e2..124a174dab 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -47,6 +47,7 @@ #define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req #define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp #define E1AP_BEARER_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req +#define E1AP_BEARER_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_modif_resp typedef f1ap_net_ip_address_t e1ap_net_ip_address_t; @@ -204,6 +205,10 @@ typedef struct DRB_nGRAN_setup_s { qos_flow_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS]; } DRB_nGRAN_setup_t; +typedef struct DRB_nGRAN_modified_s { + long id; +} DRB_nGRAN_modified_t; + typedef struct DRB_nGRAN_failed_s { long id; long cause_type; @@ -220,6 +225,13 @@ typedef struct pdu_session_setup_s { DRB_nGRAN_failed_t DRBnGRanFailedList[E1AP_MAX_NUM_NGRAN_DRB]; } pdu_session_setup_t; +typedef struct pdu_session_modif_s { + long id; + // setup as part of PDU session modification not supported yet + int numDRBModified; + DRB_nGRAN_modified_t DRBnGRanModList[E1AP_MAX_NUM_NGRAN_DRB]; +} pdu_session_modif_t; + typedef struct e1ap_bearer_setup_resp_s { uint32_t gNB_cu_cp_ue_id; uint32_t gNB_cu_up_ue_id; @@ -227,4 +239,11 @@ typedef struct e1ap_bearer_setup_resp_s { pdu_session_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS]; } e1ap_bearer_setup_resp_t; +typedef struct e1ap_bearer_modif_resp_s { + uint32_t gNB_cu_cp_ue_id; + uint32_t gNB_cu_up_ue_id; + int numPDUSessionsMod; + pdu_session_modif_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS]; +} e1ap_bearer_modif_resp_t; + #endif /* E1AP_MESSAGES_TYPES_H */ diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 45f3c4cd17..3a74fad835 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1283,7 +1283,8 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, e e1ap_bearer_setup_req_t bearerCxt = {0}; extract_BEARER_CONTEXT_MODIFICATION_REQUEST(pdu, &bearerCxt); - CUUP_process_bearer_context_mod_req(e1_inst->instance, &bearerCxt); + + e1_bearer_context_modif(&bearerCxt); return 0; } @@ -1778,6 +1779,14 @@ void *E1AP_CUUP_task(void *arg) { e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst->cuup.assoc_id, resp); } break; + case E1AP_BEARER_CONTEXT_MODIFICATION_RESP: { + //const e1ap_bearer_modif_resp_t *resp = &E1AP_BEARER_CONTEXT_MODIFICATION_RESP(msg); + const e1ap_upcp_inst_t *inst = getCxtE1(myInstance); + AssertFatal(inst != NULL, "no E1 instance found for instance %ld\n", myInstance); + LOG_W(E1AP, "E1AP_BEARER_CONTEXT_MODIFICATION_RESP lost!\n"); + //e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE + } break; + default: LOG_E(E1AP, "Unknown message received in TASK_CUUP_E1\n"); break; diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index 816867a6ab..dfb6747600 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -34,15 +34,6 @@ #include "e1ap_common.h" #include "e1ap.h" -void CUUP_process_bearer_context_mod_req(instance_t instance, e1ap_bearer_setup_req_t *const req) -{ - e1ap_upcp_inst_t *inst = getCxtE1(instance); - AssertFatal(inst, ""); - // assume we receive modification of F1-U but it is wrong, we can also get modification of N3 when HO will occur - CU_update_UP_DL_tunnel(req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id); - // TODO: send bearer cxt mod response -} - void CUUP_process_bearer_release_command(instance_t instance, e1ap_bearer_release_cmd_t *const cmd) { e1ap_upcp_inst_t *inst = getCxtE1(instance); diff --git a/openair2/E1AP/e1ap_api.h b/openair2/E1AP/e1ap_api.h index a6cbe228d1..e2d0c892d1 100644 --- a/openair2/E1AP/e1ap_api.h +++ b/openair2/E1AP/e1ap_api.h @@ -28,7 +28,6 @@ #include "openair2/COMMON/e1ap_messages_types.h" #include "openair2/E1AP/e1ap_common.h" void cuup_init_n3(instance_t instance); -void CUUP_process_bearer_context_mod_req(instance_t, e1ap_bearer_setup_req_t *const req); void CUUP_process_bearer_release_command(instance_t, e1ap_bearer_release_cmd_t *const cmd); #endif diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index 29ccb6bf32..aaf5323b03 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -219,3 +219,41 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) get_e1_if()->bearer_setup_response(&resp); } + +void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) +{ + AssertFatal(req->numPDUSessionsMod > 0, "need at least one PDU session to modify\n"); + + e1ap_bearer_modif_resp_t modif = { + .gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id, + .gNB_cu_up_ue_id = req->gNB_cu_up_ue_id, + .numPDUSessionsMod = req->numPDUSessionsMod, + }; + + instance_t f1inst = get_f1_gtp_instance(); + + for (int i=0; i < req->numPDUSessionsMod; i++) { + LOG_I(E1AP, + "UE %d: updating PDU session ID %ld (%ld bearers)\n", + req->gNB_cu_up_ue_id, + req->pduSessionMod[i].sessionId, + req->pduSessionMod[i].numDRB2Modify); + modif.pduSessionMod[i].id = req->pduSessionMod[i].sessionId; + modif.pduSessionMod[i].numDRBModified = req->pduSessionMod[i].numDRB2Modify; + for (int j=0; j < req->pduSessionMod[i].numDRB2Modify; j++) { + const DRB_nGRAN_to_setup_t *to_modif = &req->pduSessionMod[i].DRBnGRanModList[j]; + DRB_nGRAN_modified_t *modified = &modif.pduSessionMod[i].DRBnGRanModList[j]; + modified->id = to_modif->id; + + if (f1inst < 0) // no F1-U? + continue; // nothing to do + + in_addr_t addr = {0}; + memcpy(&addr, &to_modif->DlUpParamList[0].tlAddress, sizeof(in_addr_t)); + + GtpuUpdateTunnelOutgoingAddressAndTeid(f1inst, req->gNB_cu_cp_ue_id, to_modif->id, addr, to_modif->DlUpParamList[0].teId); + } + } + + get_e1_if()->bearer_modif_response(&modif); +} diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h index ec220876f5..7c9c6244f3 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h @@ -28,5 +28,6 @@ void nr_pdcp_e1_if_init(bool uses_e1); struct e1ap_bearer_setup_req_s; void e1_bearer_context_setup(const struct e1ap_bearer_setup_req_s *req); +void e1_bearer_context_modif(const struct e1ap_bearer_setup_req_s *req); #endif /* CUCP_CUUP_HANDLER_H */ diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c b/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c index dd87e56b5d..52918b4d64 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c @@ -31,7 +31,16 @@ static void bearer_setup_response_direct(const e1ap_bearer_setup_resp_t *resp) itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } +static void bearer_modif_response_direct(const e1ap_bearer_modif_resp_t *resp) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, E1AP_BEARER_CONTEXT_MODIFICATION_RESP); + e1ap_bearer_modif_resp_t *msg_resp = &E1AP_BEARER_CONTEXT_MODIFICATION_RESP(msg); + *msg_resp = *resp; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); +} + void cuup_cucp_init_direct(e1_if_t *iface) { iface->bearer_setup_response = bearer_setup_response_direct; + iface->bearer_modif_response = bearer_modif_response_direct; } diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c b/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c index 8db854786b..91ed1b1ec8 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c @@ -31,7 +31,16 @@ static void bearer_setup_response_e1ap(const e1ap_bearer_setup_resp_t *resp) itti_send_msg_to_task (TASK_CUUP_E1, 0, msg_p); } +static void bearer_modif_response_e1ap(const e1ap_bearer_modif_resp_t *resp) +{ + MessageDef *msg_p = itti_alloc_new_message(TASK_CUUP_E1, 0, E1AP_BEARER_CONTEXT_MODIFICATION_RESP); + e1ap_bearer_modif_resp_t *modif_resp = &E1AP_BEARER_CONTEXT_MODIFICATION_RESP(msg_p); + *modif_resp = *resp; + itti_send_msg_to_task (TASK_CUUP_E1, 0, msg_p); +} + void cuup_cucp_init_e1ap(e1_if_t *iface) { iface->bearer_setup_response = bearer_setup_response_e1ap; + iface->bearer_modif_response = bearer_modif_response_e1ap; } diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h index 5ec064ba03..3a576b7f7f 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h @@ -25,10 +25,13 @@ #include struct e1ap_bearer_setup_resp_s; +struct e1ap_bearer_modif_resp_s; typedef void (*e1_bearer_setup_response_func_t)(const struct e1ap_bearer_setup_resp_s *resp); +typedef void (*e1_bearer_modif_response_func_t)(const struct e1ap_bearer_modif_resp_s *resp); typedef struct e1_if_t { e1_bearer_setup_response_func_t bearer_setup_response; + e1_bearer_modif_response_func_t bearer_modif_response; } e1_if_t; e1_if_t *get_e1_if(void); diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 8806718915..3c45598f15 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -19,28 +19,11 @@ * contact@openairinterface.org */ -#include - #include "cucp_cuup_if.h" -#include "platform_types.h" + #include "nr_rrc_defs.h" - -#include "softmodem-common.h" -#include "nr_rrc_proto.h" -#include "nr_rrc_extern.h" #include "openair2/COMMON/e1ap_messages_types.h" -#include "openair3/SECU/key_nas_deriver.h" - -#include "nr_pdcp/nr_pdcp_entity.h" #include "openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h" -#include -#include "openair3/ocp-gtpu/gtp_itf.h" -#include "rrc_gNB_GTPV1U.h" -#include "common/ran_context.h" -#include "openair2/F1AP/f1ap_common.h" -#include "openair2/E1AP/e1ap_common.h" - -extern RAN_CONTEXT_t RC; static void cucp_cuup_bearer_context_setup_direct(sctp_assoc_t assoc_id, const e1ap_bearer_setup_req_t *req) { @@ -48,34 +31,13 @@ static void cucp_cuup_bearer_context_setup_direct(sctp_assoc_t assoc_id, const e e1_bearer_context_setup(req); } -void CU_update_UP_DL_tunnel(e1ap_bearer_setup_req_t *const req, instance_t instance, ue_id_t ue_id) { - for (int i=0; i < req->numPDUSessionsMod; i++) { - for (int j=0; j < req->pduSessionMod[i].numDRB2Modify; j++) { - DRB_nGRAN_to_setup_t *drb_p = req->pduSessionMod[i].DRBnGRanModList + j; - - in_addr_t addr = {0}; - memcpy(&addr, &drb_p->DlUpParamList[0].tlAddress, sizeof(in_addr_t)); - - GtpuUpdateTunnelOutgoingAddressAndTeid(instance, - (ue_id & 0xFFFF), - (ebi_t)drb_p->id, - addr, - drb_p->DlUpParamList[0].teId); - } - } -} - -static void cucp_cuup_bearer_context_mod_direct(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const req) +static void cucp_cuup_bearer_context_modif_direct(sctp_assoc_t assoc_id, const e1ap_bearer_setup_req_t *req) { AssertFatal(assoc_id == -1, "illegal assoc_id %d, impossible for integrated CU\n", assoc_id); - // only update GTP tunnels if it is really a CU - if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) - return; - instance_t gtpInst = getCxt(0)->gtpInst; - CU_update_UP_DL_tunnel(req, gtpInst, req->gNB_cu_cp_ue_id); + e1_bearer_context_modif(req); } void cucp_cuup_message_transfer_direct_init(gNB_RRC_INST *rrc) { rrc->cucp_cuup.bearer_context_setup = cucp_cuup_bearer_context_setup_direct; - rrc->cucp_cuup.bearer_context_mod = cucp_cuup_bearer_context_mod_direct; + rrc->cucp_cuup.bearer_context_mod = cucp_cuup_bearer_context_modif_direct; } diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index 2b933e3bae..1678dd8313 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -20,9 +20,6 @@ */ #include "cucp_cuup_if.h" -#include - -#include "platform_types.h" #include "nr_rrc_defs.h" #include "nr_rrc_proto.h" @@ -40,7 +37,7 @@ static void cucp_cuup_bearer_context_setup_e1ap(sctp_assoc_t assoc_id, const e1a itti_send_msg_to_task (TASK_CUCP_E1, 0, msg_p); } -static void cucp_cuup_bearer_context_mod_e1ap(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const req) +static void cucp_cuup_bearer_context_mod_e1ap(sctp_assoc_t assoc_id, const e1ap_bearer_setup_req_t *req) { AssertFatal(assoc_id > 0, "illegal assoc_id %d\n", assoc_id); MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_MODIFICATION_REQ); diff --git a/openair2/RRC/NR/cucp_cuup_if.h b/openair2/RRC/NR/cucp_cuup_if.h index a298bdfe96..125ae93522 100644 --- a/openair2/RRC/NR/cucp_cuup_if.h +++ b/openair2/RRC/NR/cucp_cuup_if.h @@ -35,11 +35,5 @@ typedef void (*cucp_cuup_bearer_context_setup_func_t)(sctp_assoc_t assoc_id, con struct gNB_RRC_INST_s; void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc); void cucp_cuup_message_transfer_e1ap_init(struct gNB_RRC_INST_s *rrc); -void fill_e1ap_bearer_setup_resp(struct e1ap_bearer_setup_resp_s *resp, - struct e1ap_bearer_setup_req_s *const req, - instance_t gtpInst, - ue_id_t ue_id, - int remote_port, - in_addr_t my_addr); -void CU_update_UP_DL_tunnel(struct e1ap_bearer_setup_req_s *const req, instance_t instance, ue_id_t ue_id); + #endif diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d744cb11c2..1534dde669 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2056,10 +2056,13 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i if (resp->drbs_to_be_setup_length > 0) { e1ap_bearer_setup_req_t req = {0}; + // TODO: bug: we receive the DRBs, but we don't associate to a PDU session + // -> we are not sure which PDU session this is, and fill "all" req.numPDUSessionsMod = UE->nb_of_pdusessions; req.gNB_cu_cp_ue_id = UE->rrc_ue_id; req.gNB_cu_up_ue_id = UE->rrc_ue_id; for (int i = 0; i < req.numPDUSessionsMod; i++) { + req.pduSessionMod[i].sessionId = UE->pduSession[i].param.pdusession_id; req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; for (int j = 0; j < resp->drbs_to_be_setup_length; j++) { f1ap_drb_to_be_setup_t *drb_f1 = resp->drbs_to_be_setup + j; @@ -2392,6 +2395,22 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); } +void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t *resp) +{ + gNB_RRC_INST *rrc = RC.nrrrc[0]; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, resp->gNB_cu_cp_ue_id); + if (ue_context_p == NULL) { + LOG_E(RRC, "no UE with CU-CP UE ID %d found\n", resp->gNB_cu_cp_ue_id); + return; + } + + // there is not really anything to do here as of now + for (int i = 0; i < resp->numPDUSessionsMod; ++i) { + const pdu_session_modif_t *pdu = &resp->pduSessionMod[i]; + LOG_I(RRC, "UE %d: PDU session ID %ld modified %d bearers\n", resp->gNB_cu_cp_ue_id, pdu->id, pdu->numDRBModified); + } +} + static void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) { AssertFatal(rrc->du != NULL, "no DU connected, cannot received F1 lost connection\n"); @@ -2671,6 +2690,10 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance); break; + case E1AP_BEARER_CONTEXT_MODIFICATION_RESP: + rrc_gNB_process_e1_bearer_context_modif_resp(&E1AP_BEARER_CONTEXT_MODIFICATION_RESP(msg_p)); + break; + case NGAP_PAGING_IND: rrc_gNB_process_PAGING_IND(msg_p, instance); break; From fb5b125110494ca9d900919536e06710f151b990 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 26 Oct 2023 14:57:10 +0200 Subject: [PATCH 32/40] Implement Bearer Context Modification Response in E1 --- openair2/E1AP/e1ap.c | 160 +++++++++++++++++++++++++++++++++--- openair2/E1AP/e1ap.h | 2 + openair2/E1AP/e1ap_asnc.h | 4 + openair2/E1AP/e1ap_common.c | 3 + 4 files changed, 156 insertions(+), 13 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 3a74fad835..a6e6886284 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -50,7 +50,9 @@ const e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3 {e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST, e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE, e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE}, /* bearerContextSetup */ - {e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST, 0, 0}, /* bearerContextModification */ + {e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST, + e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE, + 0}, /* bearerContextModification */ {0, 0, 0}, /* bearerContextModificationRequired */ {e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND, e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE, 0}, /* bearerContextRelease */ {0, 0, 0}, /* bearerContextReleaseRequired */ @@ -1185,9 +1187,69 @@ static void e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } -int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); - return -1; +static void fill_BEARER_CONTEXT_MODIFICATION_RESPONSE(const e1ap_bearer_modif_resp_t *resp, E1AP_E1AP_PDU_t *pdu) +{ + pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome; + asn1cCalloc(pdu->choice.successfulOutcome, msg); + msg->procedureCode = E1AP_ProcedureCode_id_bearerContextModification; + msg->criticality = E1AP_Criticality_reject; + msg->value.present = E1AP_SuccessfulOutcome__value_PR_BearerContextModificationResponse; + E1AP_BearerContextModificationResponse_t *out = &pdu->choice.successfulOutcome->value.choice.BearerContextModificationResponse; + + /* mandatory */ + /* c1. gNB-CU-CP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationResponseIEs_t, ieCuCpId); + ieCuCpId->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID; + ieCuCpId->criticality = E1AP_Criticality_reject; + ieCuCpId->value.present = E1AP_BearerContextModificationResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID; + ieCuCpId->value.choice.GNB_CU_CP_UE_E1AP_ID = resp->gNB_cu_cp_ue_id; + + /* mandatory */ + /* c2. gNB-CU-UP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationResponseIEs_t, ieCuUpId); + ieCuUpId->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; + ieCuUpId->criticality = E1AP_Criticality_reject; + ieCuUpId->value.present = E1AP_BearerContextModificationResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; + ieCuUpId->value.choice.GNB_CU_UP_UE_E1AP_ID = resp->gNB_cu_up_ue_id; + + /* optional */ + /* PDU sessions that have been modified */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationResponseIEs_t, ieSys); + ieSys->id = E1AP_ProtocolIE_ID_id_System_BearerContextModificationResponse; + ieSys->criticality = E1AP_Criticality_ignore; + ieSys->value.present = E1AP_BearerContextModificationResponseIEs__value_PR_System_BearerContextModificationResponse; + + E1AP_System_BearerContextModificationResponse_t *sys = &ieSys->value.choice.System_BearerContextModificationResponse; + E1AP_ProtocolIE_Container_4932P29_t *piel = calloc(1, sizeof(*piel)); + sys->present = E1AP_System_BearerContextModificationResponse_PR_nG_RAN_BearerContextModificationResponse; + sys->choice.nG_RAN_BearerContextModificationResponse = (struct E1AP_ProtocolIE_Container *)piel; + asn1cSequenceAdd(piel->list, E1AP_NG_RAN_BearerContextModificationResponse_t, ngran_bcmr); + ngran_bcmr->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Modified_List; + ngran_bcmr->criticality = E1AP_Criticality_reject; + ngran_bcmr->value.present = E1AP_NG_RAN_BearerContextModificationResponse__value_PR_PDU_Session_Resource_Modified_List; + E1AP_PDU_Session_Resource_Modified_List_t *pdu_mod_l = &ngran_bcmr->value.choice.PDU_Session_Resource_Modified_List; + for (int i = 0; i < resp->numPDUSessionsMod; ++i) { + const pdu_session_modif_t *pdu = &resp->pduSessionMod[i]; + asn1cSequenceAdd(pdu_mod_l->list, E1AP_PDU_Session_Resource_Modified_Item_t, iePdu); + iePdu->pDU_Session_ID = pdu->id; + if (pdu->numDRBModified > 0) { + iePdu->dRB_Modified_List_NG_RAN = calloc(1, sizeof(*iePdu->dRB_Modified_List_NG_RAN)); + AssertFatal(iePdu->dRB_Modified_List_NG_RAN != NULL, "out of memory\n"); + E1AP_DRB_Modified_List_NG_RAN_t *drb_mod_l = iePdu->dRB_Modified_List_NG_RAN; + for (int j = 0; j < pdu->numDRBModified; ++j) { + const DRB_nGRAN_modified_t *drb = &pdu->DRBnGRanModList[j]; + asn1cSequenceAdd(drb_mod_l->list, E1AP_DRB_Modified_Item_NG_RAN_t, drb_mod); + drb_mod->dRB_ID = drb->id; + } + } + } +} + +static int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, const e1ap_bearer_modif_resp_t *resp) +{ + E1AP_E1AP_PDU_t pdu = {0}; + fill_BEARER_CONTEXT_MODIFICATION_RESPONSE(resp, &pdu); + return e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__); } int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { @@ -1288,13 +1350,86 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, e return 0; } -int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, - sctp_assoc_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) +static void extract_BEARER_CONTEXT_MODIFICATION_RESPONSE(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_modif_resp_t *resp) { - AssertFatal(false,"Not implemented yet\n"); - return -1; + memset(resp, 0, sizeof(*resp)); + const E1AP_BearerContextModificationResponse_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextModificationResponse; + + for (int i = 0; i < in->protocolIEs.list.count; ++i) { + E1AP_BearerContextModificationResponseIEs_t *ie = in->protocolIEs.list.array[i]; + + switch (ie->id) { + case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextModificationResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID); + resp->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID: + DevAssert(ie->criticality == E1AP_Criticality_reject); + DevAssert(ie->value.present == E1AP_BearerContextModificationResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID); + resp->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_System_BearerContextModificationResponse: + DevAssert(ie->criticality == E1AP_Criticality_ignore); + DevAssert(ie->value.present == E1AP_BearerContextModificationResponseIEs__value_PR_System_BearerContextModificationResponse); + DevAssert(ie->value.choice.System_BearerContextModificationResponse.present + == E1AP_System_BearerContextModificationResponse_PR_nG_RAN_BearerContextModificationResponse); + E1AP_ProtocolIE_Container_4932P29_t *msgNGRAN_list = + (E1AP_ProtocolIE_Container_4932P29_t *) + ie->value.choice.System_BearerContextModificationResponse.choice.nG_RAN_BearerContextModificationResponse; + DevAssert(msgNGRAN_list->list.count == 1); + E1AP_NG_RAN_BearerContextModificationResponse_t *msgNGRAN = msgNGRAN_list->list.array[0]; + DevAssert(msgNGRAN->id == E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Modified_List); + DevAssert(msgNGRAN->criticality == E1AP_Criticality_reject); + DevAssert(msgNGRAN->value.present == E1AP_NG_RAN_BearerContextModificationResponse__value_PR_PDU_Session_Resource_Modified_List); + E1AP_PDU_Session_Resource_Modified_List_t *pduModifiedList = &msgNGRAN->value.choice.PDU_Session_Resource_Modified_List; + resp->numPDUSessionsMod = pduModifiedList->list.count; + + for (int i=0; i < pduModifiedList->list.count; i++) { + pdu_session_modif_t *pduModified = &resp->pduSessionMod[i]; + E1AP_PDU_Session_Resource_Modified_Item_t *mod_it = pduModifiedList->list.array[i]; + pduModified->id = mod_it->pDU_Session_ID; + + AssertFatal(mod_it->nG_DL_UP_TNL_Information == NULL, "not implemented\n"); + AssertFatal(mod_it->securityResult == NULL, "not implemented\n"); + AssertFatal(mod_it->pDU_Session_Data_Forwarding_Information_Response == NULL, "not implemented\n"); + AssertFatal(mod_it->dRB_Setup_List_NG_RAN == NULL, "not implemented\n"); + AssertFatal(mod_it->dRB_Failed_List_NG_RAN == NULL, "not implemented\n"); + AssertFatal(mod_it->dRB_Failed_To_Modify_List_NG_RAN == NULL, "not implemented\n"); + + pduModified->numDRBModified = mod_it->dRB_Modified_List_NG_RAN->list.count; + for (int j=0; j < mod_it->dRB_Modified_List_NG_RAN->list.count; j++) { + DRB_nGRAN_modified_t *drbModified = &pduModified->DRBnGRanModList[j]; + E1AP_DRB_Modified_Item_NG_RAN_t *drb = mod_it->dRB_Modified_List_NG_RAN->list.array[j]; + + drbModified->id = drb->dRB_ID; + + AssertFatal(drb->uL_UP_Transport_Parameters == NULL, "not implemented\n"); + AssertFatal(drb->pDCP_SN_Status_Information == NULL, "not implemented\n"); + AssertFatal(drb->flow_Setup_List == NULL, "not implemented\n"); + AssertFatal(drb->flow_Failed_List == NULL, "not implemented\n"); + } + } + break; + } + } +} + +int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome); + DevAssert(pdu->choice.successfulOutcome->procedureCode == E1AP_ProcedureCode_id_bearerContextModification); + DevAssert(pdu->choice.successfulOutcome->criticality == E1AP_Criticality_reject); + DevAssert(pdu->choice.successfulOutcome->value.present == E1AP_SuccessfulOutcome__value_PR_BearerContextModificationResponse); + + MessageDef *msg = itti_alloc_new_message(TASK_CUUP_E1, 0, E1AP_BEARER_CONTEXT_MODIFICATION_RESP); + e1ap_bearer_modif_resp_t *modif = &E1AP_BEARER_CONTEXT_MODIFICATION_RESP(msg); + extract_BEARER_CONTEXT_MODIFICATION_RESPONSE(pdu, modif); + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); + return 0; } int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance, @@ -1780,11 +1915,10 @@ void *E1AP_CUUP_task(void *arg) { } break; case E1AP_BEARER_CONTEXT_MODIFICATION_RESP: { - //const e1ap_bearer_modif_resp_t *resp = &E1AP_BEARER_CONTEXT_MODIFICATION_RESP(msg); + const e1ap_bearer_modif_resp_t *resp = &E1AP_BEARER_CONTEXT_MODIFICATION_RESP(msg); const e1ap_upcp_inst_t *inst = getCxtE1(myInstance); AssertFatal(inst != NULL, "no E1 instance found for instance %ld\n", myInstance); - LOG_W(E1AP, "E1AP_BEARER_CONTEXT_MODIFICATION_RESP lost!\n"); - //e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE + e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(inst->cuup.assoc_id, resp); } break; default: diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h index c9d6345318..fd82ffd147 100644 --- a/openair2/E1AP/e1ap.h +++ b/openair2/E1AP/e1ap.h @@ -42,6 +42,8 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upc int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); +int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu); + void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1ap_bearer_setup_resp_t *resp); int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); diff --git a/openair2/E1AP/e1ap_asnc.h b/openair2/E1AP/e1ap_asnc.h index 3916f4aeb7..ed5d1817a8 100644 --- a/openair2/E1AP/e1ap_asnc.h +++ b/openair2/E1AP/e1ap_asnc.h @@ -47,10 +47,14 @@ #include #include #include +#include +#include #include #include #include #include +#include +#include #include #include #include diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 154468fb66..0547680eea 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -134,6 +134,9 @@ int e1ap_decode_successful_outcome(E1AP_E1AP_PDU_t *pdu) { case E1AP_ProcedureCode_id_bearerContextSetup: break; + case E1AP_ProcedureCode_id_bearerContextModification: + break; + default: LOG_E(E1AP, "Unsupported procedure code (%d) for successful message\n", (int)pdu->choice.successfulOutcome->procedureCode); From 2e252dd377acafe1eac50a1ef51414465dc2c21c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 8 Oct 2023 16:26:54 +0200 Subject: [PATCH 33/40] Implement E1 bearer release --- openair1/SIMULATION/NR_PHY/dlsim.c | 1 + openair1/SIMULATION/NR_PHY/ulsim.c | 1 + openair2/COMMON/e1ap_messages_def.h | 3 ++ openair2/COMMON/e1ap_messages_types.h | 7 ++++ openair2/E1AP/CMakeLists.txt | 2 +- openair2/E1AP/e1ap.c | 32 ++++++++++----- openair2/E1AP/e1ap.h | 2 +- openair2/E1AP/e1ap_api.c | 44 --------------------- openair2/E1AP/e1ap_api.h | 4 +- openair2/E1AP/e1ap_common.c | 6 +++ openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c | 21 ++++++++++ openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h | 2 + openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c | 9 +++++ openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c | 9 +++++ openair2/LAYER2/nr_pdcp/cuup_cucp_if.h | 3 ++ openair2/RRC/NR/cucp_cuup_direct.c | 7 ++++ openair2/RRC/NR/cucp_cuup_e1ap.c | 11 ++++++ openair2/RRC/NR/cucp_cuup_if.h | 2 + openair2/RRC/NR/nr_rrc_defs.h | 1 + openair2/RRC/NR/rrc_gNB.c | 22 ++++++++++- 20 files changed, 129 insertions(+), 60 deletions(-) delete mode 100644 openair2/E1AP/e1ap_api.c diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 163107bf84..21a237785d 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -110,6 +110,7 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); } +void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) { abort(); } int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 7a7058f2f1..668c1cb633 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -106,6 +106,7 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); } +void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) { abort(); } int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h index 2759c655ef..ea24ac9e18 100644 --- a/openair2/COMMON/e1ap_messages_def.h +++ b/openair2/COMMON/e1ap_messages_def.h @@ -34,3 +34,6 @@ MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_RESP , MESSAGE_PRIORITY_MED , e1ap_bearer_ MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_mod_req) MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, e1ap_bearer_modif_resp_t, e1ap_bearer_modif_resp) + +MESSAGE_DEF(E1AP_BEARER_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, e1ap_bearer_release_cmd_t, e1ap_bearer_release_cmd) +MESSAGE_DEF(E1AP_BEARER_CONTEXT_RELEASE_CPLT, MESSAGE_PRIORITY_MED, e1ap_bearer_release_cplt_t, e1ap_bearer_release_cplt) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 124a174dab..f98058b85c 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -48,6 +48,8 @@ #define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp #define E1AP_BEARER_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req #define E1AP_BEARER_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_modif_resp +#define E1AP_BEARER_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_release_cmd +#define E1AP_BEARER_CONTEXT_RELEASE_CPLT(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_release_cplt typedef f1ap_net_ip_address_t e1ap_net_ip_address_t; @@ -193,6 +195,11 @@ typedef struct e1ap_bearer_release_cmd_s { long cause; } e1ap_bearer_release_cmd_t; +typedef struct e1ap_bearer_release_cplt_s { + uint32_t gNB_cu_cp_ue_id; + uint32_t gNB_cu_up_ue_id; +} e1ap_bearer_release_cplt_t; + typedef struct qos_flow_setup_s { long id; } qos_flow_setup_t; diff --git a/openair2/E1AP/CMakeLists.txt b/openair2/E1AP/CMakeLists.txt index 0384c2860b..c7657eed5a 100644 --- a/openair2/E1AP/CMakeLists.txt +++ b/openair2/E1AP/CMakeLists.txt @@ -1,6 +1,6 @@ add_subdirectory(MESSAGES) -add_library(e1ap e1ap.c e1ap_common.c e1ap_api.c) +add_library(e1ap e1ap.c e1ap_common.c) target_link_libraries(e1ap PUBLIC asn1_e1ap f1ap PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap UTIL e1_if) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index a6e6886284..d6116309db 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1505,7 +1505,7 @@ int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_bea return e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } -static int fill_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_bearer_release_cmd_t *const cmd, E1AP_E1AP_PDU_t *pdu) +static int fill_BEARER_CONTEXT_RELEASE_COMPLETE(const e1ap_bearer_release_cplt_t *cplt, E1AP_E1AP_PDU_t *pdu) { pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome; asn1cCalloc(pdu->choice.successfulOutcome, msg); @@ -1519,22 +1519,22 @@ static int fill_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_bearer_release_cmd_t *const ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID; ieC1->criticality = E1AP_Criticality_reject; ieC1->value.present = E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_CP_UE_E1AP_ID; - ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id; + ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = cplt->gNB_cu_cp_ue_id; /* mandatory */ /* c2. gNB-CU-UP UE E1AP ID */ asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextReleaseCompleteIEs_t, ieC2); ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; ieC2->criticality = E1AP_Criticality_reject; ieC2->value.present = E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; - ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id; + ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = cplt->gNB_cu_cp_ue_id; return 0; } -int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_bearer_release_cmd_t *const cmd) +int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, const e1ap_bearer_release_cplt_t *cplt) { E1AP_E1AP_PDU_t pdu = {0}; - fill_BEARER_CONTEXT_RELEASE_COMPLETE(cmd, &pdu); + fill_BEARER_CONTEXT_RELEASE_COMPLETE(cplt, &pdu); return e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } @@ -1592,12 +1592,12 @@ int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_u e1ap_bearer_release_cmd_t bearerCxt = {0}; extract_BEARER_CONTEXT_RELEASE_COMMAND(pdu, &bearerCxt); - CUUP_process_bearer_release_command(e1_inst->instance, &bearerCxt); + e1_bearer_release_cmd(&bearerCxt); return 0; } void extract_BEARER_CONTEXT_RELEASE_COMPLETE(const E1AP_E1AP_PDU_t *pdu, - e1ap_bearer_release_cmd_t *bearerCxt) { + e1ap_bearer_release_cplt_t *bearerCxt) { const E1AP_BearerContextReleaseComplete_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextReleaseComplete; E1AP_BearerContextReleaseCompleteIEs_t *ie; @@ -1634,9 +1634,12 @@ int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_ DevAssert(pdu->choice.successfulOutcome->criticality == E1AP_Criticality_reject); DevAssert(pdu->choice.successfulOutcome->value.present == E1AP_SuccessfulOutcome__value_PR_BearerContextReleaseComplete); - e1ap_bearer_release_cmd_t bearerCxt = {0}; + e1ap_bearer_release_cplt_t bearerCxt = {0}; extract_BEARER_CONTEXT_RELEASE_COMPLETE(pdu, &bearerCxt); - //TODO: CUCP_process_bearer_release_complete(&beareCxt, instance); + MessageDef *msg = itti_alloc_new_message(TASK_CUUP_E1, 0, E1AP_BEARER_CONTEXT_RELEASE_CPLT); + e1ap_bearer_release_cplt_t *cplt = &E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg); + *cplt = bearerCxt; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); return 0; } @@ -1864,6 +1867,10 @@ void *E1AP_CUCP_task(void *arg) { e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); break; + case E1AP_BEARER_CONTEXT_RELEASE_CMD: + e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(assoc_id, &E1AP_BEARER_CONTEXT_RELEASE_CMD(msg)); + break; + default: LOG_E(E1AP, "Unknown message received in TASK_CUCP_E1\n"); break; @@ -1921,6 +1928,13 @@ void *E1AP_CUUP_task(void *arg) { e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(inst->cuup.assoc_id, resp); } break; + case E1AP_BEARER_CONTEXT_RELEASE_CPLT: { + const e1ap_bearer_release_cplt_t *cplt = &E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg); + const e1ap_upcp_inst_t *inst = getCxtE1(myInstance); + AssertFatal(inst != NULL, "no E1 instance found for instance %ld\n", myInstance); + e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst->cuup.assoc_id, cplt); + } break; + default: LOG_E(E1AP, "Unknown message received in TASK_CUUP_E1\n"); break; diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h index fd82ffd147..b41559de09 100644 --- a/openair2/E1AP/e1ap.h +++ b/openair2/E1AP/e1ap.h @@ -50,7 +50,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_u int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_bearer_release_cmd_t *const cmd); +int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, const e1ap_bearer_release_cplt_t *cplt); void *E1AP_CUUP_task(void *arg); diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c deleted file mode 100644 index dfb6747600..0000000000 --- a/openair2/E1AP/e1ap_api.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 - * - * Author and copyright: Laurent Thomas, open-cells.com - * - * 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 -#include "e1ap_api.h" - -#include "nr_pdcp/nr_pdcp_entity.h" -#include "openair2/RRC/NR/cucp_cuup_if.h" -#include "openair2/RRC/LTE/MESSAGES/asn1_msg.h" -#include "openair3/SECU/key_nas_deriver.h" -#include "openair3/ocp-gtpu/gtp_itf.h" -#include "openair2/F1AP/f1ap_ids.h" -#include "e1ap_asnc.h" -#include "e1ap_common.h" -#include "e1ap.h" - -void CUUP_process_bearer_release_command(instance_t instance, e1ap_bearer_release_cmd_t *const cmd) -{ - e1ap_upcp_inst_t *inst = getCxtE1(instance); - AssertFatal(inst, ""); - newGtpuDeleteAllTunnels(inst->gtpInstN3, cmd->gNB_cu_up_ue_id); - newGtpuDeleteAllTunnels(inst->gtpInstF1U, cmd->gNB_cu_up_ue_id); - e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst->cuup.assoc_id, cmd); -} diff --git a/openair2/E1AP/e1ap_api.h b/openair2/E1AP/e1ap_api.h index e2d0c892d1..a3759399c7 100644 --- a/openair2/E1AP/e1ap_api.h +++ b/openair2/E1AP/e1ap_api.h @@ -25,9 +25,7 @@ #define E1AP_API_H #include "platform_types.h" -#include "openair2/COMMON/e1ap_messages_types.h" -#include "openair2/E1AP/e1ap_common.h" + void cuup_init_n3(instance_t instance); -void CUUP_process_bearer_release_command(instance_t, e1ap_bearer_release_cmd_t *const cmd); #endif diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 0547680eea..cf8982339d 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -117,6 +117,9 @@ int e1ap_decode_initiating_message(E1AP_E1AP_PDU_t *pdu) { case E1AP_ProcedureCode_id_bearerContextModification: break; + case E1AP_ProcedureCode_id_bearerContextRelease: + break; + default: LOG_E(E1AP, "Unsupported procedure code (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); @@ -137,6 +140,9 @@ int e1ap_decode_successful_outcome(E1AP_E1AP_PDU_t *pdu) { case E1AP_ProcedureCode_id_bearerContextModification: break; + case E1AP_ProcedureCode_id_bearerContextRelease: + break; + default: LOG_E(E1AP, "Unsupported procedure code (%d) for successful message\n", (int)pdu->choice.successfulOutcome->procedureCode); diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index aaf5323b03..d661f9c6f4 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -257,3 +257,24 @@ void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) get_e1_if()->bearer_modif_response(&modif); } + +void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) +{ + instance_t n3inst = get_n3_gtp_instance(); + instance_t f1inst = get_f1_gtp_instance(); + + LOG_I(E1AP, "releasing UE %d\n", cmd->gNB_cu_up_ue_id); + + newGtpuDeleteAllTunnels(n3inst, cmd->gNB_cu_up_ue_id); + if (f1inst >= 0) // is there F1-U? + newGtpuDeleteAllTunnels(f1inst, cmd->gNB_cu_up_ue_id); + nr_pdcp_remove_UE(cmd->gNB_cu_up_ue_id); + cu_remove_f1_ue_data(cmd->gNB_cu_up_ue_id); + + e1ap_bearer_release_cplt_t cplt = { + .gNB_cu_cp_ue_id = cmd->gNB_cu_cp_ue_id, + .gNB_cu_up_ue_id = cmd->gNB_cu_up_ue_id, + }; + + get_e1_if()->bearer_release_complete(&cplt); +} diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h index 7c9c6244f3..7290043371 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h @@ -27,7 +27,9 @@ void nr_pdcp_e1_if_init(bool uses_e1); struct e1ap_bearer_setup_req_s; +struct e1ap_bearer_release_cmd_s; void e1_bearer_context_setup(const struct e1ap_bearer_setup_req_s *req); void e1_bearer_context_modif(const struct e1ap_bearer_setup_req_s *req); +void e1_bearer_release_cmd(const struct e1ap_bearer_release_cmd_s *cmd); #endif /* CUCP_CUUP_HANDLER_H */ diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c b/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c index 52918b4d64..b6ad66e18c 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c @@ -39,8 +39,17 @@ static void bearer_modif_response_direct(const e1ap_bearer_modif_resp_t *resp) itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } +static void bearer_release_complete_direct(const e1ap_bearer_release_cplt_t *cplt) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, E1AP_BEARER_CONTEXT_RELEASE_CPLT); + e1ap_bearer_release_cplt_t *msg_cplt = &E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg); + *msg_cplt = *cplt; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); +} + void cuup_cucp_init_direct(e1_if_t *iface) { iface->bearer_setup_response = bearer_setup_response_direct; iface->bearer_modif_response = bearer_modif_response_direct; + iface->bearer_release_complete = bearer_release_complete_direct; } diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c b/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c index 91ed1b1ec8..8454d5a7d8 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c @@ -39,8 +39,17 @@ static void bearer_modif_response_e1ap(const e1ap_bearer_modif_resp_t *resp) itti_send_msg_to_task (TASK_CUUP_E1, 0, msg_p); } +static void bearer_release_complete_e1ap(const e1ap_bearer_release_cplt_t *cplt) +{ + MessageDef *msg_p = itti_alloc_new_message(TASK_CUUP_E1, 0, E1AP_BEARER_CONTEXT_RELEASE_CPLT); + e1ap_bearer_release_cplt_t *msg_cplt = &E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg_p); + *msg_cplt = *cplt; + itti_send_msg_to_task (TASK_CUUP_E1, 0, msg_p); +} + void cuup_cucp_init_e1ap(e1_if_t *iface) { iface->bearer_setup_response = bearer_setup_response_e1ap; iface->bearer_modif_response = bearer_modif_response_e1ap; + iface->bearer_release_complete = bearer_release_complete_e1ap; } diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h index 3a576b7f7f..c33694dac3 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h @@ -26,12 +26,15 @@ struct e1ap_bearer_setup_resp_s; struct e1ap_bearer_modif_resp_s; +struct e1ap_bearer_release_cplt_s; typedef void (*e1_bearer_setup_response_func_t)(const struct e1ap_bearer_setup_resp_s *resp); typedef void (*e1_bearer_modif_response_func_t)(const struct e1ap_bearer_modif_resp_s *resp); +typedef void (*e1_bearer_release_complete_func_t)(const struct e1ap_bearer_release_cplt_s *cplt); typedef struct e1_if_t { e1_bearer_setup_response_func_t bearer_setup_response; e1_bearer_modif_response_func_t bearer_modif_response; + e1_bearer_release_complete_func_t bearer_release_complete; } e1_if_t; e1_if_t *get_e1_if(void); diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 3c45598f15..ee3555a14b 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -37,7 +37,14 @@ static void cucp_cuup_bearer_context_modif_direct(sctp_assoc_t assoc_id, const e e1_bearer_context_modif(req); } +static void cucp_cuup_bearer_context_release_cmd_direct(sctp_assoc_t assoc_id, const e1ap_bearer_release_cmd_t *cmd) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d, impossible for integrated CU\n", assoc_id); + e1_bearer_release_cmd(cmd); +} + void cucp_cuup_message_transfer_direct_init(gNB_RRC_INST *rrc) { rrc->cucp_cuup.bearer_context_setup = cucp_cuup_bearer_context_setup_direct; rrc->cucp_cuup.bearer_context_mod = cucp_cuup_bearer_context_modif_direct; + rrc->cucp_cuup.bearer_context_release = cucp_cuup_bearer_context_release_cmd_direct; } diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index 1678dd8313..fb099178d4 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -47,7 +47,18 @@ static void cucp_cuup_bearer_context_mod_e1ap(sctp_assoc_t assoc_id, const e1ap_ itti_send_msg_to_task(TASK_CUCP_E1, 0, msg); } +static void cucp_cuup_bearer_context_release_cmd_e1ap(sctp_assoc_t assoc_id, const e1ap_bearer_release_cmd_t *cmd) +{ + AssertFatal(assoc_id > 0, "illegal assoc_id %d\n", assoc_id); + MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_RELEASE_CMD); + msg->ittiMsgHeader.originInstance = assoc_id; + e1ap_bearer_release_cmd_t *cmd_msg = &E1AP_BEARER_CONTEXT_RELEASE_CMD(msg); + memcpy(cmd_msg, cmd, sizeof(*cmd)); + itti_send_msg_to_task(TASK_CUCP_E1, 0, msg); +} + void cucp_cuup_message_transfer_e1ap_init(gNB_RRC_INST *rrc) { rrc->cucp_cuup.bearer_context_setup = cucp_cuup_bearer_context_setup_e1ap; rrc->cucp_cuup.bearer_context_mod = cucp_cuup_bearer_context_mod_e1ap; + rrc->cucp_cuup.bearer_context_release = cucp_cuup_bearer_context_release_cmd_e1ap; } diff --git a/openair2/RRC/NR/cucp_cuup_if.h b/openair2/RRC/NR/cucp_cuup_if.h index 125ae93522..cbf84a289e 100644 --- a/openair2/RRC/NR/cucp_cuup_if.h +++ b/openair2/RRC/NR/cucp_cuup_if.h @@ -30,7 +30,9 @@ struct e1ap_bearer_setup_req_s; struct e1ap_bearer_setup_resp_s; +struct e1ap_bearer_release_cmd_s; typedef void (*cucp_cuup_bearer_context_setup_func_t)(sctp_assoc_t assoc_id, const struct e1ap_bearer_setup_req_s *req); +typedef void (*cucp_cuup_bearer_context_release_func_t)(sctp_assoc_t assoc_id, const struct e1ap_bearer_release_cmd_s *cmd); struct gNB_RRC_INST_s; void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 92b521cf69..16b7f040ee 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -362,6 +362,7 @@ typedef struct nr_mac_rrc_dl_if_s { typedef struct cucp_cuup_if_s { cucp_cuup_bearer_context_setup_func_t bearer_context_setup; cucp_cuup_bearer_context_setup_func_t bearer_context_mod; + cucp_cuup_bearer_context_release_func_t bearer_context_release; } cucp_cuup_if_t; typedef struct nr_rrc_du_container_t { diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 1534dde669..81455e3549 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2034,8 +2034,6 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - nr_pdcp_remove_UE(UE->rrc_ue_id); - newGtpuDeleteAllTunnels(instance, UE->rrc_ue_id); rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->rrc_ue_id); LOG_I(NR_RRC, "removed UE CU UE ID %u/RNTI %04x \n", UE->rrc_ue_id, UE->rnti); rrc_delete_ue_data(UE); @@ -2411,6 +2409,15 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t } } +void rrc_gNB_process_e1_bearer_context_release_cplt(const e1ap_bearer_release_cplt_t *cplt) +{ + // there is not really anything to do here as of now + // note that we don't check for the UE: it does not exist anymore if the F1 + // UE context release complete arrived from the DU first, after which we free + // the UE context + LOG_I(RRC, "UE %d: received bearer release complete\n", cplt->gNB_cu_cp_ue_id); +} + static void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) { AssertFatal(rrc->du != NULL, "no DU connected, cannot received F1 lost connection\n"); @@ -2694,6 +2701,10 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_e1_bearer_context_modif_resp(&E1AP_BEARER_CONTEXT_MODIFICATION_RESP(msg_p)); break; + case E1AP_BEARER_CONTEXT_RELEASE_CPLT: + rrc_gNB_process_e1_bearer_context_release_cplt(&E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg_p)); + break; + case NGAP_PAGING_IND: rrc_gNB_process_PAGING_IND(msg_p, instance); break; @@ -2845,6 +2856,13 @@ rrc_gNB_generate_RRCRelease( deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd}; nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data); + sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE); + e1ap_bearer_release_cmd_t cmd = { + .gNB_cu_cp_ue_id = UE->rrc_ue_id, + .gNB_cu_up_ue_id = UE->rrc_ue_id, + }; + rrc->cucp_cuup.bearer_context_release(assoc_id, &cmd); + /* UE will be freed after UE context release complete */ } From 781d01d5de1107b6f2fad04d9afd42d6a9a6d170 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 25 Oct 2023 13:52:04 +0200 Subject: [PATCH 34/40] Remove (almost) unused e1ap_api.h --- executables/nr-softmodem.c | 1 - openair2/E1AP/e1ap.c | 1 - openair2/E1AP/e1ap_api.h | 31 ------------------------------- openair2/E1AP/e1ap_common.h | 1 + 4 files changed, 1 insertion(+), 33 deletions(-) delete mode 100644 openair2/E1AP/e1ap_api.h diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 47e2289f36..75a9e0dc24 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -80,7 +80,6 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "nfapi/oai_integration/vendor_ext.h" #include "gnb_config.h" #include "openair2/E1AP/e1ap_common.h" -#include "openair2/E1AP/e1ap_api.h" #ifdef E2_AGENT #include "openair2/E2AP/flexric/src/agent/e2_agent_api.h" diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index d6116309db..077c67ca98 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -23,7 +23,6 @@ #include "e1ap.h" #include "e1ap_common.h" -#include "e1ap_api.h" #include "gnb_config.h" #include "openair2/SDAP/nr_sdap/nr_sdap_entity.h" #include "openair3/UTILS/conversions.h" diff --git a/openair2/E1AP/e1ap_api.h b/openair2/E1AP/e1ap_api.h deleted file mode 100644 index a3759399c7..0000000000 --- a/openair2/E1AP/e1ap_api.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 - * - * Author and copyright: Laurent Thomas, open-cells.com - * - * 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 E1AP_API_H -#define E1AP_API_H - -#include "platform_types.h" - -void cuup_init_n3(instance_t instance); - -#endif diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index ed6dd2606c..e0aea6990f 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -57,5 +57,6 @@ void createE1inst(E1_t type, instance_t instance, e1ap_net_config_t *nc, e1ap_se int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, struct E1AP_E1AP_PDU *pdu, uint16_t stream, const char *func); void e1ap_common_init(); +void cuup_init_n3(instance_t instance); #endif /* E1AP_COMMON_H_ */ From 2f87a2b0e563099869e9ed34ee041b64b8ad742b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 25 Oct 2023 14:26:33 +0200 Subject: [PATCH 35/40] Remove superfluous security section from gNB-CU-UP configs --- ci-scripts/conf_files/gnb-cuup.sa.f1.conf | 33 +++---------------- .../conf_files/gnb-cuup.sa.f1.quectel.conf | 17 ---------- 2 files changed, 5 insertions(+), 45 deletions(-) diff --git a/ci-scripts/conf_files/gnb-cuup.sa.f1.conf b/ci-scripts/conf_files/gnb-cuup.sa.f1.conf index 6759654e0d..6e5ac39e9b 100644 --- a/ci-scripts/conf_files/gnb-cuup.sa.f1.conf +++ b/ci-scripts/conf_files/gnb-cuup.sa.f1.conf @@ -56,32 +56,9 @@ gNBs = } ); -security = { - # preferred ciphering algorithms - # the first one of the list that an UE supports in chosen - # valid values: nea0, nea1, nea2, nea3 - ciphering_algorithms = ( "nea0" ); - - # preferred integrity algorithms - # the first one of the list that an UE supports in chosen - # valid values: nia0, nia1, nia2, nia3 - integrity_algorithms = ( "nia2", "nia0" ); - - # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter - # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' - drb_ciphering = "yes"; - drb_integrity = "no"; +log_config : { + global_log_level = "info"; + pdcp_log_level = "info"; + f1ap_log_level = "info"; + ngap_log_level = "info"; }; - log_config : - { - global_log_level ="info"; - hw_log_level ="info"; - phy_log_level ="info"; - mac_log_level ="info"; - rlc_log_level ="debug"; - pdcp_log_level ="info"; - rrc_log_level ="info"; - f1ap_log_level ="info"; - ngap_log_level ="debug"; - }; - diff --git a/ci-scripts/conf_files/gnb-cuup.sa.f1.quectel.conf b/ci-scripts/conf_files/gnb-cuup.sa.f1.quectel.conf index 535ef68bd0..2ac45486a6 100644 --- a/ci-scripts/conf_files/gnb-cuup.sa.f1.quectel.conf +++ b/ci-scripts/conf_files/gnb-cuup.sa.f1.quectel.conf @@ -56,23 +56,6 @@ gNBs = } ); -security = { - # preferred ciphering algorithms - # the first one of the list that an UE supports in chosen - # valid values: nea0, nea1, nea2, nea3 - ciphering_algorithms = ( "nea0" ); - - # preferred integrity algorithms - # the first one of the list that an UE supports in chosen - # valid values: nia0, nia1, nia2, nia3 - integrity_algorithms = ( "nia2", "nia0" ); - - # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter - # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' - drb_ciphering = "yes"; - drb_integrity = "no"; -}; - log_config: { global_log_level = "info"; }; From c2f0bf16d7f165cfb152f849576ec086f3abe3d1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 25 Oct 2023 14:35:47 +0200 Subject: [PATCH 36/40] Rename non-existing gNB_CU_ID to existing gNB_ID in all configs --- ci-scripts/conf_files/gnb-cucp.sa.f1.conf | 2 +- ci-scripts/conf_files/gnb-cucp.sa.f1.quectel.conf | 2 +- ci-scripts/conf_files/gnb-cuup.sa.f1.conf | 2 +- ci-scripts/conf_files/gnb-cuup.sa.f1.quectel.conf | 2 +- ci-scripts/conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf | 2 +- ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf | 2 +- .../CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf | 2 +- .../CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ci-scripts/conf_files/gnb-cucp.sa.f1.conf b/ci-scripts/conf_files/gnb-cucp.sa.f1.conf index 5eb123dba1..469ab8d187 100644 --- a/ci-scripts/conf_files/gnb-cucp.sa.f1.conf +++ b/ci-scripts/conf_files/gnb-cucp.sa.f1.conf @@ -8,7 +8,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gnb-cucp.sa.f1.quectel.conf b/ci-scripts/conf_files/gnb-cucp.sa.f1.quectel.conf index 9d0c13cd74..8b9e865e0d 100644 --- a/ci-scripts/conf_files/gnb-cucp.sa.f1.quectel.conf +++ b/ci-scripts/conf_files/gnb-cucp.sa.f1.quectel.conf @@ -8,7 +8,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gnb-cuup.sa.f1.conf b/ci-scripts/conf_files/gnb-cuup.sa.f1.conf index 6e5ac39e9b..357518bcf2 100644 --- a/ci-scripts/conf_files/gnb-cuup.sa.f1.conf +++ b/ci-scripts/conf_files/gnb-cuup.sa.f1.conf @@ -7,7 +7,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gnb-cuup.sa.f1.quectel.conf b/ci-scripts/conf_files/gnb-cuup.sa.f1.quectel.conf index 2ac45486a6..4e65547db9 100644 --- a/ci-scripts/conf_files/gnb-cuup.sa.f1.quectel.conf +++ b/ci-scripts/conf_files/gnb-cuup.sa.f1.quectel.conf @@ -7,7 +7,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf b/ci-scripts/conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf index a1e66c7ade..eb664f1ccb 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; gNB_name = "gNB-OAI"; diff --git a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf index 4f615b8dba..dcdb8307dc 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf @@ -10,7 +10,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; gNB_name = "gNB-Eurecom-n78_20"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf index 01259ac5a6..aa3e5de456 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf index c2fa1bb623..65a2a49d50 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; From eb475f7747abb3cafed003373ccba250370f1de6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 26 Oct 2023 15:01:49 +0200 Subject: [PATCH 37/40] Remove useless warning --- openair2/RRC/NR/rrc_gNB.c | 1 - 1 file changed, 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 81455e3549..7af9350136 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -575,7 +575,6 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co dedicatedNAS_MessageList, ue_p->masterCellGroup); AssertFatal(size > 0, "cannot encode RRCReconfiguration in %s()\n", __func__); - LOG_W(NR_RRC, "do_RRCReconfiguration(): size %d\n", size); free_defaultMeasConfig(measconfig); if (LOG_DEBUGFLAG(DEBUG_ASN1)) { From 5fb151e195834414d119d138b77865be08cc93a7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 27 Oct 2023 08:47:18 +0200 Subject: [PATCH 38/40] Rework E1 documentation --- doc/E1-design.md | 71 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/doc/E1-design.md b/doc/E1-design.md index 6f9e8f4edd..983013dce7 100644 --- a/doc/E1-design.md +++ b/doc/E1-design.md @@ -2,38 +2,55 @@ # 1. Introduction -E1 is named for the interface that lies between the nodes CU Control Plane (CUCP) and CU User Plane (CUUP). Once the nodes are configured, all user plane traffic flows through CUUP. +E1 is the interface that lies between the nodes CU Control Plane (CUCP) and CU User Plane (CUUP). Once the nodes are configured, all user plane traffic flows through CUUP. -The E1 design in OAI follows the 3GPP specification in TS 38.460. The code design on E1 in OAI is very similar to -F1. The ITTI message passing mechanism is used to exchange messages between E1AP thread, SCTP thread and RRC thread. - -The following sequence chart shows the current E1AP message flow. +The E1 design in OAI follows the 3GPP specification in TS 38.460/463. The code +design on E1 in OAI is very similar to F1: OAI uses E1 internally to set up +bearers, even in monolithic gNB, where the actual "way" the messages are passed +is abstracted through function pointers. More specifically, there are handlers +that handle the E1 messages as shown below, *which are the same* no matter if +the CU is integrated or separate in CU-CP/UP. The below sequence diagram lists +the handlers that are executed and the current E1AP message flow (SCTP +connection setup only in split-mode, the rest is the same for CU): ```mermaid sequenceDiagram participant c as CUCP participant u as CUUP - u->>c: SCTP new association - c->>u: SCTP new association response - Note over u: Create UDP sockets for F1-U and N3 + u->c: SCTP connection setup (in split mode) u->>c: E1AP Setup Request + Note over c: Execute rrc_gNB_process_e1_setup_req() c->>u: E1AP Setup Response + Note over c: Receives PDU session setup request from AMF c->>u: Bearer Context Setup Request - Note over u: Configure DRBs and create GTP Tunnels for F1-U and N3 + Note over u: Execute e1_bearer_context_setup()
Configure DRBs and create GTP Tunnels for F1-U and N3 u->>c: Bearer Context Setup Response - Note over c: Sends F1-U UL TNL info to DU and receives DL TNL info + Note over c: Execute rrc_gNB_process_e1_setup_req()
Sends F1-U UL TNL info to DU and receives DL TNL info + c->>u: Bearer Context Modification Request - Note over u: Updates GTP Tunnels with received info + Note over u: Execute e1_bearer_context_modif()
Updates GTP Tunnels with received info + u->>c: Bearer Context Modification Response + Note over c: Execute rrc_gNB_process_e1_bearer_context_modif_resp() + + Note over c: UE release triggered + c->>u: Bearer Context Release Request + Note over u: Execute e1_bearer_release_cmd()
Frees GTP tunnels, PDCP data etc + u->>c: Bearer Context Release Complete + Note over c: Execute rrc_gNB_process_e1_bearer_context_release_cplt() ``` -_Note that the E1 bearer release procedures are currently not implemented._ +The files that implement the callback towards these handlers are in +- `cucp_cuup_direct.c`: integrated CU (for CP=>UP messages) +- `cucp_cuup_e1ap.c`: E1 split mode (for CP=>UP messages) +- `cuup_cucp_direct.c`: integrated CU (for UP=>CP messages) +- `cuup_cucp_e1ap.c`: E1 split mode (for UP=>CP messages) # 2. Running the E1 Split ## 2.1 Configuration File -The gNB is started based on the node type that is specified in the configuration file. To start a gNB instance in CUCP or CUUP, the `tr_s_preference` should be set to "f1" and the config member `E1_INTERFACE` should be present in the config file. The `type` parameter within the `E1_INTERFACE` should be set to `cp`, and `nr-softmodem` should be used to run a CU-CP. The type should be `up` and `nr-cuup` should be used to run the CU-UP. Further, there are the parameters `ipv4_cucp` and `ipv4_cuup` to specify the IP addresses of the respective network functions. +The gNB is started based on the node type that is specified in the configuration file. To start a gNB instance in CUCP or CUUP, the `tr_s_preference` should be set to "f1" and the config member `E1_INTERFACE` should be present in the config file. The `type` parameter within the `E1_INTERFACE` should be set to `cp`, and executable `nr-softmodem` should be used to run a CU-CP. The type should be `up` and executable `nr-cuup` should be used to run the CU-UP. Further, there are the parameters `ipv4_cucp` and `ipv4_cuup` to specify the IP addresses of the respective network functions. For CUCP, a typical `E1_INTERFACE` config looks like ``` @@ -62,7 +79,7 @@ One could take an existing CU configuration file and add the above parameters to The CUUP uses the IP address specified in `local_s_address` for F1-U and `GNB_IPV4_ADDRESS_FOR_NGU` for N3 links. Note that `local_s_address` is under `gNBs` and `GNB_IPV4_ADDRESS_FOR_NGU` is part of the `NETWORK_INTERFACES` config member. -Alternatively, you can use the config files `ci-scripts/conf_files/gnb-cucp.sa.conf` and `ci-scripts/conf_files/gnb-cuup.sa.conf` which are already in the repository. +Alternatively, you can use the config files `ci-scripts/conf_files/gnb-cucp.sa.f1.conf` and `ci-scripts/conf_files/gnb-cuup.sa.f1.conf`. ## 2.2 Steps to Run the Split in rfsimulator with OAI UE @@ -73,7 +90,7 @@ Note: A 5G core must be running at this point. Steps to start the OAI 5G core ca 1. Start the CUCP first by running the following command ``` -sudo ./nr-softmodem -O ../../../ci-scripts/conf_files/gnb-cucp.sa.conf --gNBs.[0].min_rxtxtime 6 --sa +sudo ./nr-softmodem -O ../../../ci-scripts/conf_files/gnb-cucp.sa.f1.conf --gNBs.[0].min_rxtxtime 6 --sa ``` Note that `min_rxtxtime` should be set to `6` only when you are connecting an OAI UE to the gNB. @@ -82,7 +99,7 @@ Note that `min_rxtxtime` should be set to `6` only when you are connecting an OA CUUP (has its own executable): ``` -sudo ./nr-cuup -O ../../../ci-scripts/conf_files/gnb-cuup.sa.conf --sa +sudo ./nr-cuup -O ../../../ci-scripts/conf_files/gnb-cuup.sa.f1.conf --sa ``` DU: @@ -106,3 +123,25 @@ You can also run the nodes on different machines. If you do so please change the ![E1/F1/NG parameters](images/e1-archi.png){width=1200} [PDF version](images/e1-archi.pdf) | [LaTeX/TikZ version](img/e1-archi.tex) if you want to modify to reflect your setup + +# 4. Multiple CU-UP + +It is possible to connect multiple CU-UP to the same CU-CP. In the handler of +the E1 Setup Request, the CU-CP verifies that the PLMN(s) (MCC, MNC) between +both nodes match, and that no CU-UP with the same ID exists. Note that the +NSSAIs for the CU-UPs can be different. + +During attach, the following rules are used to select a CU-UP at the CU-CP, in +order: +- Select a CU-UP based on slice identifiers: + - If both the SST and SD match exactly, that CU-UP is selected. (If multiple + have the same NSSAI, the first is always selected.) + - Otherwise, the first CU-UP with the same SST but different SD is selected. +- Round-robin across all CU-UPs. +- The first CU-UP. +- If no CU-UP is selected, the CU-CP asserts. + +Note that CU-UPs are not released from CU-CP internal structures. That means +that you have to restart the CU-CP if you want to connect the CU-UP again +(e.g., after a crash). The CU-CP might also misfunction during attach if a +CU-UP was connected, but disconnected in the meantime. From a87cad57b7760fde3f94fba5db1ce22a109d7658 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 27 Oct 2023 10:28:11 +0200 Subject: [PATCH 39/40] Fix: correct SD index --- openair2/RRC/NR/rrc_gNB_NGAP.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 40d96fe527..1e1b9529b3 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -785,7 +785,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins pdu->nssai.sst = nssai->sST; pdu->nssai.sd = 0xffffff; if (nssai->sD_flag) - pdu->nssai.sd = nssai->sD[0] << 16 | nssai->sD[1] << 8 | nssai->sD[0]; + pdu->nssai.sd = nssai->sD[0] << 16 | nssai->sD[1] << 8 | nssai->sD[2]; if (cuup_nssai.sst == 0) cuup_nssai = pdu->nssai; /* for CU-UP selection below */ pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed; From fa5c4d3a4cf9befdbf9ea324d0483c66a80a5b98 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Oct 2023 08:37:13 +0100 Subject: [PATCH 40/40] Fix SDAP: correct ID, set default - Set the correct QoS flow ID to associate a correct QoS flow to the bearer: the UE would misassociate otherwise - Set the DRB as the default: the handler applies bool with true==1, so use bool value --- openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c | 4 ++-- openair2/RRC/NR/rrc_gNB_NGAP.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index d661f9c6f4..7e00b0ee8d 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -53,8 +53,8 @@ static void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, const asn1cCalloc(sdap_config->mappedQoS_FlowsToAdd, FlowsToAdd); for (int j=0; j < drb->numQosFlow2Setup; j++) { - asn1cSequenceAdd(FlowsToAdd->list, NR_QFI_t, qfi); - *qfi = drb->qosFlows[j].fiveQI; + asn1cSequenceAdd(FlowsToAdd->list, NR_QFI_t, id); + *id = drb->qosFlows[j].id; } sdap_config->mappedQoS_FlowsToRelease = NULL; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 1e1b9529b3..49d3ccad99 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -799,7 +799,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins drb->id = i + j + UE->nb_of_pdusessions; - drb->defaultDRB = E1AP_DefaultDRB_true; + drb->defaultDRB = true; drb->sDAP_Header_UL = !(rrc->configuration.enable_sdap); drb->sDAP_Header_DL = !(rrc->configuration.enable_sdap);