diff --git a/CMakeLists.txt b/CMakeLists.txt index eff1778c0f..c2ac55465b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -345,6 +345,7 @@ set(NGAP_DIR ${OPENAIR3_DIR}/NGAP) include_directories ("${NGAP_DIR}") add_library(ngap ${NGAP_DIR}/ngap_gNB.c + ${NGAP_DIR}/ngap_common.c ${NGAP_DIR}/ngap_gNB_context_management_procedures.c ${NGAP_DIR}/ngap_gNB_decoder.c ${NGAP_DIR}/ngap_gNB_encoder.c diff --git a/doc/E1AP/E1-design.md b/doc/E1AP/E1-design.md index e98c0ac581..8fafd09f66 100644 --- a/doc/E1AP/E1-design.md +++ b/doc/E1AP/E1-design.md @@ -194,3 +194,7 @@ Note that CU-UPs are not released from CU-CP internal structures. That means that you have to restart the CU-CP if you want to connect the CU-UP again (e.g., after a crash). The CU-CP might also misfunction during attach if a CU-UP was connected, but disconnected in the meantime. + +# 5. Abnormal conditions + +* The CU-UP goes offline during normal operation (e.g. UEs have a valid PDU Session and are exchanging data on the UP): after restarting the CU-UP, the UP is not restored and the user will notice GTP errors. In this case the UEs have to reconnect. diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c index 978486f261..856dcd6152 100644 --- a/executables/nr-cuup.c +++ b/executables/nr-cuup.c @@ -172,6 +172,7 @@ int main(int argc, char **argv) MessageDef *msg = RCconfig_NR_CU_E1(&e1type); AssertFatal(msg != NULL, "Send init to task for E1AP UP failed\n"); itti_send_msg_to_task(TASK_CUUP_E1, 0, msg); + LOG_D(E1AP, "Send E1AP REGISTER REQ to TASK_CUUP_E1\n"); #ifdef E2_AGENT ////////////////////////////////// diff --git a/openair2/COMMON/ngap_messages_def.h b/openair2/COMMON/ngap_messages_def.h index 87d8a59fba..62498698f2 100644 --- a/openair2/COMMON/ngap_messages_def.h +++ b/openair2/COMMON/ngap_messages_def.h @@ -69,7 +69,6 @@ MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMPLETE, MESSAGE_PRIORITY_MED, ngap_ue_rele MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_RESP , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_resp_t , ngap_ue_ctxt_modification_resp) MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_FAIL , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_fail_t , ngap_ue_ctxt_modification_fail) MESSAGE_DEF(NGAP_PDUSESSION_SETUP_RESP , MESSAGE_PRIORITY_MED, ngap_pdusession_setup_resp_t , ngap_pdusession_setup_resp) -MESSAGE_DEF(NGAP_PDUSESSION_SETUP_REQUEST_FAIL , MESSAGE_PRIORITY_MED, ngap_pdusession_setup_req_fail_t , ngap_pdusession_setup_request_fail) MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_RESP , MESSAGE_PRIORITY_MED, ngap_pdusession_modify_resp_t , ngap_pdusession_modify_resp) MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, ngap_pdusession_release_resp_t , ngap_pdusession_release_resp) MESSAGE_DEF(NGAP_PATH_SWITCH_REQ , MESSAGE_PRIORITY_MED, ngap_path_switch_req_t , ngap_path_switch_req) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index c4d2cd011a..31b7abd3f8 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -51,7 +51,6 @@ #define NGAP_UE_CTXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_resp #define NGAP_UE_CTXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_fail #define NGAP_PDUSESSION_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_resp -#define NGAP_PDUSESSION_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_request_fail #define NGAP_PDUSESSION_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_modify_resp #define NGAP_PATH_SWITCH_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_path_switch_req #define NGAP_PATH_SWITCH_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.ngap_path_switch_req_ack @@ -336,19 +335,21 @@ typedef struct pdusession_modify_s { qos_flow_tobe_modified_t qos[QOSFLOW_MAX_VALUE]; } pdusession_modify_t; -typedef enum ngap_Cause_e { - NGAP_CAUSE_NOTHING, /* No components present */ +/* Cause (9.3.1.2 of 3GPP TS 38.413) */ +typedef enum ngap_cause_group_e { + NGAP_CAUSE_NOTHING, /* No components present */ NGAP_CAUSE_RADIO_NETWORK, NGAP_CAUSE_TRANSPORT, NGAP_CAUSE_NAS, NGAP_CAUSE_PROTOCOL, NGAP_CAUSE_MISC, - NGAP_Cause_PR_choice_ExtensionS, - //Evilish manual duplicate of asn.1 grammar - //because it is human work, whereas it can be generated by machine - //and because humans manual copy creates bugs - //and we create multiple names for the same thing, that is a source of confusion -} ngap_Cause_t; +} ngap_cause_group_t; + +/* Cause (9.3.1.2 of 3GPP TS 38.413) */ +typedef struct ngap_cause_s { + ngap_cause_group_t type; + uint8_t value; +} ngap_cause_t; typedef enum ngap_Cause_radio_network_e { NGAP_CAUSE_RADIO_NETWORK_UNSPECIFIED, @@ -378,7 +379,7 @@ typedef enum ngap_Cause_radio_network_e { NGAP_CAUSE_RADIO_NETWORK_FAILURE_IN_RADIO_INTERFACE_PROCEDURE, NGAP_CAUSE_RADIO_NETWORK_INTERACTION_WITH_OTHER_PROCEDURE, NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_PDU_SESSION_ID, - NGAP_CAUSE_RADIO_NETWORK_UNKOWN_QOS_FLOW_ID, + NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_QOS_FLOW_ID, NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_PDU_SESSION_ID_INSTANCES, NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_QOS_FLOW_ID_INSTANCES, NGAP_CAUSE_RADIO_NETWORK_ENCRYPTION_AND_OR_INTEGRITY_PROTECTION_ALGORITHMS_NOT_SUPPORTED, @@ -398,8 +399,12 @@ typedef enum ngap_Cause_radio_network_e { NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_CN_DETECTED_MOBILITY, NGAP_CAUSE_RADIO_NETWORK_N26_INTERFACE_NOT_AVAILABLE, NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_PRE_EMPTION, - NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_LOCATION_REPORTING_REFERENCE_ID_INSTANCES -} ngap_Cause_radio_network_t; + NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_LOCATION_REPORTING_REFERENCE_ID_INSTANCES, + NGAP_CAUSE_RADIO_NETWORK_RSN_NOT_AVAILABLE_FOR_THE_UP, + NGAP_CAUSE_RADIO_NETWORK_NPN_ACCESS_DENIED, + NGAP_CAUSE_RADIO_NETWORK_CAG_ONLY_ACCESS_DENIED, + NGAP_CAUSE_RADIO_NETWORK_INSUFFICIENT_UE_CAPABILITIES +} ngap_cause_radio_network_t; /** * NGAP protocol cause values as per 9.3.1.2 `Cause` section in 3GPP TS 38.413. @@ -418,8 +423,7 @@ typedef struct pdusession_failed_s { /* Unique pdusession_id for the UE. */ uint8_t pdusession_id; /* Cause of the failure */ - ngap_Cause_t cause; - uint8_t cause_value; + ngap_cause_t cause; } pdusession_failed_t; typedef enum ngap_ue_ctxt_modification_present_s { @@ -557,9 +561,8 @@ typedef struct ngap_initial_context_setup_fail_s { uint64_t amf_ue_ngap_id; - ngap_Cause_t cause; - long cause_value; -} ngap_initial_context_setup_fail_t, ngap_ue_ctxt_modification_fail_t, ngap_pdusession_setup_req_fail_t; + ngap_cause_t cause; +} ngap_initial_context_setup_fail_t, ngap_ue_ctxt_modification_fail_t; typedef struct ngap_nas_non_delivery_ind_s { uint32_t gNB_ue_ngap_id; @@ -803,8 +806,7 @@ typedef struct ngap_ue_release_req_s { uint8_t nb_of_pdusessions; /* list of pdusession resource by RRC layers */ pdusession_release_t pdusessions[NGAP_MAX_PDUSESSION]; - ngap_Cause_t cause; - long cause_value; + ngap_cause_t cause; } ngap_ue_release_req_t, ngap_ue_release_resp_t; typedef struct ngap_pdusession_modify_req_s { diff --git a/openair2/COMMON/sctp_messages_types.h b/openair2/COMMON/sctp_messages_types.h index 313cdfa899..f311fd118a 100644 --- a/openair2/COMMON/sctp_messages_types.h +++ b/openair2/COMMON/sctp_messages_types.h @@ -36,11 +36,22 @@ #define SCTP_INIT_MSG_MULTI_CNF(mSGpTR) (mSGpTR)->ittiMsg.sctp_init_msg_multi_cnf #define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association -enum sctp_state_e { - SCTP_STATE_CLOSED, - SCTP_STATE_SHUTDOWN, - SCTP_STATE_ESTABLISHED, - SCTP_STATE_UNREACHABLE +#define SCTP_STATES \ + ITEM(SCTP_STATE_CLOSED) \ + ITEM(SCTP_STATE_SHUTDOWN) \ + ITEM(SCTP_STATE_ESTABLISHED) \ + ITEM(SCTP_STATE_UNREACHABLE) + +typedef enum { +#define ITEM(state) state, + SCTP_STATES +#undef ITEM +} sctp_state_e; + +static const char *sctp_state_s[] __attribute__((unused)) = { +#define ITEM(state) #state, + SCTP_STATES +#undef ITEM }; typedef struct sctp_new_association_req_s { @@ -112,7 +123,7 @@ typedef struct sctp_new_association_resp_s { uint16_t in_streams; /* State of the association at SCTP level */ - enum sctp_state_e sctp_state; + sctp_state_e sctp_state; } sctp_new_association_resp_t; typedef struct sctp_data_ind_s { diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 79b326593b..66206e3767 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1281,6 +1281,13 @@ static void e1apCUUP_send_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_setup_req_t e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__); } +/** + * @brief SCTP association response handler (CU-CP to/from CU-UP) + * it behaves differently depending on the type of E1 instance, + * CUCP: informs RRC of E1 connection loss with CU-UP + * CUUP: triggers a new SCTP association request by sending an ITTI to the CU-UP task + * @param type indicates whether the handler is for the CU-CP or CU-UP + */ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) @@ -1288,24 +1295,26 @@ static void e1_task_handle_sctp_association_resp(E1_t type, 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; - } - + // Handle SCTP establishment failure 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, - instance, - sctp_new_association_resp->ulp_cnx_id); - long timer_id; // if we want to cancel timer - timer_setup(1, 0, TASK_CUUP_E1, 0, TIMER_ONE_SHOT, NULL, &timer_id); + if (type == CPtype) { + // Inform RRC that the CU-UP is gone + LOG_W(E1AP, + "Lost connection (%s) with CU-UP (assoc_id %d)\n", + sctp_state_s[sctp_new_association_resp->sctp_state], + sctp_new_association_resp->assoc_id); + 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); + } else if (type == UPtype) { + // Trigger new E1 association when no CU-CP is connected + LOG_W(E1AP, + "Lost connection (%s) with CU-CP (assoc_id %d): trigger new E1 association\n", + sctp_state_s[sctp_new_association_resp->sctp_state], + sctp_new_association_resp->assoc_id); + long timer_id; + timer_setup(1, 0, TASK_CUUP_E1, 0, TIMER_ONE_SHOT, NULL, &timer_id); + } return; } @@ -1373,7 +1382,11 @@ void e1_task_handle_sctp_association_ind(E1_t type, instance_t instance, sctp_ne inst->cuup.assoc_id = sctp_new_ind->assoc_id; } -void e1apHandleTimer(instance_t myInstance) +/** + * @brief Handle the timer triggered by a connection loss with CU-CP + * it uses a stored network configuration and send a new SCTP association request + */ +static void e1apHandleTimer(instance_t myInstance) { LOG_W(E1AP, "Try to reconnect to CP\n"); if (getCxtE1(myInstance)->sockState != SCTP_STATE_ESTABLISHED) @@ -1483,6 +1496,8 @@ void *E1AP_CUUP_task(void *arg) LOG_D(E1AP, "CUUP received %s for instance %ld\n", messages_info[msgType].name, myInstance); switch (msgType) { case E1AP_REGISTER_REQ: { + /* E1AP Register Request triggered at startup + create a new E1 instance and send the first association request */ e1ap_register_req_t *reg_req = &E1AP_REGISTER_REQ(msg); createE1inst(UPtype, myInstance, reg_req->gnb_id, ®_req->net_config, ®_req->setup_req); e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, ®_req->net_config); @@ -1490,6 +1505,8 @@ void *E1AP_CUUP_task(void *arg) case SCTP_NEW_ASSOCIATION_RESP: e1_task_handle_sctp_association_resp(UPtype, myInstance, &msg->ittiMsg.sctp_new_association_resp); + if (getCxtE1(myInstance)->sockState == SCTP_STATE_ESTABLISHED) + LOG_A(E1AP, "E1 connection established (%s)\n", sctp_state_s[getCxtE1(myInstance)->sockState]); break; case SCTP_DATA_IND: @@ -1497,6 +1514,7 @@ void *E1AP_CUUP_task(void *arg) break; case TIMER_HAS_EXPIRED: + // Timer triggered by a connection loss with CU-CP e1apHandleTimer(myInstance); break; diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index 4acc606bec..452762965c 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -31,7 +31,7 @@ typedef struct e1ap_upcp_inst_s { instance_t instance; uint32_t gnb_id; // associated gNB's ID, unused in E1 but necessary for e.g. E2 agent E1_t type; - enum sctp_state_e sockState; + sctp_state_e sockState; struct { sctp_assoc_t assoc_id; e1ap_setup_req_t setupReq; diff --git a/openair2/E1AP/e1ap_setup.c b/openair2/E1AP/e1ap_setup.c index fc59a881fa..c27e1bd112 100644 --- a/openair2/E1AP/e1ap_setup.c +++ b/openair2/E1AP/e1ap_setup.c @@ -67,6 +67,17 @@ static void get_NGU_S1U_addr(char **addr, uint16_t *port) return; } +/** + * @brief Prepares an E1AP_REGISTER_REQ message for gNB-CU-UP/CP registration + * + * This function creates and populates an E1AP_REGISTER_REQ message using system + * configuration parameters. It supports both integrated CU-CP/UP and E1 splits, + * fetching RAN, PLMN, NSSAIs, and network configuration. + * + * @param entity Specifies the entity type (CU-CP or CU-UP. If NULL, assumes integrated CU-CP/UP + * + * @return A pointer to the E1AP_REGISTER_REQ message or NULL on allocation failure + */ MessageDef *RCconfig_NR_CU_E1(const E1_t *entity) { MessageDef *msgConfig = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_REGISTER_REQ); diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 59e4bb29af..fa77f818ea 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -65,7 +65,7 @@ static void cu_task_handle_sctp_association_ind(instance_t instance, static void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { DevAssert(sctp_new_association_resp != NULL); - enum sctp_state_e state = sctp_new_association_resp->sctp_state; + sctp_state_e state = sctp_new_association_resp->sctp_state; if (state != SCTP_STATE_ESTABLISHED) { f1ap_cudu_inst_t *f1ap_cu_data = getCxt(instance); AssertFatal(f1ap_cu_data != NULL, "illegal state: SCTP shutdown for non-existing F1AP endpoint\n"); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index b33b2c158c..953f723853 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -116,8 +116,7 @@ typedef struct pdu_session_param_s { pdusession_t param; pdu_session_status_t status; uint8_t xid; // transaction_id - ngap_Cause_t cause; - uint8_t cause_value; + ngap_cause_t cause; } rrc_pdu_session_param_t; /** diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index ab2a95ecde..52009b2959 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -86,6 +86,7 @@ bool ue_associated_to_cuup(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue); sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue); sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue, int sst, int sd); int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req); +bool is_cuup_associated(gNB_RRC_INST *rrc); /* 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); @@ -104,7 +105,8 @@ void ue_cxt_mod_direct(MessageDef *msg, void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp); -void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink); +bool trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink) + __attribute__((warn_unused_result)); int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib, uint32_t tmsi, uint8_t paging_drx); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 2456a851de..dc1e1b5bab 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -594,7 +594,7 @@ void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t continue; } - if (ue_p->pduSession[i].cause != NGAP_CAUSE_NOTHING) { + if (ue_p->pduSession[i].cause.type != NGAP_CAUSE_NOTHING) { // set xid of failure pdu session ue_p->pduSession[i].xid = xid; ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED; @@ -610,10 +610,10 @@ void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t } if (j == MAX_DRBS_PER_UE) { + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CauseRadioNetwork_unspecified}; ue_p->pduSession[i].xid = xid; ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED; - ue_p->pduSession[i].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_p->pduSession[i].cause_value = NGAP_CauseRadioNetwork_unspecified; + ue_p->pduSession[i].cause = cause; continue; } @@ -634,10 +634,10 @@ void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t default: LOG_E(NR_RRC, "not supported 5qi %lu\n", ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI); + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CauseRadioNetwork_not_supported_5QI_value}; ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED; ue_p->pduSession[i].xid = xid; - ue_p->pduSession[i].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_p->pduSession[i].cause_value = NGAP_CauseRadioNetwork_not_supported_5QI_value; + ue_p->pduSession[i].cause = cause; continue; } LOG_I(NR_RRC, @@ -766,6 +766,10 @@ static void cuup_notify_reestablishment(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p) .gNB_cu_cp_ue_id = ue_p->rrc_ue_id, .gNB_cu_up_ue_id = ue_p->rrc_ue_id, }; + // Quit re-establishment notification if no CU-UP is associated + if (!is_cuup_associated(rrc)) { + return; + } if (!ue_associated_to_cuup(rrc, ue_p)) return; /* loop through active DRBs */ @@ -1222,9 +1226,10 @@ fallback_rrc_setup: fill_random(&random_value, sizeof(random_value)); random_value = random_value & 0x7fffffffff; /* random value is 39 bits */ + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = ngap_cause}; /* request release of the "old" UE in case it exists */ if (ue_context_p != NULL) - rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(0, ue_context_p, NGAP_CAUSE_RADIO_NETWORK, ngap_cause); + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(0, ue_context_p, cause); rrc_gNB_ue_context_t *new = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); activate_srb(&new->ue_context, 1); @@ -1402,6 +1407,14 @@ static int handle_rrcReestablishmentComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE return 0; } +/** + * @brief Forward stored NAS PDU to UE (3GPP TS 38.413) + * - 8.2.1.2: If the NAS-PDU IE is included in the PDU SESSION RESOURCE SETUP REQUEST message, + * the NG-RAN node shall pass it to the UE. + * - 8.3.1.2: If the NAS-PDU IE is included in the INITIAL CONTEXT SETUP REQUEST message, + * the NG-RAN node shall pass it transparently towards the UE. + * - 8.6.2: The NAS-PDU IE contains an AMF–UE message that is transferred without interpretation in the NG-RAN node. + */ void rrc_forward_ue_nas_message(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE) { if (UE->nas_pdu.buffer == NULL || UE->nas_pdu.length == 0) @@ -1522,7 +1535,12 @@ static void handle_ueCapabilityInformation(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, * up security and request capabilities, so trigger PDU sessions now. The * UE NAS message will be forwarded in the corresponding reconfiguration, * the Initial context setup response after reconfiguration complete. */ - trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0); + if (!trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0)) { + LOG_W(NR_RRC, "Failed to setup bearers for UE %d: send Initial Context Setup Response\n", UE->rrc_ue_id); + rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(rrc, UE); + rrc_forward_ue_nas_message(rrc, UE); + return; + } } else { rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(rrc, UE); rrc_forward_ue_nas_message(rrc, UE); @@ -1734,7 +1752,11 @@ static int rrc_gNB_decode_dcch(gNB_RRC_INST *rrc, const f1ap_ul_rrc_message_t *m * to set up security, so trigger PDU sessions now. The UE NAS * message will be forwarded in the corresponding reconfiguration, * the Initial context setup response after reconfiguration complete. */ - trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0); + if (!trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0)) { + LOG_W(NR_RRC, "Failed to setup bearers for UE %d: send Initial Context Setup Response\n", UE->rrc_ue_id); + rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(rrc, UE); + rrc_forward_ue_nas_message(rrc, UE); + } } else { /* we already have capabilities, and no PDU sessions to setup, ack * this UE */ @@ -1882,6 +1904,11 @@ static void f1u_ul_gtp_update(f1u_tunnel_t *f1u, const up_params_t *p) * E1 to the CU of this UE. Also updates TEID info internally */ static void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f1ap_drb_to_be_setup_t *drbs) { + // Quit bearer updates if no CU-UP is associated + if (!is_cuup_associated(rrc)) { + return; + } + // we assume the same UE ID in CU-UP and CU-CP e1ap_bearer_mod_req_t req = { .gNB_cu_cp_ue_id = UE->rrc_ue_id, @@ -2031,10 +2058,8 @@ static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p, sctp_as /* TODO: marshall types correctly */ LOG_I(NR_RRC, "received UE Context Release Request for UE %u, forwarding to AMF\n", req->gNB_CU_ue_id); - rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(instance, - ue_context_p, - NGAP_CAUSE_RADIO_NETWORK, - NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST); + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST}; + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(instance, ue_context_p, cause); } static void rrc_delete_ue_data(gNB_RRC_UE_t *UE) diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 2d5ff73446..08f83ea5c8 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -320,11 +320,29 @@ static int decodePDUSessionResourceSetup(pdusession_t *session) return 0; } -void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink) +/** + * @brief Triggers bearer setup for the specified UE. + * + * This function initiates the setup of bearer contexts for a given UE + * by preparing and sending an E1AP Bearer Setup Request message to the CU-UP. + * + * @return True if bearer setup was successfully initiated, false otherwise + * @retval true Bearer setup was initiated successfully + * @retval false No CU-UP is associated, so bearer setup could not be initiated + * + * @note the return value is expected to be used (as per declaration) + * + */ +bool trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink) { AssertFatal(UE->as_security_active, "logic bug: security should be active when activating DRBs\n"); e1ap_bearer_setup_req_t bearer_req = {0}; + // Reject bearers setup if there's no CU-UP associated + if (!is_cuup_associated(rrc)) { + return false; + } + e1ap_nssai_t cuup_nssai = {0}; for (int i = 0; i < n; i++) { rrc_pdu_session_param_t *pduSession = find_pduSession(UE, sessions[i].pdusession_id, true); @@ -419,27 +437,60 @@ void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession * CU-UPs, and send them to the different CU-UPs. */ sctp_assoc_t assoc_id = get_new_cuup_for_ue(rrc, UE, cuup_nssai.sst, cuup_nssai.sd); rrc->cucp_cuup.bearer_context_setup(assoc_id, &bearer_req); + return true; +} + +/** + * @brief Fill PDU Session Resource Failed to Setup Item of the + * PDU Session Resource Failed to Setup List for either: + * - NGAP PDU Session Resource Setup Response + * - NGAP Initial Context Setup Response + */ +static void fill_pdu_session_resource_failed_to_setup_item(pdusession_failed_t *f, int pdusession_id, ngap_cause_t cause) +{ + f->pdusession_id = pdusession_id; + f->cause = cause; +} + +/** + * @brief Fill Initial Context Setup Response with a PDU Session Resource Failed to Setup List + * and send ITTI message to TASK_NGAP + */ +static void send_ngap_initial_context_setup_resp_fail(instance_t instance, + ngap_initial_context_setup_req_t *msg, + ngap_cause_t cause) +{ + MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, instance, NGAP_INITIAL_CONTEXT_SETUP_RESP); + ngap_initial_context_setup_resp_t *resp = &NGAP_INITIAL_CONTEXT_SETUP_RESP(msg_p); + resp->gNB_ue_ngap_id = msg->gNB_ue_ngap_id; + + for (int i = 0; i < msg->nb_of_pdusessions; i++) { + fill_pdu_session_resource_failed_to_setup_item(&resp->pdusessions_failed[i], msg->pdusession_param[i].pdusession_id, cause); + } + resp->nb_of_pdusessions = 0; + resp->nb_of_pdusessions_failed = msg->nb_of_pdusessions; + itti_send_msg_to_task(TASK_NGAP, instance, msg_p); } //------------------------------------------------------------------------------ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t instance) //------------------------------------------------------------------------------ { + gNB_RRC_INST *rrc = RC.nrrrc[instance]; ngap_initial_context_setup_req_t *req = &NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, req->gNB_ue_ngap_id); if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to NGAP and discard it! */ LOG_W(NR_RRC, "[gNB %ld] In NGAP_INITIAL_CONTEXT_SETUP_REQ: unknown UE from NGAP ids (%u)\n", instance, req->gNB_ue_ngap_id); + ngap_cause_t cause = { .type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_LOCAL_UE_NGAP_ID}; rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_FAIL(req->gNB_ue_ngap_id, NULL, - NGAP_CAUSE_RADIO_NETWORK, - NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_LOCAL_UE_NGAP_ID); + cause); return (-1); } - gNB_RRC_INST *rrc = RC.nrrrc[instance]; + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + UE->amf_ue_ngap_id = req->amf_ue_ngap_id; /* store guami in gNB_RRC_UE_t context; @@ -485,7 +536,13 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t // do not remove the above allocation which is reused here: this is used // in handle_rrcReconfigurationComplete() to know that we need to send a // Initial context setup response message - trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0); + if (!trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0)) { + LOG_W(NR_RRC, "UE %d: reject PDU Session Setup in Initial Context Setup Response\n", UE->rrc_ue_id); + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CAUSE_RADIO_NETWORK_RESOURCES_NOT_AVAILABLE_FOR_THE_SLICE}; + send_ngap_initial_context_setup_resp_fail(rrc->module_id, req, cause); + rrc_forward_ue_nas_message(rrc, UE); + return -1; + } } else { /* no PDU sesion to setup: acknowledge this message, and forward NAS * message, if required */ @@ -528,10 +585,10 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_ } } else if (session->status != PDU_SESSION_STATUS_ESTABLISHED) { session->status = PDU_SESSION_STATUS_FAILED; - pdusession_failed_t *fail = &resp->pdusessions_failed[pdu_sessions_failed]; - fail->pdusession_id = session->param.pdusession_id; - fail->cause = NGAP_CAUSE_RADIO_NETWORK; - fail->cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_PDU_SESSION_ID}; + fill_pdu_session_resource_failed_to_setup_item(&resp->pdusessions_failed[pdu_sessions_failed], + session->param.pdusession_id, + cause); pdu_sessions_failed++; } } @@ -543,15 +600,13 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_FAIL(uint32_t gnb, const rrc_gNB_ue_context_t *const ue_context_pP, - const ngap_Cause_t causeP, - const long cause_valueP) + const ngap_cause_t causeP) { MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_INITIAL_CONTEXT_SETUP_FAIL); ngap_initial_context_setup_fail_t *fail = &NGAP_INITIAL_CONTEXT_SETUP_FAIL(msg_p); memset(fail, 0, sizeof(*fail)); fail->gNB_ue_ngap_id = gnb; fail->cause = causeP; - fail->cause_value = cause_valueP; itti_send_msg_to_task(TASK_NGAP, 0, msg_p); } @@ -738,8 +793,8 @@ void rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE session->status = PDU_SESSION_STATUS_FAILED; pdusession_failed_t *fail = &resp->pdusessions_failed[pdu_sessions_failed]; fail->pdusession_id = session->param.pdusession_id; - fail->cause = NGAP_CAUSE_RADIO_NETWORK; - fail->cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; + fail->cause.type = NGAP_CAUSE_RADIO_NETWORK; + fail->cause.value = NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_PDU_SESSION_ID; pdu_sessions_failed++; } resp->nb_of_pdusessions = pdu_sessions_done; @@ -762,47 +817,72 @@ void rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE return; } -//------------------------------------------------------------------------------ -void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance) -//------------------------------------------------------------------------------ +/** + * @brief Fill PDU Session Resource Setup Response with a list of PDU Session Resources Failed to Setup + * and send ITTI message to TASK_NGAP + */ +static void send_ngap_pdu_session_setup_resp_fail(instance_t instance, ngap_pdusession_setup_req_t *msg, ngap_cause_t cause) { + MessageDef *msg_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_RESP); + ngap_pdusession_setup_resp_t *resp = &NGAP_PDUSESSION_SETUP_RESP(msg_resp); + resp->gNB_ue_ngap_id = msg->gNB_ue_ngap_id; + resp->nb_of_pdusessions_failed = msg->nb_pdusessions_tosetup; + resp->nb_of_pdusessions = 0; + for (int i = 0; i < resp->nb_of_pdusessions_failed; ++i) { + fill_pdu_session_resource_failed_to_setup_item(&resp->pdusessions_failed[i], + msg->pdusession_setup_params[i].pdusession_id, + cause); + } + itti_send_msg_to_task(TASK_NGAP, instance, msg_resp); +} - ngap_pdusession_setup_req_t* msg=&NGAP_PDUSESSION_SETUP_REQ(msg_p); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], msg->gNB_ue_ngap_id); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; +void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance) +{ gNB_RRC_INST *rrc = RC.nrrrc[instance]; - + ngap_pdusession_setup_req_t* msg=&NGAP_PDUSESSION_SETUP_REQ(msg_p); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, msg->gNB_ue_ngap_id); + // Reject PDU Session Resource setup if no UE context is found if (ue_context_p == NULL) { - MessageDef *msg_fail_p = NULL; - LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_SETUP_REQ: unknown UE from NGAP ids (%u)\n", instance, msg->gNB_ue_ngap_id); - msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_REQUEST_FAIL); - NGAP_PDUSESSION_SETUP_FAIL(msg_fail_p).gNB_ue_ngap_id = msg->gNB_ue_ngap_id; - // TODO add failure cause when defined! - itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); - return ; + LOG_W(NR_RRC, + "[gNB %ld] In NGAP_PDUSESSION_SETUP_REQ: no UE context found from UE NGAP ID (%u)\n", + instance, + msg->gNB_ue_ngap_id); + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_LOCAL_UE_NGAP_ID}; + send_ngap_pdu_session_setup_resp_fail(instance, msg, cause); + return; } - DevAssert(UE->rrc_ue_id == msg->gNB_ue_ngap_id); - LOG_I(NR_RRC, "UE %d: received PDU session setup request\n", UE->rrc_ue_id); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + LOG_I(NR_RRC, "UE %d: received PDU Session Resource Setup Request\n", UE->rrc_ue_id); + // Reject PDU Session Resource setup if gNB_ue_ngap_id is not matching + if (UE->rrc_ue_id != msg->gNB_ue_ngap_id) { + LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_SETUP_REQ: unknown UE NGAP ID (%u)\n", instance, msg->gNB_ue_ngap_id); + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_LOCAL_UE_NGAP_ID}; + send_ngap_pdu_session_setup_resp_fail(instance, msg, cause); + rrc_forward_ue_nas_message(rrc, UE); + return; + } + + // Reject PDU Session Resource setup if there is no security context active if (!UE->as_security_active) { - LOG_E(NR_RRC, "UE %d: no security context active for UE, rejecting PDU session setup request\n", UE->rrc_ue_id); - MessageDef *msg_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_RESP); - ngap_pdusession_setup_resp_t *resp = &NGAP_PDUSESSION_SETUP_RESP(msg_resp); - resp->gNB_ue_ngap_id = UE->rrc_ue_id; - resp->nb_of_pdusessions_failed = msg->nb_pdusessions_tosetup; - for (int i = 0; i < resp->nb_of_pdusessions_failed; ++i) { - pdusession_failed_t *f = &resp->pdusessions_failed[i]; - f->pdusession_id = msg->pdusession_setup_params[i].pdusession_id; - f->cause = NGAP_CAUSE_PROTOCOL; - f->cause_value = NGAP_CAUSE_PROTOCOL_MSG_NOT_COMPATIBLE_WITH_RECEIVER_STATE; - } - itti_send_msg_to_task(TASK_NGAP, instance, msg_resp); + LOG_E(NR_RRC, "UE %d: no security context active for UE, rejecting PDU Session Resource Setup Request\n", UE->rrc_ue_id); + ngap_cause_t cause = {.type = NGAP_CAUSE_PROTOCOL, .value = NGAP_CAUSE_PROTOCOL_MSG_NOT_COMPATIBLE_WITH_RECEIVER_STATE}; + send_ngap_pdu_session_setup_resp_fail(instance, msg, cause); + rrc_forward_ue_nas_message(rrc, UE); return; } UE->amf_ue_ngap_id = msg->amf_ue_ngap_id; - trigger_bearer_setup(rrc, UE, msg->nb_pdusessions_tosetup, msg->pdusession_setup_params, msg->ueAggMaxBitRateDownlink); + + if (!trigger_bearer_setup(rrc, UE, msg->nb_pdusessions_tosetup, msg->pdusession_setup_params, msg->ueAggMaxBitRateDownlink)) { + // Reject PDU Session Resource setup if there's no CU-UP associated + LOG_W(NR_RRC, "UE %d: reject PDU Session Setup in PDU Session Resource Setup Response\n", UE->rrc_ue_id); + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CAUSE_RADIO_NETWORK_RESOURCES_NOT_AVAILABLE_FOR_THE_SLICE}; + send_ngap_pdu_session_setup_resp_fail(instance, msg, cause); + rrc_forward_ue_nas_message(rrc, UE); + } + return; } @@ -926,17 +1006,18 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins UE->nb_of_pdusessions++; sess->status = PDU_SESSION_STATUS_FAILED; sess->param.pdusession_id = sessMod->pdusession_id; - sess->cause = NGAP_CAUSE_RADIO_NETWORK; - UE->pduSession[i].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; + sess->cause.type = NGAP_CAUSE_RADIO_NETWORK; + UE->pduSession[i].cause.type = NGAP_CAUSE_RADIO_NETWORK; + UE->pduSession[i].cause.value = NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_PDU_SESSION_ID; } else { all_failed = false; sess->status = PDU_SESSION_STATUS_NEW; sess->param.pdusession_id = sessMod->pdusession_id; - sess->cause = NGAP_CAUSE_RADIO_NETWORK; - sess->cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances; + sess->cause.type = NGAP_CAUSE_RADIO_NETWORK; + sess->cause.value = NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_PDU_SESSION_ID_INSTANCES; sess->status = PDU_SESSION_STATUS_NEW; sess->param.pdusession_id = sessMod->pdusession_id; - sess->cause = NGAP_CAUSE_NOTHING; + sess->cause.type = NGAP_CAUSE_NOTHING; if (sessMod->nas_pdu.buffer != NULL) { UE->pduSession[i].param.nas_pdu = sessMod->nas_pdu; } @@ -964,8 +1045,8 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins for (int i = 0; i < UE->nb_of_pdusessions; i++) { if (UE->pduSession[i].status == PDU_SESSION_STATUS_FAILED) { msg->pdusessions_failed[i].pdusession_id = UE->pduSession[i].param.pdusession_id; - msg->pdusessions_failed[i].cause = UE->pduSession[i].cause; - msg->pdusessions_failed[i].cause_value = UE->pduSession[i].cause_value; + msg->pdusessions_failed[i].cause.type = UE->pduSession[i].cause.type; + msg->pdusessions_failed[i].cause.value = UE->pduSession[i].cause.value; } } itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); @@ -1000,7 +1081,7 @@ int rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE LOG_I(NR_RRC, "update pdu session %d \n", pduSession->param.pdusession_id); // Update UE->pduSession pduSession->status = PDU_SESSION_STATUS_ESTABLISHED; - pduSession->cause = NGAP_CAUSE_NOTHING; + pduSession->cause.type = NGAP_CAUSE_NOTHING; for (int qos_flow_index = 0; qos_flow_index < UE->pduSession[i].param.nb_qos; qos_flow_index++) { pduSession->param.qos[qos_flow_index] = UE->pduSession[i].param.qos[qos_flow_index]; } @@ -1022,16 +1103,16 @@ int rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE } else { LOG_W(NR_RRC, "PDU SESSION modify of a not existing pdu session %d \n", UE->pduSession[i].param.pdusession_id); resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->pduSession[i].param.pdusession_id; - resp->pdusessions_failed[pdu_sessions_failed].cause = NGAP_CAUSE_RADIO_NETWORK; - resp->pdusessions_failed[pdu_sessions_failed].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_PDU_SESSION_ID}; + resp->pdusessions_failed[pdu_sessions_failed].cause = cause; pdu_sessions_failed++; } } else if ((UE->pduSession[i].status == PDU_SESSION_STATUS_NEW) || (UE->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED)) { LOG_D(NR_RRC, "PDU SESSION is NEW or already ESTABLISHED\n"); } else if (UE->pduSession[i].status == PDU_SESSION_STATUS_FAILED) { resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->pduSession[i].param.pdusession_id; - resp->pdusessions_failed[pdu_sessions_failed].cause = UE->pduSession[i].cause; - resp->pdusessions_failed[pdu_sessions_failed].cause_value = UE->pduSession[i].cause_value; + resp->pdusessions_failed[pdu_sessions_failed].cause.type = UE->pduSession[i].cause.type; + resp->pdusessions_failed[pdu_sessions_failed].cause.value = UE->pduSession[i].cause.value; pdu_sessions_failed++; } else @@ -1055,7 +1136,9 @@ int rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE } //------------------------------------------------------------------------------ -void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, const rrc_gNB_ue_context_t *const ue_context_pP, const ngap_Cause_t causeP, const long cause_valueP) +void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, + const rrc_gNB_ue_context_t *const ue_context_pP, + const ngap_cause_t causeP) //------------------------------------------------------------------------------ { if (ue_context_pP == NULL) { @@ -1066,8 +1149,8 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, con ngap_ue_release_req_t *req = &NGAP_UE_CONTEXT_RELEASE_REQ(msg); memset(req, 0, sizeof(*req)); req->gNB_ue_ngap_id = UE->rrc_ue_id; - req->cause = causeP; - req->cause_value = cause_valueP; + req->cause.type = causeP.type; + req->cause.value = causeP.value; for (int i = 0; i < UE->nb_of_pdusessions; i++) { req->pdusessions[i].pdusession_id = UE->pduSession[i].param.pdusession_id; req->nb_of_pdusessions++; @@ -1268,8 +1351,8 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_ int j=UE->nb_of_pdusessions++; UE->pduSession[j].status = PDU_SESSION_STATUS_FAILED; UE->pduSession[j].param.pdusession_id = cmd->pdusession_release_params[pdusession].pdusession_id; - UE->pduSession[j].cause = NGAP_CAUSE_RADIO_NETWORK; - UE->pduSession[j].cause_value = 30; + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_PDU_SESSION_ID}; + UE->pduSession[j].cause = cause; continue; } if (pduSession->status == PDU_SESSION_STATUS_FAILED) { diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h index 0a0c976549..a4ccaaa41b 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.h +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -48,8 +48,7 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_FAIL(uint32_t gnb, const rrc_gNB_ue_context_t *const ue_context_pP, - const ngap_Cause_t causeP, - const long cause_valueP); + const ngap_cause_t causeP); int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mui_t *rrc_gNB_mui); @@ -65,7 +64,9 @@ int rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p); -void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, const rrc_gNB_ue_context_t *const ue_context_pP, const ngap_Cause_t causeP, const long cause_valueP); +void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, + const rrc_gNB_ue_context_t *const ue_context_pP, + const ngap_cause_t causeP); int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t instance); diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index 621ebca56e..d0cc371209 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -90,6 +90,16 @@ static const nr_rrc_cuup_container_t *select_cuup_round_robin(size_t n_t, const return NULL; } +bool is_cuup_associated(gNB_RRC_INST *rrc) +{ + nr_rrc_cuup_container_t *cuup = NULL; + RB_FOREACH(cuup, rrc_cuup_tree, &rrc->cuups) { + return true; + } + LOG_W(NR_RRC, "no CU-UP associated to CU-CP\n"); + return false; +} + bool ue_associated_to_cuup(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue) { f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id); diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 654ef04be1..ff7a4fba59 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -429,10 +429,8 @@ static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id) cu_remove_f1_ue_data(ue_id); ue_data.du_assoc_id = 0; cu_add_f1_ue_data(ue_id, &ue_data); - rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(0, - ue_context_p, - NGAP_CAUSE_RADIO_NETWORK, - NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST); + ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST}; + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(0, ue_context_p, cause); count++; } } diff --git a/openair3/NGAP/ngap_common.c b/openair3/NGAP/ngap_common.c index bded329570..385730f70d 100644 --- a/openair3/NGAP/ngap_common.c +++ b/openair3/NGAP/ngap_common.c @@ -31,3 +31,38 @@ #include "ngap_common.h" int asn1_xer_print = 0; + +void encode_ngap_cause(NGAP_Cause_t *out, const ngap_cause_t *in) +{ + switch (in->type) { + case NGAP_CAUSE_RADIO_NETWORK: + out->present = NGAP_Cause_PR_radioNetwork; + out->choice.radioNetwork = in->value; + break; + + case NGAP_CAUSE_TRANSPORT: + out->present = NGAP_Cause_PR_transport; + out->choice.transport = in->value; + break; + + case NGAP_CAUSE_NAS: + out->present = NGAP_Cause_PR_nas; + out->choice.nas = in->value; + break; + + case NGAP_CAUSE_PROTOCOL: + out->present = NGAP_Cause_PR_protocol; + out->choice.protocol = in->value; + break; + + case NGAP_CAUSE_MISC: + out->present = NGAP_Cause_PR_misc; + out->choice.misc = in->value; + break; + + case NGAP_CAUSE_NOTHING: + default: + AssertFatal(false, "Unknown failure cause %d\n", in->type); + break; + } +} diff --git a/openair3/NGAP/ngap_common.h b/openair3/NGAP/ngap_common.h index f83414e2bb..259f0cbb18 100644 --- a/openair3/NGAP/ngap_common.h +++ b/openair3/NGAP/ngap_common.h @@ -36,10 +36,10 @@ #ifndef NGAP_COMMON_H_ #define NGAP_COMMON_H_ -#include #include "common/utils/LOG/log.h" #include "oai_asn1.h" #include "ngap_msg_includes.h" +#include "openair2/COMMON/ngap_messages_types.h" /* Checking version of ASN1C compiler */ #if (ASN1C_ENVIRONMENT_VERSION < ASN1C_MINIMUM_VERSION) @@ -84,6 +84,8 @@ extern int asn1_xer_print; **/ typedef int (*ngap_message_decoded_callback)(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu); +void encode_ngap_cause(NGAP_Cause_t *out, const ngap_cause_t *in); + /** @}*/ #endif /* NGAP_COMMON_H_ */ diff --git a/openair3/NGAP/ngap_gNB_context_management_procedures.c b/openair3/NGAP/ngap_gNB_context_management_procedures.c index 524fcee6c4..7abbec2592 100644 --- a/openair3/NGAP/ngap_gNB_context_management_procedures.c +++ b/openair3/NGAP/ngap_gNB_context_management_procedures.c @@ -200,32 +200,8 @@ int ngap_ue_context_release_req(instance_t instance, ie->id = NGAP_ProtocolIE_ID_id_Cause; ie->criticality = NGAP_Criticality_ignore; ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_Cause; - DevAssert(ue_release_req_p->cause <= NGAP_Cause_PR_choice_ExtensionS); - switch(ue_release_req_p->cause){ - case NGAP_CAUSE_RADIO_NETWORK: - ie->value.choice.Cause.present = NGAP_Cause_PR_radioNetwork; - ie->value.choice.Cause.choice.radioNetwork = ue_release_req_p->cause_value; - break; - case NGAP_CAUSE_TRANSPORT: - ie->value.choice.Cause.present = NGAP_Cause_PR_transport; - ie->value.choice.Cause.choice.transport = ue_release_req_p->cause_value; - break; - case NGAP_CAUSE_NAS: - ie->value.choice.Cause.present = NGAP_Cause_PR_nas; - ie->value.choice.Cause.choice.nas = ue_release_req_p->cause_value; - break; - case NGAP_CAUSE_PROTOCOL: - ie->value.choice.Cause.present = NGAP_Cause_PR_protocol; - ie->value.choice.Cause.choice.protocol = ue_release_req_p->cause_value; - break; - case NGAP_CAUSE_MISC: - ie->value.choice.Cause.present = NGAP_Cause_PR_misc; - ie->value.choice.Cause.choice.misc = ue_release_req_p->cause_value; - break; - default: - NGAP_WARN("Received NG Error indication cause NGAP_Cause_PR_choice_Extensions\n"); - break; - } + DevAssert(ue_release_req_p->cause.type <= NGAP_CAUSE_MISC); + encode_ngap_cause(&ie->value.choice.Cause, &ue_release_req_p->cause); } if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index 2916967b83..6309485e2d 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -1141,8 +1141,8 @@ static int ngap_gNB_handle_pdusession_modify_request(sctp_assoc_t assoc_id, uint item_p = (NGAP_PDUSessionResourceModifyItemModReq_t *)ie->value.choice.PDUSessionResourceModifyListModReq.list.array[nb_of_pdusessions_failed]; pdusession_failed_t *tmp = &msg->pdusessions_failed[nb_of_pdusessions_failed]; tmp->pdusession_id = item_p->pDUSessionID; - tmp->cause = NGAP_CAUSE_RADIO_NETWORK; - tmp->cause_value = NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID; + tmp->cause.type = NGAP_CAUSE_RADIO_NETWORK; + tmp->cause.value = NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID; } msg->nb_of_pdusessions_failed = ie->value.choice.PDUSessionResourceModifyListModReq.list.count; ngap_gNB_pdusession_modify_resp(amf_desc_p->ngap_gNB_instance->instance,msg); diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 86ecd6eead..83daacf758 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -681,37 +681,7 @@ int ngap_gNB_initial_ctxt_resp(instance_t instance, ngap_initial_context_setup_r item->pDUSessionID = initial_ctxt_resp_p->pdusessions_failed[i].pdusession_id; /* cause */ - switch(initial_ctxt_resp_p->pdusessions_failed[i].cause) { - case NGAP_CAUSE_RADIO_NETWORK: - pdusessionUnTransfer.cause.present = NGAP_Cause_PR_radioNetwork; - pdusessionUnTransfer.cause.choice.radioNetwork = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_CAUSE_TRANSPORT: - pdusessionUnTransfer.cause.present = NGAP_Cause_PR_transport; - pdusessionUnTransfer.cause.choice.transport = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_CAUSE_NAS: - pdusessionUnTransfer.cause.present = NGAP_Cause_PR_nas; - pdusessionUnTransfer.cause.choice.nas = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_CAUSE_PROTOCOL: - pdusessionUnTransfer.cause.present = NGAP_Cause_PR_protocol; - pdusessionUnTransfer.cause.choice.protocol = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_CAUSE_MISC: - pdusessionUnTransfer.cause.present = NGAP_Cause_PR_misc; - pdusessionUnTransfer.cause.choice.misc = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_CAUSE_NOTHING: - default: - AssertFatal(false, "Unknown PDU session failure cause %d\n", initial_ctxt_resp_p->pdusessions_failed[i].cause); - break; - } + encode_ngap_cause(&pdusessionUnTransfer.cause, &initial_ctxt_resp_p->pdusessions_failed[i].cause); NGAP_INFO("initial context setup response: failed pdusession ID %ld\n", item->pDUSessionID); asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, &pdusessionUnTransfer); @@ -812,33 +782,7 @@ int ngap_gNB_initial_ctxt_fail(instance_t instance, ngap_initial_context_setup_f ie->id = NGAP_ProtocolIE_ID_id_Cause; ie->criticality = NGAP_Criticality_ignore; ie->value.present = NGAP_InitialContextSetupFailureIEs__value_PR_Cause; - - switch (initial_ctxt_fail->cause) { - case NGAP_CAUSE_RADIO_NETWORK: - ie->value.choice.Cause.present = NGAP_Cause_PR_radioNetwork; - ie->value.choice.Cause.choice.radioNetwork = initial_ctxt_fail->cause_value; - break; - case NGAP_CAUSE_TRANSPORT: - ie->value.choice.Cause.present = NGAP_Cause_PR_transport; - ie->value.choice.Cause.choice.transport = initial_ctxt_fail->cause_value; - break; - case NGAP_CAUSE_NAS: - ie->value.choice.Cause.present = NGAP_Cause_PR_nas; - ie->value.choice.Cause.choice.nas = initial_ctxt_fail->cause_value; - break; - case NGAP_CAUSE_PROTOCOL: - ie->value.choice.Cause.present = NGAP_Cause_PR_protocol; - ie->value.choice.Cause.choice.protocol = initial_ctxt_fail->cause_value; - break; - case NGAP_CAUSE_MISC: - ie->value.choice.Cause.present = NGAP_Cause_PR_misc; - ie->value.choice.Cause.choice.misc = initial_ctxt_fail->cause_value; - break; - case NGAP_CAUSE_NOTHING: - default: - AssertFatal(false, "Unknown NGAP Initial Context Setup failure cause %d\n", initial_ctxt_fail->cause); - break; - } + encode_ngap_cause(&ie->value.choice.Cause, &initial_ctxt_fail->cause); } if (asn1_xer_print) { xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, &pdu); @@ -1058,37 +1002,7 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance, ngap_pdusession_setup_re item->pDUSessionID = pdusession_failed->pdusession_id; /* cause */ - switch(pdusession_failed->cause) { - case NGAP_CAUSE_RADIO_NETWORK: - pdusessionUnTransfer_p.cause.present = NGAP_Cause_PR_radioNetwork; - pdusessionUnTransfer_p.cause.choice.radioNetwork = pdusession_failed->cause_value; - break; - - case NGAP_CAUSE_TRANSPORT: - pdusessionUnTransfer_p.cause.present = NGAP_Cause_PR_transport; - pdusessionUnTransfer_p.cause.choice.transport = pdusession_failed->cause_value; - break; - - case NGAP_CAUSE_NAS: - pdusessionUnTransfer_p.cause.present = NGAP_Cause_PR_nas; - pdusessionUnTransfer_p.cause.choice.nas = pdusession_failed->cause_value; - break; - - case NGAP_CAUSE_PROTOCOL: - pdusessionUnTransfer_p.cause.present = NGAP_Cause_PR_protocol; - pdusessionUnTransfer_p.cause.choice.protocol = pdusession_failed->cause_value; - break; - - case NGAP_CAUSE_MISC: - pdusessionUnTransfer_p.cause.present = NGAP_Cause_PR_misc; - pdusessionUnTransfer_p.cause.choice.misc = pdusession_failed->cause_value; - break; - - case NGAP_CAUSE_NOTHING: - default: - AssertFatal(false, "Unknown PDU session failure cause %d\n", pdusession_failed->cause); - break; - } + encode_ngap_cause(&pdusessionUnTransfer_p.cause, &pdusession_failed->cause); NGAP_INFO("pdusession setup response: failed pdusession ID %ld\n", item->pDUSessionID); asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, &pdusessionUnTransfer_p); @@ -1222,37 +1136,8 @@ int ngap_gNB_pdusession_modify_resp(instance_t instance, ngap_pdusession_modify_ NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t pdusessionTransfer = {0}; - switch(pdusession_modify_resp_p->pdusessions_failed[i].cause) { - case NGAP_CAUSE_RADIO_NETWORK: - pdusessionTransfer.cause.present = NGAP_Cause_PR_radioNetwork; - pdusessionTransfer.cause.choice.radioNetwork = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_CAUSE_TRANSPORT: - pdusessionTransfer.cause.present = NGAP_Cause_PR_transport; - pdusessionTransfer.cause.choice.transport = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_CAUSE_NAS: - pdusessionTransfer.cause.present = NGAP_Cause_PR_nas; - pdusessionTransfer.cause.choice.nas = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_CAUSE_PROTOCOL: - pdusessionTransfer.cause.present = NGAP_Cause_PR_protocol; - pdusessionTransfer.cause.choice.protocol = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_CAUSE_MISC: - pdusessionTransfer.cause.present = NGAP_Cause_PR_misc; - pdusessionTransfer.cause.choice.misc = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_CAUSE_NOTHING: - default: - AssertFatal(false, "Unknown PDU session failure cause %d\n", pdusession_modify_resp_p->pdusessions_failed[i].cause); - break; - } + // NGAP cause + encode_ngap_cause(&pdusessionTransfer.cause, &pdusession_modify_resp_p->pdusessions_failed[i].cause); asn_encode_to_new_buffer_result_t res = {0}; NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t *pdusessionTransfer_p = NULL; diff --git a/openair3/SCTP/sctp_eNB_itti_messaging.c b/openair3/SCTP/sctp_eNB_itti_messaging.c index 40472ed923..bdfa2b0e01 100644 --- a/openair3/SCTP/sctp_eNB_itti_messaging.c +++ b/openair3/SCTP/sctp_eNB_itti_messaging.c @@ -68,7 +68,7 @@ int sctp_itti_send_association_resp(task_id_t task_id, instance_t instance, sctp_assoc_t assoc_id, uint16_t cnx_id, - enum sctp_state_e state, + sctp_state_e state, uint16_t out_streams, uint16_t in_streams) { diff --git a/openair3/SCTP/sctp_eNB_itti_messaging.h b/openair3/SCTP/sctp_eNB_itti_messaging.h index a91e95493c..a9fa20c10a 100644 --- a/openair3/SCTP/sctp_eNB_itti_messaging.h +++ b/openair3/SCTP/sctp_eNB_itti_messaging.h @@ -35,7 +35,7 @@ int sctp_itti_send_association_resp(task_id_t task_id, instance_t instance, sctp_assoc_t assoc_id, uint16_t cnx_id, - enum sctp_state_e state, + sctp_state_e state, uint16_t out_streams, uint16_t in_streams);