From 7cfa4821077df77ff956bdb4b9e0989c2f79d230 Mon Sep 17 00:00:00 2001 From: "Madhuri.G" Date: Tue, 10 Dec 2024 17:33:19 +0530 Subject: [PATCH] Initial Context Setup Failure NGAP Failure message - Initial Context Setup Failure. When an Initial Context Setup Request is received with the UE context as null, it triggers Initial Context Setup failure. --- openair2/COMMON/ngap_messages_types.h | 7 +- openair2/RRC/NR/rrc_gNB_NGAP.c | 23 +++-- openair2/RRC/NR/rrc_gNB_NGAP.h | 5 ++ openair3/NGAP/ngap_gNB.c | 4 + openair3/NGAP/ngap_gNB_nas_procedures.c | 109 ++++++++++++++++++++++++ openair3/NGAP/ngap_gNB_nas_procedures.h | 2 + 6 files changed, 143 insertions(+), 7 deletions(-) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 2ac5652a9f..c4d2cd011a 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -553,9 +553,12 @@ typedef struct ngap_initial_context_setup_resp_s { } ngap_initial_context_setup_resp_t; typedef struct ngap_initial_context_setup_fail_s { - uint32_t gNB_ue_ngap_id; + uint32_t gNB_ue_ngap_id; - /* TODO add cause */ + 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; typedef struct ngap_nas_non_delivery_ind_s { diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index bf71357aed..2d5ff73446 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -432,12 +432,11 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to NGAP and discard it! */ - MessageDef *msg_fail_p = NULL; 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); - msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_INITIAL_CONTEXT_SETUP_FAIL); - NGAP_INITIAL_CONTEXT_SETUP_FAIL(msg_fail_p).gNB_ue_ngap_id = req->gNB_ue_ngap_id; - // TODO add failure cause when defined! - itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); + 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); return (-1); } gNB_RRC_INST *rrc = RC.nrrrc[instance]; @@ -542,6 +541,20 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_ itti_send_msg_to_task (TASK_NGAP, rrc->module_id, msg_p); } +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) +{ + 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); +} + static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(const gNB_RRC_INST *rrc, uint16_t algorithms) { int i; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h index 235a175954..0a0c976549 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.h +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -46,6 +46,11 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *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); + int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mui_t *rrc_gNB_mui); void rrc_gNB_send_NGAP_UPLINK_NAS(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_UL_DCCH_Message_t *const ul_dcch_msg); diff --git a/openair3/NGAP/ngap_gNB.c b/openair3/NGAP/ngap_gNB.c index 9c328c37c7..b60ac1c13c 100644 --- a/openair3/NGAP/ngap_gNB.c +++ b/openair3/NGAP/ngap_gNB.c @@ -328,6 +328,10 @@ void *ngap_gNB_process_itti_msg(void *notUsed) { ngap_gNB_initial_ctxt_resp(instance, &NGAP_INITIAL_CONTEXT_SETUP_RESP(received_msg)); break; + case NGAP_INITIAL_CONTEXT_SETUP_FAIL: + ngap_gNB_initial_ctxt_fail(instance, &NGAP_INITIAL_CONTEXT_SETUP_FAIL(received_msg)); + break; + case NGAP_PDUSESSION_SETUP_RESP: ngap_gNB_pdusession_setup_resp(instance, &NGAP_PDUSESSION_SETUP_RESP(received_msg)); break; diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 6cce5b695e..86ecd6eead 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -749,6 +749,115 @@ int ngap_gNB_initial_ctxt_resp(instance_t instance, ngap_initial_context_setup_r return 0; } +//--------------------------------------------------------------------------------------------------------- +int ngap_gNB_initial_ctxt_fail(instance_t instance, ngap_initial_context_setup_fail_t *initial_ctxt_fail) +//--------------------------------------------------------------------------------------------------------- +{ + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + NGAP_NGAP_PDU_t pdu; + uint8_t *buffer = NULL; + uint32_t length; + + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(initial_ctxt_fail != NULL); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_get_ue_context(initial_ctxt_fail->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", initial_ctxt_fail->gNB_ue_ngap_id); + return -1; + } + /* Uplink NAS transport can occur either during an ngap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { + NGAP_WARN( + "You are attempting to send NAS data over non-connected " + "gNB ue ngap id: %08x, current state: %d\n", + initial_ctxt_fail->gNB_ue_ngap_id, + ue_context_p->ue_state); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_unsuccessfulOutcome; + asn1cCalloc(pdu.choice.unsuccessfulOutcome, out); + out->procedureCode = NGAP_ProcedureCode_id_InitialContextSetup; + out->criticality = NGAP_Criticality_reject; + out->value.present = NGAP_UnsuccessfulOutcome__value_PR_InitialContextSetupFailure; + NGAP_InitialContextSetupFailure_t *fail = &out->value.choice.InitialContextSetupFailure; + /* mandatory */ + { + asn1cSequenceAdd(fail->protocolIEs.list, NGAP_InitialContextSetupFailureIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupFailureIEs__value_PR_AMF_UE_NGAP_ID; + // ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + } + /* mandatory */ + { + asn1cSequenceAdd(fail->protocolIEs.list, NGAP_InitialContextSetupFailureIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupFailureIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = initial_ctxt_fail->gNB_ue_ngap_id; + } + /* mandatory */ + { + asn1cSequenceAdd(fail->protocolIEs.list, NGAP_InitialContextSetupFailureIEs_t, ie); + 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; + } + } + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, &pdu); + } + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode InitialContextSetupFailure\n"); + /* Encode procedure has failed... */ + return -1; + } + /* UE associated signalling -> use the allocated stream */ + LOG_I(NR_RRC, "Send message to sctp: NGAP_InitialContextSetupFailure\n"); + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, + buffer, + length, + ue_context_p->tx_stream); + return 0; +} + //------------------------------------------------------------------------------ int ngap_gNB_ue_capabilities(instance_t instance, ngap_ue_cap_info_ind_t *ue_cap_info_ind_p) //------------------------------------------------------------------------------ diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.h b/openair3/NGAP/ngap_gNB_nas_procedures.h index f977bf3a69..3cd03838b4 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.h +++ b/openair3/NGAP/ngap_gNB_nas_procedures.h @@ -49,6 +49,8 @@ int ngap_gNB_handle_nas_first_req( int ngap_gNB_initial_ctxt_resp( instance_t instance, ngap_initial_context_setup_resp_t *initial_ctxt_resp_p); +int ngap_gNB_initial_ctxt_fail(instance_t instance, ngap_initial_context_setup_fail_t *initial_ctxt_fail); + int ngap_gNB_ue_capabilities(instance_t instance, ngap_ue_cap_info_ind_t *ue_cap_info_ind_p);