From 7faabc6b45b1a6ec76486125d86f7da8b40df4a8 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 10 Jan 2024 19:05:52 +0100 Subject: [PATCH 01/13] 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)); From c8103f2905658a570f451993a24b6e10411b7a76 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 11 Jan 2024 10:55:27 +0100 Subject: [PATCH 02/13] Minor fix to E1 Setup Failure log --- openair2/RRC/NR/rrc_gNB_cuup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index 5abdbcfac7..75003b05eb 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -128,9 +128,8 @@ static void e1ap_setup_failure(sctp_assoc_t assoc_id, uint64_t transac_id) 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", + LOG_I(NR_RRC, "Triggering E1AP Setup Failure for transac_id %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); } From 60ca77f83fdb5b63e54aacf44661ffef661c31b7 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 10 Jan 2024 19:45:44 +0100 Subject: [PATCH 03/13] Enhancement of E1 and F1 documentation - improved description of F1 and E1 operation on a local setup --- doc/E1-design.md | 24 +++++++++++++++++++++--- doc/F1-design.md | 12 ++++++------ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/doc/E1-design.md b/doc/E1-design.md index 4184c946ea..334ddeea52 100644 --- a/doc/E1-design.md +++ b/doc/E1-design.md @@ -53,11 +53,29 @@ The files that implement the callback towards these handlers are in # 2. Running the E1 Split +The setup is assuming that all modules are running on the same machine. The user can refer to the [F1 design document](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/F1-design.md) for the mutual configuration of DU and the E1 CUCP-CUUP 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 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. +The gNB is started based on the node type that is specified in the configuration file. The following parameters must be configured accordingly. -For CUCP, a typical `E1_INTERFACE` config looks like +On either CUCP and CUUP: +* The southbound transport preference `gNBs.[0].tr_s_preference` set to `f1` +* config section `E1_INTERFACE` should be present + +On the CU-CP: +* `type` parameter within the `E1_INTERFACE` should be set to `cp` + +On the CU-UP: +* `type` parameter within the `E1_INTERFACE` should be set to `up` + +Executables: +* executable `nr-softmodem` to run a CU-CP +* executable `nr-cuup` to run the CU-UP + +In the `E1_INTERFACE` configuration section, the parameters `ipv4_cucp` and `ipv4_cuup` must be configured to specify the IP addresses of the respective network functions. + +For CUCP, a typical `E1_INTERFACE` config looks like: ``` E1_INTERFACE = ( @@ -82,7 +100,7 @@ E1_INTERFACE = ``` One could take an existing CU configuration file and add the above parameters to run the gNB as CUCP or CUUP. -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. +The CUUP uses the IP address specified in `gNBs.[0].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.f1.conf` and `ci-scripts/conf_files/gnb-cuup.sa.f1.conf`. diff --git a/doc/F1-design.md b/doc/F1-design.md index ee45128ebb..115ad916d2 100644 --- a/doc/F1-design.md +++ b/doc/F1-design.md @@ -20,15 +20,15 @@ The F1 interface is the functional split of 3GPP between the CU (centralized unit: PDCP, RRC, SDAP) and the DU (distributed unit: RLC, MAC, PHY). It is standardized in TS 38.470 - 38.473 for 5G NR. No equivalent for 4G exists. -We assume that each DU handles only one cell. Multiple DUs connected to one CU +We assume that each DU handles only one cell. Multiple DUs connected to one CU are supported. Mobility over F1 is not yet supported. # Control plane status (F1-C) ## Implementation Status -Note that OAI uses F1 "internally". That means, that even if you run a -monolithic gNB, the internal information exchange uses F1. You can therefore +Note that OAI uses F1 "internally". That means, that even **if you run a +monolithic gNB, the internal information exchange uses F1**. You can therefore expect that everything working in a monolithic deployment should also work in F1. The current implementation is based on R16.3. @@ -118,13 +118,13 @@ see [this `docker-compose` file](../ci-scripts/yaml_files/5g_f1_rfsimulator/dock The rules to decide if a config triggers a start of a DU, CU, or monolithic gNB, are, in order: -1. If the `MACRLCs` section lists `f1` as northbound transport preference +1. If the `MACRLCs` section lists `f1` as **northbound transport preference** (`tr_n_preference`), it is a DU. -2. If the `gNBs` section lists `f1` as a southound transport preference +2. If the `gNBs` section lists `f1` as a **southound transport preference** (`tr_s_preference`), it is a CU. 3. It is a (monolithic) gNB. -## Configuration of F1 IP/port information +## Local network deployment of F1 For a local deployment, you should update the following fields. We assume that the CU will bind on `192.168.70.129` towards the core, From b9bfff332761b367c842a10964b97536b977f3ca Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 10 Jan 2024 19:53:11 +0100 Subject: [PATCH 04/13] Minor improvements to E1 procedures readability --- executables/nr-softmodem.c | 2 +- openair2/COMMON/e1ap_messages_def.h | 6 +++--- openair2/E1AP/e1ap.c | 16 ++++++++++++++++ openair2/GNB_APP/gnb_app.c | 2 +- openair2/RRC/NR/rrc_gNB.c | 9 +++++++++ openair2/RRC/NR/rrc_gNB_cuup.c | 3 +++ 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index ad24e55755..2a8ebabef2 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -400,7 +400,7 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf } } - // If CU + // E1AP initialisation, whether the node is a CU or has integrated CU if (node_type == ngran_gNB_CU || node_type == ngran_gNB) { MessageDef *msg = RCconfig_NR_CU_E1(NULL); instance_t inst = 0; diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h index 6da8e85ee1..fd39731df1 100644 --- a/openair2/COMMON/e1ap_messages_def.h +++ b/openair2/COMMON/e1ap_messages_def.h @@ -22,10 +22,10 @@ /* 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) */ +/* E1AP Interface Management Messages */ +/* E1AP Setup Request: gNB-CU-UP -> gNB-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 */ +/* E1AP Setup Response: gNB-CU-CP -> gNB-CU-UP */ 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) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index baeb690440..662a3af6e1 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1860,6 +1860,14 @@ void e1apHandleTimer(instance_t myInstance) e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, &getCxtE1(myInstance)->net_config); } +/** + * @brief E1AP Centralized Unit Control Plane (CU-CP) task function. + * + * This is the main task loop for the E1AP CUCP module: + * it listens for incoming messages from the Inter-Task Interface (ITTI) + * and calls the relevant handlers for each message type. + * + */ void *E1AP_CUCP_task(void *arg) { LOG_I(E1AP, "Starting E1AP at CU CP\n"); MessageDef *msg = NULL; @@ -1931,6 +1939,14 @@ void *E1AP_CUCP_task(void *arg) { } } +/** + * @brief E1AP Centralized Unit User Plane (CU-UP) task function. + * + * This is the main task loop for the E1AP CUUP module: + * it listens for incoming messages from the Inter-Task Interface (ITTI) + * and calls the relevant handlers for each message type. + * + */ void *E1AP_CUUP_task(void *arg) { LOG_I(E1AP, "Starting E1AP at CU UP\n"); e1ap_common_init(); diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index e2c0b48bd4..081508958b 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -148,7 +148,7 @@ void *gNB_app_task(void *args_p) AssertFatal(false, "Create task for E1AP CP failed\n"); E1_t e1type = CPtype; MessageDef *msg = RCconfig_NR_CU_E1(&e1type); - AssertFatal(msg != NULL, "Send inti to task for E1AP CP failed\n"); + AssertFatal(msg != NULL, "Send itti 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); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 48f59fcb51..f6486c0032 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2065,6 +2065,9 @@ static pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi, return NULL; } +/** + * @brief E1AP Bearer Context Setup Response processing +*/ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { gNB_RRC_INST *rrc = RC.nrrrc[0]; @@ -2172,6 +2175,9 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req); } +/** + * @brief E1AP Bearer Context Modification Response processing +*/ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t *resp) { gNB_RRC_INST *rrc = RC.nrrrc[0]; @@ -2188,6 +2194,9 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t } } +/** + * @brief E1AP Bearer Context Release processing +*/ 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 diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index 75003b05eb..4ed1886e75 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -134,6 +134,9 @@ static void e1ap_setup_failure(sctp_assoc_t assoc_id, uint64_t transac_id) itti_send_msg_to_task(TASK_CUCP_E1, 0 /*unused by callee*/, msg_p); } +/** + * @brief E1AP Setup Request processing on CU-CP +*/ 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"); From 45ca753b24ea8169d7d6dbb9fcc9040dde73adc5 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 12 Jan 2024 11:01:19 +0100 Subject: [PATCH 05/13] Handling E1 connection loss on CU-CP - it triggers the RRC callback after SCTP SHUTDOWN indication - CUUP entity cleanup at RRC level --- openair2/COMMON/e1ap_messages_def.h | 3 +++ openair2/COMMON/e1ap_messages_types.h | 7 +++++++ openair2/E1AP/e1ap.c | 10 ++++++++++ openair2/RRC/NR/nr_rrc_proto.h | 3 +++ openair2/RRC/NR/rrc_gNB.c | 4 ++++ openair2/RRC/NR/rrc_gNB_cuup.c | 25 +++++++++++++++++++++++++ 6 files changed, 52 insertions(+) diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h index fd39731df1..7c81334e68 100644 --- a/openair2/COMMON/e1ap_messages_def.h +++ b/openair2/COMMON/e1ap_messages_def.h @@ -22,6 +22,9 @@ /* gNB_CUUP application layer -> E1AP messages */ MESSAGE_DEF(E1AP_REGISTER_REQ, MESSAGE_PRIORITY_MED, e1ap_register_req_t, e1ap_register_req) +/* E1AP -> RRC to inform about lost connection */ +MESSAGE_DEF(E1AP_LOST_CONNECTION, MESSAGE_PRIORITY_MED, e1ap_lost_connection_t, e1ap_lost_connection) + /* E1AP Interface Management Messages */ /* E1AP Setup Request: gNB-CU-UP -> gNB-CU-CP */ MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_setup_req) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 605441e5f7..43d63924e0 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -51,6 +51,7 @@ #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 +#define E1AP_LOST_CONNECTION(mSGpTR) (mSGpTR)->ittiMsg.e1ap_lost_connection typedef net_ip_address_t e1ap_net_ip_address_t; @@ -279,4 +280,10 @@ typedef struct e1ap_bearer_modif_resp_s { pdu_session_modif_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS]; } e1ap_bearer_modif_resp_t; +/* E1AP Connection Loss indication */ +typedef struct e1ap_lost_connection_t { + int dummy; +} e1ap_lost_connection_t; + + #endif /* E1AP_MESSAGES_TYPES_H */ diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 662a3af6e1..6ceb6b8b6c 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1774,6 +1774,16 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, { DevAssert(sctp_new_association_resp != NULL); getCxtE1(instance)->sockState = sctp_new_association_resp->sctp_state; + + if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN) { + LOG_I(E1AP, "Received SCTP shutdown for assoc_id %d, removing CUCP endpoint\n", sctp_new_association_resp->assoc_id); + /* inform RRC that the CU-UP is gone */ + MessageDef *message_p = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_LOST_CONNECTION); + message_p->ittiMsgHeader.originInstance = sctp_new_association_resp->assoc_id; + itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); + return; + } + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { LOG_W(E1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index a1342a33f9..45cb2d3439 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -129,6 +129,9 @@ sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_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); +/* Process indication of E1 connection loss on CU-CP */ +void rrc_gNB_process_e1_lost_connection(gNB_RRC_INST *rrc, e1ap_lost_connection_t *lc, sctp_assoc_t assoc_id); + 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 f6486c0032..6388665b74 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2476,6 +2476,10 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_e1_bearer_context_release_cplt(&E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg_p)); break; + case E1AP_LOST_CONNECTION: /* CUCP */ + rrc_gNB_process_e1_lost_connection(RC.nrrrc[0], &E1AP_LOST_CONNECTION(msg_p), msg_p->ittiMsgHeader.originInstance); + break; + case NGAP_PAGING_IND: rrc_gNB_process_PAGING_IND(msg_p, instance); break; diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index 4ed1886e75..9c4aa05dc0 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -189,3 +189,28 @@ int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req) return 0; } + +/** + * @brief RRC Processing of the indication of E1 connection loss on CU-CP +*/ +void rrc_gNB_process_e1_lost_connection(gNB_RRC_INST *rrc, e1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) +{ + LOG_I(NR_RRC, "Received E1 connection loss indication on RRC\n"); + AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n"); + nr_rrc_cuup_container_t e = {.assoc_id = assoc_id}; + nr_rrc_cuup_container_t *cuup = RB_FIND(rrc_cuup_tree, &rrc->cuups, &e); + if (cuup == NULL) { + LOG_W(NR_RRC, "CU-UP for assoc_id %d not found!\n", assoc_id); + return; + } + if (cuup->setup_req != NULL) { + e1ap_setup_req_t *req = cuup->setup_req; + LOG_I(NR_RRC, "releasing CU-UP %s on assoc_id %d\n", req->gNB_cu_up_name, assoc_id); + free(cuup->setup_req); + } + nr_rrc_cuup_container_t *removed = RB_REMOVE(rrc_cuup_tree, &rrc->cuups, cuup); + // Free relevant CU-UP structures + free(cuup); + DevAssert(removed != NULL); + rrc->num_cuups--; +} From 6fca568091afd1b0a62ceadcfc6465276f438b3e Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 12 Jan 2024 11:03:30 +0100 Subject: [PATCH 06/13] Minor improvements to code comments --- openair2/COMMON/e1ap_messages_def.h | 10 +++++++--- openair2/E1AP/e1ap.c | 4 ++++ openair2/RRC/NR/rrc_gNB.c | 4 ++-- openair2/RRC/NR/rrc_gNB_cuup.c | 5 +++++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h index 7c81334e68..df72a99f7f 100644 --- a/openair2/COMMON/e1ap_messages_def.h +++ b/openair2/COMMON/e1ap_messages_def.h @@ -33,12 +33,16 @@ MESSAGE_DEF(E1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, e1ap_setup_resp_t , e1ap_set /* E1AP Setup Failure: gNB-CU-CP -> gNB-CU-UP */ MESSAGE_DEF(E1AP_SETUP_FAIL, MESSAGE_PRIORITY_MED, e1ap_setup_fail_t, e1ap_setup_fail) +/* E1AP Bearer Context Management Procedures */ +/* E1AP Bearer Context Setup Request: gNB-CU-CP -> gNB-CU-UP */ MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_setup_req) - +/* E1AP Bearer Context Setup Response: gNB-CU-UP -> gNB-CU-CP */ MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_RESP , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_resp_t , e1ap_bearer_setup_resp) - +/* E1AP Bearer Context Modification Request: gNB-CU-CP -> gNB-CU-UP */ MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_mod_req) +/* E1AP Bearer Context Modification Response: gNB-CU-UP -> gNB-CU-CP */ MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, e1ap_bearer_modif_resp_t, e1ap_bearer_modif_resp) - +/* E1AP Bearer Context Release Request: gNB-CU-CP -> gNB-CU-UP */ MESSAGE_DEF(E1AP_BEARER_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, e1ap_bearer_release_cmd_t, e1ap_bearer_release_cmd) +/* E1AP Bearer Context Release Response: gNB-CU-UP -> gNB-CU-CP */ MESSAGE_DEF(E1AP_BEARER_CONTEXT_RELEASE_CPLT, MESSAGE_PRIORITY_MED, e1ap_bearer_release_cplt_t, e1ap_bearer_release_cplt) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 6ceb6b8b6c..975330be78 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -36,6 +36,10 @@ #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); + +/** + * @brief E1AP messages handlers +*/ const e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3] = { {0, 0, 0}, /* Reset */ diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 6388665b74..7c3c200f15 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2066,7 +2066,7 @@ static pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi, } /** - * @brief E1AP Bearer Context Setup Response processing + * @brief E1AP Bearer Context Setup Response processing on CU-CP */ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { @@ -2176,7 +2176,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp } /** - * @brief E1AP Bearer Context Modification Response processing + * @brief E1AP Bearer Context Modification Response processing on CU-CP */ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t *resp) { diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index 9c4aa05dc0..6751739cac 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -122,6 +122,11 @@ 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; } +/* CU-CP Functions */ + +/** + * @brief Trigger E1AP Setup Failure on CU-CP +*/ 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); From 374b6d8ab4d8ed0a3613839afdaee38a36faa075 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 12 Jan 2024 11:15:03 +0100 Subject: [PATCH 07/13] Set E1AP functions with local scope as static --- openair2/E1AP/e1ap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 975330be78..fb89344f82 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -73,7 +73,7 @@ const char *const e1ap_direction2String(int e1ap_dir) return(e1ap_direction_String[e1ap_dir]); } -int e1ap_handle_message(instance_t instance, sctp_assoc_t assoc_id, const uint8_t *const data, const uint32_t data_length) +static int e1ap_handle_message(instance_t instance, sctp_assoc_t assoc_id, const uint8_t *const data, const uint32_t data_length) { E1AP_E1AP_PDU_t pdu= {0}; int ret; @@ -105,7 +105,7 @@ int e1ap_handle_message(instance_t instance, sctp_assoc_t assoc_id, const uint8_ return ret; } -void e1_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) +static void e1_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { int result; DevAssert(sctp_data_ind != NULL); @@ -310,8 +310,9 @@ void e1apCUCP_send_SETUP_FAILURE(sctp_assoc_t assoc_id, long transac_id) e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } -void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, - e1ap_setup_req_t *req) { +static 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; From 763726185a084884cf42d2321d88dccc3260317b Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 12 Jan 2024 14:52:14 +0100 Subject: [PATCH 08/13] Added documentation about sanitizers - new file: /doc/dev_tools/sanitizers.md --- doc/BUILD.md | 2 ++ doc/README.md | 1 + doc/dev_tools/sanitizers.md | 63 +++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 doc/dev_tools/sanitizers.md diff --git a/doc/BUILD.md b/doc/BUILD.md index 87b6dcca89..1cc9a688c5 100644 --- a/doc/BUILD.md +++ b/doc/BUILD.md @@ -63,6 +63,8 @@ Calling the `build_oai` script with the `-h` option gives the list of all availa - `--ninja` is to use the `ninja` build tool, which speeds up compilation. - `-c` is to clean the workspace and force a complete rebuild. +`build_oai` also provides various options to enable runtime error checkers, i.e. sanitizers in order to find various types of bugs in the codebase and eventually enhance the stability of the OAI softmodems. Refer to [sanitizers.md](./dev_tools/sanitizers.md) for more details. + ## Installing dependencies Install all dependencies by issuing the `-I` option. To install furthermore libraries for optional libraries, use the `--install-optional-packages` option. The `-I` option will also install dependencies for an SDR when paired with `-w`. For instance, in order to install all dependencies and the ones for USRP, run: diff --git a/doc/README.md b/doc/README.md index 0f52a0b8ff..b634bd0315 100644 --- a/doc/README.md +++ b/doc/README.md @@ -21,6 +21,7 @@ - [BUILD.md](./BUILD.md): how to build the sources - [cross-compile.md](./cross-compile.md): how to cross-compile OAI for ARM - [clang-format.md](./clang-format.md): how to format the code +- [sanitizers.md](./dev_tools/sanitizers.md): how to run with ASan/UBSan/MemSAN/TSan - [environment-variables.md](./environment-variables.md): the environment variables used by OAI There is some general information in the [OpenAirInterface Gitlab Wiki](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/home) diff --git a/doc/dev_tools/sanitizers.md b/doc/dev_tools/sanitizers.md new file mode 100644 index 0000000000..6e6376ee08 --- /dev/null +++ b/doc/dev_tools/sanitizers.md @@ -0,0 +1,63 @@ + + + + + +
+ + + + + + OAI Build Procedures +
+ +[[_TOC_]] + +# Sanitize options in `build_oai` + +The `build_oai` script provides various [Instrumentation Options](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html) to add run-time instrumentation to the code and enable runtime error checkers, i.e. sanitizers, in order to help find various types of bugs in the codebase and eventually enhance the stability of the OAI softmodems. The following sanitizers can be enabled using different build options: + +## Address Sanitizer (ASAN) +[Address Sanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) is enabled using the `--sanitize-address` option or its shorthand `-fsanitize=address`. It serves as a fast memory error detector and helps detect issues like out-of-bounds accesses, use-after-free bugs, and memory leaks. + +### Run OAI Softmodem with ASAN on + +It is necessary to add the envinronment variable `LD_LIBRARY_PATH` to the run command, e.g.: +``` +cd cmake_targets/ran_build/build +sudo LD_LIBRARY_PATH=. ./nr-softmodem ... +``` + +## Undefined Behavior Sanitizer (UBSAN) +[Undefined Behavior Sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) (UBSAN) is a runtime undefined behavior checker. It uses compile-time instrumentation to catch undefined behavior by inserting code that performs specific checks before operations that may cause it. UBSAN can be activated with the `--sanitize-undefined` option or `-fsanitize=undefined`. + +UBSAN offers a range of suboptions that enable precise checks for various types of undefined behavior at runtime. These suboptions can be set by tweaking the [CMakeLists.txt](../../CMakeLists.txt) file. Here is an overview of some key suboptions: + +* `-fsanitize=shift`: Enables checks for the result of shift operations, with suboptions for base and exponent. +* `-fsanitize=integer-divide-by-zero`: Detects integer division by zero. +* `-fsanitize=null`: Enables pointer checking, issuing an error message when dereferencing a NULL pointer or binding a reference to a NULL pointer. +* `-fsanitize=signed-integer-overflow`: Detects signed integer overflow. +* `-fsanitize=bounds`: Instruments array bounds, detecting various out-of-bounds accesses. +* `-fsanitize=alignment`: Checks the alignment of pointers when dereferenced or when a reference is bound to an insufficiently aligned target. +* `-fsanitize=object-size`: Checks out-of-bounds pointer accesses. +* `-fsanitize=float-divide-by-zero`: Detects floating-point division by zero. + +## Memory Sanitizer +To enable [Memory Sanitizer](https://clang.llvm.org/docs/MemorySanitizer.html), use the `--sanitize-memory` option or `-fsanitize=memory`. It requires clang and is incompatible with ASAN and UBSAN. Building with this option helps catch issues related to uninitialized memory reads. + +To build with Memory Sanitizer, use the following command: +``` +CC=/usr/bin/clang CXX=/usr/bin/clang++ ./build_oai ... --sanitize-memory +``` + +## Thread Sanitizer +[Thread Sanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html) can be activated using the `--sanitize-thread` option or `-fsanitize=thread`. This sanitizer helps identify data races and other threading-related issues in the code. + +# Summary of Sanitizer Options + +- `--sanitize`: Shortcut for using both ASAN and UBSAN. +- `--sanitize-address` or `-fsanitize=address`: Enable ASAN on all targets. +- `--sanitize-undefined` or `-fsanitize=undefined`: Enable UBSAN on all targets. +- `--sanitize-memory` or `-fsanitize=memory`: Enable Memory Sanitizer on all targets (requires clang). +- `--sanitize-thread` or `-fsanitize=thread`: Enable Thread Sanitizer on all targets. From 4f4cb4757c244157e21d21c87fa178e0b5ccb09e Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 12 Jan 2024 16:32:34 +0100 Subject: [PATCH 09/13] Extended E1 design documentation - provided insights on the messages flow with requests towards northbound --- doc/E1-design.md | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/doc/E1-design.md b/doc/E1-design.md index 334ddeea52..e80c431029 100644 --- a/doc/E1-design.md +++ b/doc/E1-design.md @@ -45,11 +45,37 @@ sequenceDiagram Note over c: Execute rrc_gNB_process_e1_bearer_context_release_cplt() ``` -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) +The implementation of callbacks towards these handlers is distributed across the following file, depending on the operating mode: + +| Mode | CP=>UP messages |UP=>CP messages | +| --------------| --------------------|--------------------| +| Integrated CU | `cucp_cuup_direct.c`|`cuup_cucp_direct.c`| +| E1 Split | `cucp_cuup_e1ap.c` |`cuup_cucp_e1ap.c` | + +As long as concerns E1 Interface Management Procedures, the code flow of request messages towards northbound looks like this: + +```mermaid +sequenceDiagram + participant r as RRC + participant c as CUCP + participant u as CUUP + + Note over u: E1AP_CUUP_task (SCTP Handler) + Note over u: ASN1 encoder + u->>c: e.g. E1 Setup Request (SCTP) + Note over c: E1AP_CUCP_task (SCTP Handler) + Note over c: ASN1 decoder + c->>r: E1AP_SETUP_REQ (ITTI) + Note over r: TASK_RRC_GNB (RRC Handler) + r->>c: E1AP_SETUP_RESP (ITTI) + Note over c: E1AP_CUCP_task (E1AP Callback) + Note over c: ASN1 encoder + + c->>u: e.g. E1 Setup Response/Failure + Note over u: E1AP_CUUP_task (SCTP Handler) + Note over u: ASN1 decoder +``` + # 2. Running the E1 Split From 309673f5197188a2b3fcde175254cb7b6d8abe94 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 24 Jan 2024 11:10:52 +0100 Subject: [PATCH 10/13] Minor fixes to documentation and logging --- doc/E1-design.md | 4 ++-- openair2/GNB_APP/gnb_app.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/E1-design.md b/doc/E1-design.md index e80c431029..6939e3867e 100644 --- a/doc/E1-design.md +++ b/doc/E1-design.md @@ -79,7 +79,7 @@ sequenceDiagram # 2. Running the E1 Split -The setup is assuming that all modules are running on the same machine. The user can refer to the [F1 design document](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/F1-design.md) for the mutual configuration of DU and the E1 CUCP-CUUP split. +The setup is assuming that all modules are running on the same machine. The user can refer to the [F1 design document](./F1-design.md) for local deployment of the DU. ## 2.1 Configuration File @@ -113,7 +113,7 @@ E1_INTERFACE = ) ``` -For CUUP, it is +For CUUP, it is: ``` E1_INTERFACE = ( diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 081508958b..39946c95f1 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -148,7 +148,7 @@ void *gNB_app_task(void *args_p) AssertFatal(false, "Create task for E1AP CP failed\n"); E1_t e1type = CPtype; MessageDef *msg = RCconfig_NR_CU_E1(&e1type); - AssertFatal(msg != NULL, "Send itti to task for E1AP CP failed\n"); + AssertFatal(msg != NULL, "Send ITTI 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); From d5753a6bba9a9c044545ecb493c3677154f25e80 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 24 Jan 2024 13:17:17 +0100 Subject: [PATCH 11/13] Partial formatting of e1ap.c with clang-format --- openair2/E1AP/e1ap.c | 383 +++++++++++++++++++++++-------------------- 1 file changed, 203 insertions(+), 180 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index fb89344f82..79581698d9 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -39,7 +39,7 @@ typedef int (*e1ap_message_processing_t)(sctp_assoc_t assoc_id, e1ap_upcp_inst_t /** * @brief E1AP messages handlers -*/ + */ const e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3] = { {0, 0, 0}, /* Reset */ @@ -65,17 +65,17 @@ const e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3 const char *const e1ap_direction2String(int e1ap_dir) { static const char *e1ap_direction_String[] = { - "", /* Nothing */ - "Initiating message", /* initiating message */ - "Successfull outcome", /* successfull outcome */ - "UnSuccessfull outcome", /* successfull outcome */ + "", /* Nothing */ + "Initiating message", /* initiating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ }; - return(e1ap_direction_String[e1ap_dir]); + return (e1ap_direction_String[e1ap_dir]); } static int e1ap_handle_message(instance_t instance, sctp_assoc_t assoc_id, const uint8_t *const data, const uint32_t data_length) { - E1AP_E1AP_PDU_t pdu= {0}; + E1AP_E1AP_PDU_t pdu = {0}; int ret; DevAssert(data != NULL); @@ -85,19 +85,25 @@ static int e1ap_handle_message(instance_t instance, sctp_assoc_t assoc_id, const } const E1AP_ProcedureCode_t procedureCode = pdu.choice.initiatingMessage->procedureCode; /* Checking procedure Code and direction of message */ - if ((procedureCode >= E1AP_NUM_MSG_HANDLERS) || (pdu.present > E1AP_E1AP_PDU_PR_unsuccessfulOutcome) || (pdu.present <= E1AP_E1AP_PDU_PR_NOTHING)) { + if ((procedureCode >= E1AP_NUM_MSG_HANDLERS) || (pdu.present > E1AP_E1AP_PDU_PR_unsuccessfulOutcome) + || (pdu.present <= E1AP_E1AP_PDU_PR_NOTHING)) { LOG_E(E1AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", assoc_id, procedureCode, pdu.present); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_E1AP_E1AP_PDU, &pdu); return -1; } if (e1ap_message_processing[procedureCode][pdu.present - 1] == NULL) { - // No handler present. This can mean not implemented or no procedure for eNB (wrong direction). - LOG_E(E1AP, "[SCTP %d] No handler for procedureCode %ld in %s\n", assoc_id, procedureCode, e1ap_direction2String(pdu.present - 1)); - ret=-1; + // No handler present. This can mean not implemented or no procedure for eNB + // (wrong direction). + LOG_E(E1AP, + "[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, + procedureCode, + e1ap_direction2String(pdu.present - 1)); + ret = -1; } else { /* Calling the right handler */ - LOG_D(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])(assoc_id, getCxtE1(instance), &pdu); } @@ -109,33 +115,33 @@ static void e1_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *s { int result; DevAssert(sctp_data_ind != NULL); - e1ap_handle_message(instance, sctp_data_ind->assoc_id, - sctp_data_ind->buffer, sctp_data_ind->buffer_length); + e1ap_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->buffer, sctp_data_ind->buffer_length); result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } 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}; + AssertFatal(false, "Not implemented yet\n"); + E1AP_E1AP_PDU_t pdu = {0}; return e1ap_encode_send(isCu, assoc_id, &pdu, 0, __func__); } -int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset) { - AssertFatal(false,"Not implemented yet\n"); +int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } int e1ap_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } int e1ap_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } @@ -144,16 +150,16 @@ int e1ap_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, ui */ int e1ap_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } -int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *ErrorIndication) { - AssertFatal(false,"Not implemented yet\n"); +int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *ErrorIndication) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } - /* E1 Setup: can be sent on both ways, to be refined */ @@ -211,7 +217,7 @@ static void fill_SETUP_REQUEST(e1ap_setup_req_t *setup, E1AP_E1AP_PDU_t *pdu) int numSupportedPLMNs = setup->supported_plmns; - for (int i=0; i < numSupportedPLMNs; i++) { + for (int i = 0; i < numSupportedPLMNs; i++) { asn1cSequenceAdd(ieC5->value.choice.SupportedPLMNs_List.list, E1AP_SupportedPLMNs_Item_t, supportedPLMN); /* 5.1 PLMN Identity */ PLMN_ID_t *id = &setup->plmn[i].id; @@ -264,7 +270,7 @@ void e1ap_send_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1ap_setup_resp_t *e1 /** * @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 */ @@ -301,7 +307,7 @@ static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu) /** * @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); @@ -310,27 +316,23 @@ void e1apCUCP_send_SETUP_FAILURE(sctp_assoc_t assoc_id, long transac_id) e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } -static void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, - e1ap_setup_req_t *req) +static 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; /* transac_id */ - F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, - E1AP_ProtocolIE_ID_id_TransactionID, true); + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_TransactionID, true); req->transac_id = ie->value.choice.TransactionID; LOG_D(E1AP, "gNB CU UP E1 setup request transaction ID: %ld\n", req->transac_id); /* gNB CU UP ID */ - F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, - E1AP_ProtocolIE_ID_id_gNB_CU_UP_ID, true); + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_gNB_CU_UP_ID, true); 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); + 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)); @@ -340,18 +342,17 @@ static 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); + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_CNSupport, true); 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, - E1AP_ProtocolIE_ID_id_SupportedPLMNs, true); + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_SupportedPLMNs, true); req->supported_plmns = ie->value.choice.SupportedPLMNs_List.list.count; LOG_D(E1AP, "Number of supported PLMNs: %d\n", req->supported_plmns); - for (int i=0; i < req->supported_plmns; i++) { - E1AP_SupportedPLMNs_Item_t *supported_plmn_item = (E1AP_SupportedPLMNs_Item_t *)(ie->value.choice.SupportedPLMNs_List.list.array[i]); + for (int i = 0; i < req->supported_plmns; i++) { + E1AP_SupportedPLMNs_Item_t *supported_plmn_item = + (E1AP_SupportedPLMNs_Item_t *)(ie->value.choice.SupportedPLMNs_List.list.array[i]); /* PLMN Identity */ PLMN_ID_t *id = &req->plmn[i].id; @@ -409,8 +410,7 @@ int e1apCUUP_handle_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst /* transac_id */ long transaction_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); + 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; LOG_D(E1AP, "gNB CU UP E1 setup response transaction ID: %ld\n", transaction_id); @@ -426,7 +426,7 @@ int e1apCUUP_handle_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst /** * @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"); @@ -434,8 +434,7 @@ int e1apCUUP_handle_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, 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); + 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; @@ -444,8 +443,7 @@ int e1apCUUP_handle_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, 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); + 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); @@ -478,7 +476,7 @@ static void fill_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu) int numSupportedPLMNs = 1; - for (int i=0; i < numSupportedPLMNs; i++) { + for (int i = 0; i < numSupportedPLMNs; i++) { asn1cSequenceAdd(ieC2->value.choice.SupportedPLMNs_List.list, E1AP_SupportedPLMNs_Item_t, supportedPLMN); /* 5.1 PLMN Identity */ OCTET_STRING_fromBuf(&supportedPLMN->pLMN_Identity, "OAI", strlen("OAI")); @@ -493,7 +491,7 @@ static void fill_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu) int numTNLAtoRemoveList = 1; - for (int i=0; i < numTNLAtoRemoveList; i++) { + for (int i = 0; i < numTNLAtoRemoveList; i++) { asn1cSequenceAdd(ieC2->value.choice.GNB_CU_UP_TNLA_To_Remove_List.list, E1AP_GNB_CU_UP_TNLA_To_Remove_Item_t, TNLAtoRemove); TNLAtoRemove->tNLAssociationTransportLayerAddress.present = E1AP_CP_TNL_Information_PR_endpoint_IP_Address; TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &TNLAtoRemove->tNLAssociationTransportLayerAddress.choice.endpoint_IP_Address); // TODO: correct me @@ -513,13 +511,13 @@ void e1apCUUP_send_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id) int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(void) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(void) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } @@ -531,23 +529,19 @@ int e1apCUCP_handle_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu) E1AP_GNB_CU_UP_E1SetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.GNB_CU_UP_E1SetupRequest; */ - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } -int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) +int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } -int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id, - uint32_t stream, - E1AP_E1AP_PDU_t *pdu) +int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } @@ -555,25 +549,27 @@ int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id, E1 release */ -int e1ap_send_RELEASE_REQUEST(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1ap_send_RELEASE_REQUEST(instance_t instance) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } -int e1ap_send_RELEASE_ACKNOWLEDGE(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1ap_send_RELEASE_ACKNOWLEDGE(instance_t instance) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } int e1ap_handle_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } int e1ap_handle_RELEASE_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } @@ -645,7 +641,7 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear msgNGRAN->criticality = E1AP_Criticality_reject; msgNGRAN->value.present = E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List; E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2Setup = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List; - for(pdu_session_to_setup_t *i=bearerCxt->pduSession; i < bearerCxt->pduSession+bearerCxt->numPDUSessions; i++) { + for (pdu_session_to_setup_t *i = bearerCxt->pduSession; i < bearerCxt->pduSession + bearerCxt->numPDUSessions; i++) { asn1cSequenceAdd(pdu2Setup->list, E1AP_PDU_Session_Resource_To_Setup_Item_t, ieC6_1); ieC6_1->pDU_Session_ID = i->sessionId; ieC6_1->pDU_Session_Type = i->sessionType; @@ -665,7 +661,7 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress); INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID); - for (DRB_nGRAN_to_setup_t *j=i->DRBnGRanList; j < i->DRBnGRanList+i->numDRB2Setup; j++) { + for (DRB_nGRAN_to_setup_t *j = i->DRBnGRanList; j < i->DRBnGRanList + i->numDRB2Setup; j++) { asn1cSequenceAdd(ieC6_1->dRB_To_Setup_List_NG_RAN.list, E1AP_DRB_To_Setup_Item_NG_RAN_t, ieC6_1_1); ieC6_1_1->dRB_ID = j->id; @@ -681,12 +677,12 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear roTimer->t_Reordering = j->reorderingTimer; ieC6_1_1->pDCP_Configuration.rLC_Mode = j->rLC_Mode; - for (cell_group_t *k=j->cellGroupList; k < j->cellGroupList+j->numCellGroups; k++) { + for (cell_group_t *k = j->cellGroupList; k < j->cellGroupList + j->numCellGroups; k++) { asn1cSequenceAdd(ieC6_1_1->cell_Group_Information.list, E1AP_Cell_Group_Information_Item_t, ieC6_1_1_1); ieC6_1_1_1->cell_Group_ID = k->id; } - for (qos_flow_to_setup_t *k=j->qosFlows; k < j->qosFlows+j->numQosFlow2Setup; k++) { + for (qos_flow_to_setup_t *k = j->qosFlows; k < j->qosFlows + j->numQosFlow2Setup; k++) { asn1cSequenceAdd(ieC6_1_1->qos_flow_Information_To_Be_Setup, E1AP_QoS_Flow_QoS_Parameter_Item_t, ieC6_1_1_1); ieC6_1_1_1->qoS_Flow_Identifier = k->qfi; @@ -730,66 +726,78 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(const e1ap_bearer_setup_resp_t *r pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome; asn1cCalloc(pdu->choice.successfulOutcome, msg); msg->procedureCode = E1AP_ProcedureCode_id_bearerContextSetup; - msg->criticality = E1AP_Criticality_reject; + msg->criticality = E1AP_Criticality_reject; msg->value.present = E1AP_SuccessfulOutcome__value_PR_BearerContextSetupResponse; E1AP_BearerContextSetupResponse_t *out = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse; /* mandatory */ /* c1. gNB-CU-CP UE E1AP ID */ asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC1); - ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID; - ieC1->criticality = E1AP_Criticality_reject; - ieC1->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID; + ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID; ieC1->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_BearerContextSetupResponseIEs_t, ieC2); - ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; - ieC2->criticality = E1AP_Criticality_reject; - ieC2->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; + ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; + ieC2->criticality = E1AP_Criticality_reject; + ieC2->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; ieC2->value.choice.GNB_CU_CP_UE_E1AP_ID = resp->gNB_cu_up_ue_id; asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC3); - ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse; - ieC3->criticality = E1AP_Criticality_reject; + 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 - 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; - asn1cSequenceAdd(msgEUTRAN_list->list, E1AP_EUTRAN_BearerContextSetupResponse_t, msgEUTRAN); - msgEUTRAN->id = E1AP_ProtocolIE_ID_id_DRB_Setup_List_EUTRAN; - msgEUTRAN->criticality = E1AP_Criticality_reject; - msgEUTRAN->value.present = E1AP_EUTRAN_BearerContextSetupResponse__value_PR_DRB_Setup_List_EUTRAN; - E1AP_DRB_Setup_List_EUTRAN_t *drbSetup = &msgEUTRAN->value.choice.DRB_Setup_List_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; + asn1cSequenceAdd(msgEUTRAN_list->list, + E1AP_EUTRAN_BearerContextSetupResponse_t, msgEUTRAN); msgEUTRAN->id = + E1AP_ProtocolIE_ID_id_DRB_Setup_List_EUTRAN; msgEUTRAN->criticality = + E1AP_Criticality_reject; msgEUTRAN->value.present = + E1AP_EUTRAN_BearerContextSetupResponse__value_PR_DRB_Setup_List_EUTRAN; + E1AP_DRB_Setup_List_EUTRAN_t *drbSetup = + &msgEUTRAN->value.choice.DRB_Setup_List_EUTRAN; for (drb_setup_t *i=resp->DRBList; i < resp->DRBList+resp->numDRBs; i++) { asn1cSequenceAdd(drbSetup->list, E1AP_DRB_Setup_Item_EUTRAN_t, ieC3_1); ieC3_1->dRB_ID = i->drbId; - ieC3_1->s1_DL_UP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel; + ieC3_1->s1_DL_UP_TNL_Information.present = + E1AP_UP_TNL_Information_PR_gTPTunnel; asn1cCalloc(ieC3_1->s1_DL_UP_TNL_Information.choice.gTPTunnel, gTPTunnel); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress); - INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, + &gTPTunnel->transportLayerAddress); INT32_TO_OCTET_STRING(i->teId, + &gTPTunnel->gTP_TEID); - for (up_params_t *j=i->UpParamList; j < i->UpParamList+i->numUpParam; j++) { - asn1cSequenceAdd(ieC3_1->uL_UP_Transport_Parameters.list, E1AP_UP_Parameters_Item_t, ieC3_1_1); - ieC3_1_1->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel; + for (up_params_t *j=i->UpParamList; j < i->UpParamList+i->numUpParam; j++) + { asn1cSequenceAdd(ieC3_1->uL_UP_Transport_Parameters.list, + E1AP_UP_Parameters_Item_t, ieC3_1_1); ieC3_1_1->uP_TNL_Information.present = + E1AP_UP_TNL_Information_PR_gTPTunnel; asn1cCalloc(ieC3_1_1->uP_TNL_Information.choice.gTPTunnel, gTPTunnel); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(j->tlAddress, &gTPTunnel->transportLayerAddress); - INT32_TO_OCTET_STRING(j->teId, &gTPTunnel->gTP_TEID); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(j->tlAddress, + &gTPTunnel->transportLayerAddress); INT32_TO_OCTET_STRING(j->teId, + &gTPTunnel->gTP_TEID); } } - } else */{ - ieC3->value.choice.System_BearerContextSetupResponse.present = E1AP_System_BearerContextSetupResponse_PR_nG_RAN_BearerContextSetupResponse; + } 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; + ieC3->value.choice.System_BearerContextSetupResponse.choice.nG_RAN_BearerContextSetupResponse = + (struct E1AP_ProtocolIE_Container *)msgNGRAN_list; asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextSetupResponse_t, msgNGRAN); msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Setup_List; msgNGRAN->criticality = E1AP_Criticality_reject; 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 (const 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; @@ -798,11 +806,11 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(const e1ap_bearer_setup_resp_t *r TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress); INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID); - for (const 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 (const 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); @@ -810,7 +818,7 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(const e1ap_bearer_setup_resp_t *r INT32_TO_OCTET_STRING(k->teId, &gTPTunnel->gTP_TEID); } - for (const 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->qfi; } @@ -819,7 +827,7 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(const e1ap_bearer_setup_resp_t *r if (i->numDRBFailed > 0) ieC3_1->dRB_Failed_List_NG_RAN = calloc(1, sizeof(E1AP_DRB_Failed_List_NG_RAN_t)); - for (const 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; @@ -857,19 +865,20 @@ void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1 e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__); } -int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } -void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, - e1ap_bearer_setup_req_t *bearerCxt) { +void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_req_t *bearerCxt) +{ const E1AP_BearerContextSetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest; E1AP_BearerContextSetupRequestIEs_t *ie; 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++) { + for (int i = 0; i < in->protocolIEs.list.count; i++) { ie = in->protocolIEs.list.array[i]; switch(ie->id) { @@ -931,7 +940,7 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2SetupList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List; bearerCxt->numPDUSessions = pdu2SetupList->list.count; - for (int i=0; i < pdu2SetupList->list.count; i++) { + for (int i = 0; i < pdu2SetupList->list.count; i++) { pdu_session_to_setup_t *pdu_session = bearerCxt->pduSession + i; E1AP_PDU_Session_Resource_To_Setup_Item_t *pdu2Setup = pdu2SetupList->list.array[i]; @@ -956,7 +965,7 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, E1AP_DRB_To_Setup_List_NG_RAN_t *drb2SetupList = &pdu2Setup->dRB_To_Setup_List_NG_RAN; pdu_session->numDRB2Setup = drb2SetupList->list.count; - for (int j=0; j < drb2SetupList->list.count; j++) { + for (int j = 0; j < drb2SetupList->list.count; j++) { DRB_nGRAN_to_setup_t *drb = pdu_session->DRBnGRanList + j; E1AP_DRB_To_Setup_Item_NG_RAN_t *drb2Setup = drb2SetupList->list.array[j]; @@ -981,7 +990,7 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, E1AP_Cell_Group_Information_t *cellGroupList = &drb2Setup->cell_Group_Information; drb->numCellGroups = cellGroupList->list.count; - for (int k=0; k < cellGroupList->list.count; k++) { + for (int k = 0; k < cellGroupList->list.count; k++) { E1AP_Cell_Group_Information_Item_t *cg2Setup = cellGroupList->list.array[k]; drb->cellGroupList[k].id = cg2Setup->cell_Group_ID; @@ -989,7 +998,7 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, E1AP_QoS_Flow_QoS_Parameter_List_t *qos2SetupList = &drb2Setup->qos_flow_Information_To_Be_Setup; drb->numQosFlow2Setup = qos2SetupList->list.count; - for (int k=0; k < qos2SetupList->list.count; k++) { + for (int k = 0; k < qos2SetupList->list.count; k++) { qos_flow_to_setup_t *qos_flow = drb->qosFlows + k; E1AP_QoS_Flow_QoS_Parameter_Item_t *qos2Setup = qos2SetupList->list.array[k]; @@ -1026,8 +1035,6 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, break; } } - - } int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu) @@ -1045,14 +1052,14 @@ int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_upc return 0; } -void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu, - e1ap_bearer_setup_resp_t *bearerCxt) { +void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_resp_t *bearerCxt) +{ const E1AP_BearerContextSetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse; E1AP_BearerContextSetupResponseIEs_t *ie; 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++) { + for (int i = 0; i < in->protocolIEs.list.count; i++) { ie = in->protocolIEs.list.array[i]; switch(ie->id) { @@ -1082,7 +1089,7 @@ void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu, E1AP_PDU_Session_Resource_Setup_List_t *pduSetupList = &msgNGRAN->value.choice.PDU_Session_Resource_Setup_List; bearerCxt->numPDUSessions = pduSetupList->list.count; - for (int i=0; i < pduSetupList->list.count; i++) { + for (int i = 0; i < pduSetupList->list.count; i++) { pdu_session_setup_t *pduSetup = bearerCxt->pduSession + i; E1AP_PDU_Session_Resource_Setup_Item_t *pdu_session = pduSetupList->list.array[i]; pduSetup->id = pdu_session->pDU_Session_ID; @@ -1096,14 +1103,14 @@ void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu, } pduSetup->numDRBSetup = pdu_session->dRB_Setup_List_NG_RAN.list.count; - for (int j=0; j < pdu_session->dRB_Setup_List_NG_RAN.list.count; j++) { + for (int j = 0; j < pdu_session->dRB_Setup_List_NG_RAN.list.count; j++) { DRB_nGRAN_setup_t *drbSetup = pduSetup->DRBnGRanList + j; E1AP_DRB_Setup_Item_NG_RAN_t *drb = pdu_session->dRB_Setup_List_NG_RAN.list.array[j]; drbSetup->id = drb->dRB_ID; drbSetup->numUpParam = drb->uL_UP_Transport_Parameters.list.count; - for (int k=0; k < drb->uL_UP_Transport_Parameters.list.count; k++) { + for (int k = 0; k < drb->uL_UP_Transport_Parameters.list.count; k++) { up_params_t *UL_UP_param = drbSetup->UpParamList + k; E1AP_UP_Parameters_Item_t *in_UL_UP_param = drb->uL_UP_Transport_Parameters.list.array[k]; @@ -1159,7 +1166,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_up 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"); + AssertFatal(false, "Not implemented yet\n"); return -1; } @@ -1203,18 +1210,18 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *con msgNGRAN->criticality = E1AP_Criticality_reject; msgNGRAN->value.present = E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List; E1AP_PDU_Session_Resource_To_Modify_List_t *pdu2Setup = &msgNGRAN->value.choice.PDU_Session_Resource_To_Modify_List; - for(pdu_session_to_setup_t *i=bearerCxt->pduSessionMod; i < bearerCxt->pduSessionMod+bearerCxt->numPDUSessionsMod; i++) { + for (pdu_session_to_setup_t *i = bearerCxt->pduSessionMod; i < bearerCxt->pduSessionMod + bearerCxt->numPDUSessionsMod; i++) { asn1cSequenceAdd(pdu2Setup->list, E1AP_PDU_Session_Resource_To_Modify_Item_t, ieC3_1); ieC3_1->pDU_Session_ID = i->sessionId; - for (DRB_nGRAN_to_setup_t *j=i->DRBnGRanModList; j < i->DRBnGRanModList+i->numDRB2Modify; j++) { + for (DRB_nGRAN_to_setup_t *j = i->DRBnGRanModList; j < i->DRBnGRanModList + i->numDRB2Modify; j++) { asn1cCalloc(ieC3_1->dRB_To_Modify_List_NG_RAN, drb2Mod_List); asn1cSequenceAdd(drb2Mod_List->list, E1AP_DRB_To_Modify_Item_NG_RAN_t, drb2Mod); drb2Mod->dRB_ID = j->id; if (j->numDlUpParam > 0) { asn1cCalloc(drb2Mod->dL_UP_Parameters, DL_UP_Param_List); - for (up_params_t *k=j->DlUpParamList; k < j->DlUpParamList+j->numDlUpParam; k++) { + for (up_params_t *k = j->DlUpParamList; k < j->DlUpParamList + j->numDlUpParam; k++) { asn1cSequenceAdd(DL_UP_Param_List->list, E1AP_UP_Parameters_Item_t, DL_UP_Param); DL_UP_Param->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel; asn1cCalloc(DL_UP_Param->uP_TNL_Information.choice.gTPTunnel, gTPTunnel); @@ -1301,19 +1308,20 @@ static int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc return e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__); } -int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } -void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu, - e1ap_bearer_setup_req_t *bearerCxt) { +void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_req_t *bearerCxt) +{ const E1AP_BearerContextModificationRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextModificationRequest; E1AP_BearerContextModificationRequestIEs_t *ie; 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++) { + for (int i = 0; i < in->protocolIEs.list.count; i++) { ie = in->protocolIEs.list.array[i]; switch(ie->id) { @@ -1344,7 +1352,7 @@ void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu, E1AP_PDU_Session_Resource_To_Modify_List_t *pdu2ModList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Modify_List; bearerCxt->numPDUSessionsMod = pdu2ModList->list.count; - for (int i=0; i < pdu2ModList->list.count; i++) { + for (int i = 0; i < pdu2ModList->list.count; i++) { pdu_session_to_setup_t *pdu_session = bearerCxt->pduSessionMod + i; E1AP_PDU_Session_Resource_To_Modify_Item_t *pdu2Mod = pdu2ModList->list.array[i]; @@ -1352,7 +1360,7 @@ void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu, E1AP_DRB_To_Modify_List_NG_RAN_t *drb2ModList = pdu2Mod->dRB_To_Modify_List_NG_RAN; pdu_session->numDRB2Modify = drb2ModList->list.count; - for (int j=0; j < drb2ModList->list.count; j++) { + for (int j = 0; j < drb2ModList->list.count; j++) { DRB_nGRAN_to_setup_t *drb = pdu_session->DRBnGRanModList + j; E1AP_DRB_To_Modify_Item_NG_RAN_t *drb2Mod = drb2ModList->list.array[j]; @@ -1360,9 +1368,9 @@ void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu, E1AP_UP_Parameters_t *dl_up_paramList = drb2Mod->dL_UP_Parameters; drb->numDlUpParam = dl_up_paramList->list.count; - for (int k=0; k < dl_up_paramList->list.count; k++) { + for (int k = 0; k < dl_up_paramList->list.count; k++) { up_params_t *dl_up_param = drb->DlUpParamList + k; - E1AP_UP_Parameters_Item_t *dl_up_param_in = dl_up_paramList->list.array[k]; + E1AP_UP_Parameters_Item_t *dl_up_param_in = dl_up_paramList->list.array[k]; if (dl_up_param_in->uP_TNL_Information.choice.gTPTunnel) { // Optional IE DevAssert(dl_up_param_in->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel); BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_param_in->uP_TNL_Information.choice.gTPTunnel->transportLayerAddress, @@ -1384,7 +1392,9 @@ void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(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) +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); @@ -1436,7 +1446,7 @@ static void extract_BEARER_CONTEXT_MODIFICATION_RESPONSE(const E1AP_E1AP_PDU_t * 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++) { + 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; @@ -1449,7 +1459,7 @@ static void extract_BEARER_CONTEXT_MODIFICATION_RESPONSE(const E1AP_E1AP_PDU_t * 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++) { + 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]; @@ -1466,7 +1476,9 @@ static void extract_BEARER_CONTEXT_MODIFICATION_RESPONSE(const E1AP_E1AP_PDU_t * } } -int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_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) { DevAssert(pdu != NULL); DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome); @@ -1486,17 +1498,19 @@ int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } -int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } -int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } @@ -1505,7 +1519,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } @@ -1514,7 +1528,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } /* @@ -1587,19 +1601,20 @@ int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, const e return e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } -int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } -void extract_BEARER_CONTEXT_RELEASE_COMMAND(const E1AP_E1AP_PDU_t *pdu, - e1ap_bearer_release_cmd_t *bearerCxt) { +void extract_BEARER_CONTEXT_RELEASE_COMMAND(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_release_cmd_t *bearerCxt) +{ const E1AP_BearerContextReleaseCommand_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextReleaseCommand; E1AP_BearerContextReleaseCommandIEs_t *ie; 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++) { + for (int i = 0; i < in->protocolIEs.list.count; i++) { ie = in->protocolIEs.list.array[i]; switch(ie->id) { @@ -1645,14 +1660,14 @@ int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_u return 0; } -void extract_BEARER_CONTEXT_RELEASE_COMPLETE(const E1AP_E1AP_PDU_t *pdu, - e1ap_bearer_release_cplt_t *bearerCxt) { +void extract_BEARER_CONTEXT_RELEASE_COMPLETE(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_release_cplt_t *bearerCxt) +{ const E1AP_BearerContextReleaseComplete_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextReleaseComplete; E1AP_BearerContextReleaseCompleteIEs_t *ie; 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++) { + for (int i = 0; i < in->protocolIEs.list.count; i++) { ie = in->protocolIEs.list.array[i]; switch(ie->id) { @@ -1697,7 +1712,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } @@ -1705,8 +1720,9 @@ int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance, BEARER CONTEXT INACTIVITY NOTIFICATION */ -int e1apCUUP_send_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUUP_send_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } @@ -1715,39 +1731,42 @@ int e1apCUCP_handle_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } /* DL DATA */ -int e1apCUUP_send_DL_DATA_NOTIFICATION(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUUP_send_DL_DATA_NOTIFICATION(instance_t instance) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } -int e1apCUUP_send_DATA_USAGE_REPORT(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUUP_send_DATA_USAGE_REPORT(instance_t instance) +{ + AssertFatal(false, "Not implemented yet\n"); return -1; } int e1apCUCP_handle_DL_DATA_NOTIFICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } int e1apCUCP_handle_send_DATA_USAGE_REPORT(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + AssertFatal(false, "Not implemented yet\n"); return -1; } -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); +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); } @@ -1775,7 +1794,9 @@ static void e1apCUUP_send_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_setup_req_t 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) +static void e1_task_handle_sctp_association_resp(E1_t type, + instance_t instance, + sctp_new_association_resp_t *sctp_new_association_resp) { DevAssert(sctp_new_association_resp != NULL); getCxtE1(instance)->sockState = sctp_new_association_resp->sctp_state; @@ -1790,7 +1811,9 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, } if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { - LOG_W(E1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", + LOG_W(E1AP, + "Received unsuccessful result for SCTP association (%u), instance " + "%ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); @@ -1839,7 +1862,8 @@ void cuup_init_n3(instance_t instance) N3GTPUInst = &getCxtE1(instance)->gtpInstN3; } -void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr) { +void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr) +{ LOG_I(E1AP, "E1AP_CUCP_SCTP_REQ(create socket)\n"); MessageDef *message_p = NULL; message_p = itti_alloc_new_message (TASK_CUCP_E1, 0, SCTP_INIT_MSG); @@ -1883,7 +1907,8 @@ void e1apHandleTimer(instance_t myInstance) * and calls the relevant handlers for each message type. * */ -void *E1AP_CUCP_task(void *arg) { +void *E1AP_CUCP_task(void *arg) +{ LOG_I(E1AP, "Starting E1AP at CU CP\n"); MessageDef *msg = NULL; e1ap_common_init(); @@ -1891,7 +1916,7 @@ void *E1AP_CUCP_task(void *arg) { while (1) { itti_receive_msg(TASK_CUCP_E1, &msg); - instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg); + 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); sctp_assoc_t assoc_id = msg->ittiMsgHeader.originInstance; @@ -1950,7 +1975,6 @@ void *E1AP_CUCP_task(void *arg) { result = itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d) in E1AP_CUCP_task!\n", result); msg = NULL; - } } @@ -1962,7 +1986,8 @@ void *E1AP_CUCP_task(void *arg) { * and calls the relevant handlers for each message type. * */ -void *E1AP_CUUP_task(void *arg) { +void *E1AP_CUUP_task(void *arg) +{ LOG_I(E1AP, "Starting E1AP at CU UP\n"); e1ap_common_init(); int result; @@ -1998,21 +2023,21 @@ void *E1AP_CUUP_task(void *arg) { 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; + } 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); e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(inst->cuup.assoc_id, resp); - } break; + } 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; + } break; default: LOG_E(E1AP, "Unknown message received in TASK_CUUP_E1\n"); @@ -2022,7 +2047,5 @@ void *E1AP_CUUP_task(void *arg) { result = itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d) in E1AP_CUUP_task!\n", result); msg = NULL; - } } - From 1f4928f52fd0aef2e400081f82442299d0b69263 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 24 Jan 2024 14:35:00 +0100 Subject: [PATCH 12/13] Updated E1AP in doc/FEATURE_SET.md --- doc/FEATURE_SET.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 831561e025..6ac0a98c9c 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -203,10 +203,17 @@ Furthermore, the gNB and UE support ## gNB E1AP -- Integration of E1AP messages and procedures for exchange between CU-CP and CU-UP according to 38.463 Rel. 16 - - gNB-CU-UP E1 Setup Setup request/response - - E1 Bearer Context Setup +- Integration of E1AP messages and procedures for exchange between CU-CP and CU-UP according to TS 38.463 Rel. 16 + - E1 Setup (gNB-CU-UP initiated) + - E1 Setup Request + - E1 Setup Response + - E1 Setup Failure + - E1 Bearer Context Setup (gNB-CU-CP initiated) + - E1 Bearer Context Setup Request + - E1 Bearer Context Setup Response - Bearer Context Modification (gNB-CU-CP initiated) + - E1 Bearer Context Modification Request + - E1 Bearer Context Modification Response - Interface with RRC and PDCP ## gNB GTP-U From f3f8e8403bc4e7030c20a3dc469a10ac50cad46c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 25 Jan 2024 15:55:37 +0100 Subject: [PATCH 13/13] Update FEATURE_SET.md for F1AP --- doc/FEATURE_SET.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 6ac0a98c9c..9933ba3107 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -191,12 +191,13 @@ Furthermore, the gNB and UE support ## gNB F1AP - Integration of F1AP messages and procedures for the control plane exchanges between the CU and DU entities according to 38.473 Rel. 16 - - F1 Setup request/response + - F1 Setup request/response/failure - F1 DL/UL RRC message transfer - F1 Initial UL RRC message transfer - F1 UE Context setup request/response - F1 UE Context modification request/response - - F1 UE Context release + - F1 UE Context modification required + - F1 UE Context release req/cmd/complete - F1 gNB CU configuration update - Interface with RRC - Interface with gtp-u (tunnel creation/handling for F1-U interface)