From 7faabc6b45b1a6ec76486125d86f7da8b40df4a8 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 10 Jan 2024 19:05:52 +0100 Subject: [PATCH] Implementation E1 Setup Failure (8.2.3.3 of 3GPP TS 38.463) - CU-CP replying to the CU-UP with a Setup Failure message in case of unsuccessfull E1 Setup Request - message is decoded by the CU-UP, and stops the process --- doc/E1-design.md | 13 +++++++--- openair2/COMMON/e1ap_messages_def.h | 2 ++ openair2/COMMON/e1ap_messages_types.h | 6 +++++ openair2/E1AP/e1ap.c | 36 +++++++++++++++++++++++++-- openair2/RRC/NR/rrc_gNB_cuup.c | 17 ++++++++++++- 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/doc/E1-design.md b/doc/E1-design.md index 983013dce7..4184c946ea 100644 --- a/doc/E1-design.md +++ b/doc/E1-design.md @@ -17,17 +17,22 @@ connection setup only in split-mode, the rest is the same for CU): sequenceDiagram participant c as CUCP participant u as CUUP - 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,u: E1 Setup Procedure + u->c: SCTP connection setup (in split mode) + u->>c: E1 Setup Request + Note over c: Execute rrc_gNB_process_e1_setup_req() + c->>u: E1 Setup Response + c-->>u: E1 Setup Failure + + Note over c,u: E1 Bearer Context Setup Procedure Note over c: Receives PDU session setup request from AMF c->>u: Bearer Context Setup Request 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: Execute rrc_gNB_process_e1_setup_req()
Sends F1-U UL TNL info to DU and receives DL TNL info + Note over c,u: E1 Bearer Context Modification (CU-CP Initiated) Procedure c->>u: Bearer Context Modification Request Note over u: Execute e1_bearer_context_modif()
Updates GTP Tunnels with received info u->>c: Bearer Context Modification Response diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h index ea24ac9e18..6da8e85ee1 100644 --- a/openair2/COMMON/e1ap_messages_def.h +++ b/openair2/COMMON/e1ap_messages_def.h @@ -27,6 +27,8 @@ MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_set /* E1AP -> eNB_DU or eNB_CU_RRC -> E1AP application layer messages */ MESSAGE_DEF(E1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, e1ap_setup_resp_t , e1ap_setup_resp) +/* E1AP Setup Failure: gNB-CU-CP -> gNB-CU-UP */ +MESSAGE_DEF(E1AP_SETUP_FAIL, MESSAGE_PRIORITY_MED, e1ap_setup_fail_t, e1ap_setup_fail) MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_setup_req) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index b6400b53b5..605441e5f7 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -44,6 +44,7 @@ #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_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_fail #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 @@ -94,6 +95,11 @@ typedef struct e1ap_setup_resp_s { long transac_id; } e1ap_setup_resp_t; +/* E1AP Setup Failure */ +typedef struct e1ap_setup_fail_s { + long transac_id; +} e1ap_setup_fail_t; + typedef struct cell_group_s { long id; } cell_group_t; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 353b8931e1..baeb690440 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -257,25 +257,36 @@ void e1ap_send_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1ap_setup_resp_t *e1 e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } +/** + * @brief E1 Setup Failure ASN1 messager builder + * @ref 9.2.1.6 GNB-CU-UP E1 SETUP FAILURE of 3GPP TS 38.463 +*/ static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu) { /* Create */ /* 0. pdu Type */ pdu->present = E1AP_E1AP_PDU_PR_unsuccessfulOutcome; asn1cCalloc(pdu->choice.unsuccessfulOutcome, initMsg); + /* mandatory */ + /** + * Message Type IE + * - procedureCode (integer) + * - Type of Message (choice) + * @ref clause 9.3.1.1 of 3GPP TS 38.463 + */ initMsg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup; initMsg->criticality = E1AP_Criticality_reject; initMsg->value.present = E1AP_UnsuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupFailure; E1AP_GNB_CU_UP_E1SetupFailure_t *out = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure; /* mandatory */ - /* c1. Transaction ID (integer value) */ + /* c1. Transaction ID (integer value), clause 9.3.1.53 of 3GPP TS 38.463 */ asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ieC1); ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID; ieC1->criticality = E1AP_Criticality_reject; ieC1->value.present = E1AP_GNB_CU_UP_E1SetupFailureIEs__value_PR_TransactionID; ieC1->value.choice.TransactionID = transac_id; /* mandatory */ - /* c2. cause (integer value) */ + /* c2. cause (integer value), clause 9.3.1.2 of 3GPP TS 38.463 */ asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ieC2); ieC2->id = E1AP_ProtocolIE_ID_id_Cause; ieC2->criticality = E1AP_Criticality_ignore; @@ -284,8 +295,12 @@ static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu) ieC2->value.choice.Cause.choice.radioNetwork = E1AP_CauseRadioNetwork_unspecified; } +/** + * @brief E1 Setup Failure ASN1 messager encoder +*/ void e1apCUCP_send_SETUP_FAILURE(sctp_assoc_t assoc_id, long transac_id) { + LOG_D(E1AP, "CU-CP: Encoding E1AP Setup Failure for transac_id %ld...\n", transac_id); E1AP_E1AP_PDU_t pdu = {0}; fill_SETUP_FAILURE(transac_id, &pdu); e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); @@ -404,18 +419,31 @@ int e1apCUUP_handle_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst return 0; } +/** + * @brief E1 Setup Failure ASN1 messager decoder on CU-UP +*/ int e1apCUUP_handle_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu) { + LOG_D(E1AP, "CU-UP: Decoding E1AP Setup Failure...\n"); E1AP_GNB_CU_UP_E1SetupFailureIEs_t *ie; DevAssert(pdu != NULL); E1AP_GNB_CU_UP_E1SetupFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure; /* Transaction ID */ F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in, E1AP_ProtocolIE_ID_id_TransactionID, true); + long transaction_id; + long old_transaction_id = inst->cuup.setupReq.transac_id; + transaction_id = ie->value.choice.TransactionID; + if (old_transaction_id != transaction_id) + LOG_E(E1AP, "Transaction IDs do not match %ld != %ld\n", old_transaction_id, transaction_id); + E1AP_free_transaction_identifier(transaction_id); + /* Cause */ F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in, E1AP_ProtocolIE_ID_id_Cause, true); + LOG_E(E1AP, "received E1 Setup Failure, please check the CU-CP output and the CU-UP parameters\n"); + exit(1); return 0; } @@ -1875,6 +1903,10 @@ void *E1AP_CUCP_task(void *arg) { e1ap_send_SETUP_RESPONSE(assoc_id, &E1AP_SETUP_RESP(msg)); break; + case E1AP_SETUP_FAIL: + e1apCUCP_send_SETUP_FAILURE(assoc_id, E1AP_SETUP_FAIL(msg).transac_id); + break; + case E1AP_BEARER_CONTEXT_SETUP_REQ: e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); break; diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index 6c5ea8aef5..5abdbcfac7 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -122,6 +122,19 @@ sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue return ue_data.e1_assoc_id; } +static void e1ap_setup_failure(sctp_assoc_t assoc_id, uint64_t transac_id) +{ + MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, E1AP_SETUP_FAIL); + msg_p->ittiMsgHeader.originInstance = assoc_id; + e1ap_setup_fail_t *setup_fail = &E1AP_SETUP_FAIL(msg_p); + setup_fail->transac_id = transac_id; + LOG_I(NR_RRC, "Triggering E1AP Setup Failure for transac_id %ld (%ld), assoc_id %ld\n", + transac_id, + E1AP_SETUP_FAIL(msg_p).transac_id, + msg_p->ittiMsgHeader.originInstance); + itti_send_msg_to_task(TASK_CUCP_E1, 0 /*unused by callee*/, msg_p); +} + 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"); @@ -138,6 +151,7 @@ int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req) c->setup_req->gNB_cu_up_id, c->setup_req->gNB_cu_up_name, c->assoc_id); + e1ap_setup_failure(assoc_id, req->transac_id); return -1; } } @@ -151,11 +165,12 @@ int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req) id->mnc, rrc->configuration.mcc[i], rrc->configuration.mnc[i]); + e1ap_setup_failure(assoc_id, req->transac_id); return -1; } } - 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); + LOG_I(NR_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); nr_rrc_cuup_container_t *cuup = malloc(sizeof(*cuup)); AssertFatal(cuup, "out of memory\n"); cuup->setup_req = malloc(sizeof(*cuup->setup_req));