diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c index 90490e327f24e67ca52b6fb14123ce1e0fb72187..832f785551b08fb37208621f1c3a544b06ec1997 100644 --- a/executables/nr-cuup.c +++ b/executables/nr-cuup.c @@ -111,7 +111,7 @@ f1ap_cudu_inst_t *getCxt(F1_t isCU, instance_t instanceP) return NULL; } -void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) +void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid) { abort(); } diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 87426eff98416de4c9e568fcbd39026d34517b80..2f9f56e23aad23e8645bda42879db9032a1f9c92 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -263,17 +263,6 @@ typedef enum pdu_session_type_e { PDUSessionType_unstructured = 4 }pdu_session_type_t; -typedef struct ngap_transport_layer_addr_s { - /* Length of the transport layer address buffer in bits. NGAP layer received a - * bit string<1..160> containing one of the following addresses: ipv4, - * ipv6, or ipv4 and ipv6. The layer doesn't interpret the buffer but - * silently forward it to NG-U. - */ - uint8_t pdu_session_type; - uint8_t length; - uint8_t buffer[20]; // in network byte order -} ngap_transport_layer_addr_t; - typedef struct pdusession_s { /* Unique pdusession_id for the UE. */ int pdusession_id; @@ -283,11 +272,16 @@ typedef struct pdusession_s { /* Quality of service for this pdusession */ pdusession_level_qos_parameter_t qos[QOSFLOW_MAX_VALUE]; /* The transport layer address for the IP packets */ - ngap_transport_layer_addr_t upf_addr; + pdu_session_type_t pdu_session_type; + transport_layer_addr_t upf_addr; /* S-GW Tunnel endpoint identifier */ uint32_t gtp_teid; /* Stores the DRB ID of the DRBs used by this PDU Session */ uint8_t used_drbs[NGAP_MAX_DRBS_PER_UE]; + uint32_t gNB_teid_N3; + transport_layer_addr_t gNB_addr_N3; + uint32_t UPF_teid_N3; + transport_layer_addr_t UPF_addr_N3; } pdusession_t; typedef enum pdusession_qosflow_mapping_ind_e{ @@ -306,7 +300,8 @@ typedef struct pdusession_setup_s { uint8_t pdusession_id; /* The transport layer address for the IP packets */ - ngap_transport_layer_addr_t gNB_addr; + uint8_t pdu_session_type; + transport_layer_addr_t gNB_addr; /* UPF Tunnel endpoint identifier */ uint32_t gtp_teid; @@ -323,7 +318,8 @@ typedef struct pdusession_tobeswitched_s { uint8_t pdusession_id; /* The transport layer address for the IP packets */ - ngap_transport_layer_addr_t upf_addr; + uint8_t pdu_session_type; + transport_layer_addr_t upf_addr; /* S-GW Tunnel endpoint identifier */ uint32_t gtp_teid; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index fd3f420466c1c9690798a61b621e8e27bcc6ba77..9128b0f50e509bd320ca592a79c42842709f7e89 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -3808,7 +3808,6 @@ do_RRCConnectionReestablishment( LTE_DL_CCCH_Message_t dl_ccch_msg; LTE_RRCConnectionReestablishment_t *rrcConnectionReestablishment = NULL; int i = 0; - ue_context_pP->ue_context.reestablishment_xid = Transaction_id; LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id]; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 1f14eae9f6e82458b349e4069a1e697473cf497c..01ba86bc98c1cac014873f00f3c2520d95b427eb 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1139,7 +1139,6 @@ int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP, struct NR_SRB_ToAddMod *SRB2_config = NULL; NR_DL_DCCH_Message_t dl_dcch_msg = {0}; NR_RRCReestablishment_t *rrcReestablishment = NULL; - ue_context_pP->ue_context.reestablishment_xid = Transaction_id; NR_SRB_ToAddModList_t **SRB_configList2 = NULL; SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id]; diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 05ec9a837b558085ff5985578836ee00a595c30f..d0d4365e70a8cdc30386f010d197d0cad8ec4548 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -179,13 +179,14 @@ static NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, NR_SRB_To return SRB_configList2; } -static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) { +static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) +{ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; protocol_ctxt_t ctxt = {0}; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); - fill_DRB_configList(&ctxt, ue_context_p); + fill_DRB_configList(&ctxt, ue_context_p, xid); gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; // Fixme: xid not random, but almost! @@ -208,7 +209,7 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const } } -static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) { +static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) { instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; CU_update_UP_DL_tunnel(req, gtpInst, req->rnti); } diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index a3311b2ee14681bccca0b814a24853613297c3b2..eeea7ed3a9642bba9401c46a32dee1f985ac5f4a 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -35,12 +35,13 @@ extern RAN_CONTEXT_t RC; -static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) { +static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) +{ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti); protocol_ctxt_t ctxt = {0}; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); - fill_DRB_configList(&ctxt, ue_context_p); + fill_DRB_configList(&ctxt, ue_context_p, xid); MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_SETUP_REQ); e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p); memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t)); @@ -48,7 +49,8 @@ static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const r itti_send_msg_to_task (TASK_CUCP_E1, instance, msg_p); } -static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) { +static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) +{ MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_MODIFICATION_REQ); e1ap_bearer_setup_req_t *req_msg = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg); memcpy(req_msg, req, sizeof(*req)); diff --git a/openair2/RRC/NR/cucp_cuup_if.h b/openair2/RRC/NR/cucp_cuup_if.h index 079a32e8506eaf56c3f682d2b9c269cd7527983d..ed4702b4b28659435494f504acc19e9da90a5532 100644 --- a/openair2/RRC/NR/cucp_cuup_if.h +++ b/openair2/RRC/NR/cucp_cuup_if.h @@ -27,7 +27,7 @@ struct e1ap_bearer_setup_req_s; struct e1ap_bearer_setup_resp_s; -typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *const req, instance_t instance); +typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *const req, instance_t instance, uint8_t xid); struct gNB_RRC_INST_s; void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 942e9ffb1f1889c9e05b3eb5301c20b63942bfb4..9887d8936740f8c5324950dcef60dbefc5bae18f 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -128,7 +128,7 @@ typedef enum UE_STATE_NR_e { #define NO_SECURITY_MODE 0x20 /* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */ -#define NR_RRC_TRANSACTION_IDENTIFIER_NUMBER 3 +#define NR_RRC_TRANSACTION_IDENTIFIER_NUMBER 4 typedef struct { unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */ @@ -258,14 +258,15 @@ typedef enum pdu_session_satus_e { PDU_SESSION_STATUS_DONE, PDU_SESSION_STATUS_ESTABLISHED, PDU_SESSION_STATUS_REESTABLISHED, // after HO - PDU_SESSION_STATUS_TOMODIFY, // ENDC NSA + PDU_SESSION_STATUS_TOMODIFY, // ENDC NSA PDU_SESSION_STATUS_FAILED, - PDU_SESSION_STATUS_TORELEASE // to release DRB between eNB and UE + PDU_SESSION_STATUS_TORELEASE, // to release DRB between eNB and UE + PDU_SESSION_STATUS_RELEASED } pdu_session_status_t; typedef struct pdu_session_param_s { pdusession_t param; - uint8_t status; + pdu_session_status_t status; uint8_t xid; // transaction_id ngap_Cause_t cause; uint8_t cause_value; @@ -305,6 +306,19 @@ typedef struct drb_s { } pdcp_config; } drb_t; +typedef enum { + RRC_FIRST_RECONF, + RRC_SETUP, + RRC_SETUP_FOR_REESTABLISHMENT, + RRC_REESTABLISH, + RRC_REESTABLISH_COMPLETE, + RRC_DEFAULT_RECONF, + RRC_DEDICATED_RECONF, + RRC_PDUSESSION_ESTABLISH, + RRC_PDUSESSION_MODIFY, + RRC_PDUSESSION_RELEASE +} rrc_action_t; + typedef struct gNB_RRC_UE_s { uint8_t primaryCC_id; NR_SRB_ToAddModList_t *SRB_configList; @@ -369,38 +383,20 @@ typedef struct gNB_RRC_UE_s { nr_rrc_guami_t ue_guami; ngap_security_capabilities_t security_capabilities; - - /* Total number of e_rab already setup in the list */ - uint8_t setup_e_rabs; - /* Number of e_rab to be setup in the list */ + //NSA block + /* Number of NSA e_rab */ uint8_t nb_of_e_rabs; - /* Number of e_rab to be modified in the list */ - uint8_t nb_of_modify_e_rabs; - uint8_t nb_of_failed_e_rabs; - nr_e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; - /* Number of pdu session managed for the ue */ - uint8_t nb_of_pdusessions; - /* Number of e_rab to be modified in the list */ - uint8_t nb_of_modify_pdusessions; - uint8_t nb_of_failed_pdusessions; - rrc_pdu_session_param_t modify_pdusession[NR_NB_RB_MAX]; - /* list of e_rab to be setup by RRC layers */ /* list of pdu session to be setup by RRC layers */ nr_e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; - rrc_pdu_session_param_t pduSession[NGAP_MAX_PDU_SESSION]; - //release e_rabs - uint8_t nb_release_of_e_rabs; - e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB]; - uint8_t nb_release_of_pdusessions; - pdusession_failed_t pdusessions_release_failed[NGAP_MAX_PDUSESSION]; - // LG: For GTPV1 TUNNELS - uint32_t gnb_gtp_teid[S1AP_MAX_E_RAB]; - transport_layer_addr_t gnb_gtp_addrs[S1AP_MAX_E_RAB]; - rb_id_t gnb_gtp_ebi[S1AP_MAX_E_RAB]; - rb_id_t gnb_gtp_psi[S1AP_MAX_E_RAB]; - //GTPV1 F1-U TUNNELS - uint32_t incoming_teid[S1AP_MAX_E_RAB]; + uint32_t nsa_gtp_teid[S1AP_MAX_E_RAB]; + transport_layer_addr_t nsa_gtp_addrs[S1AP_MAX_E_RAB]; + rb_id_t nsa_gtp_ebi[S1AP_MAX_E_RAB]; + rb_id_t nsa_gtp_psi[S1AP_MAX_E_RAB]; + //SA block + int nb_of_pdusessions; + rrc_pdu_session_param_t pduSession[NGAP_MAX_PDU_SESSION]; + rrc_action_t xids[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; uint32_t ul_failure_timer; uint32_t ue_release_timer; uint32_t ue_release_timer_thres; @@ -412,11 +408,8 @@ typedef struct gNB_RRC_UE_s { uint32_t ue_release_timer_thres_rrc; uint32_t ue_reestablishment_timer; uint32_t ue_reestablishment_timer_thres; - uint8_t e_rab_release_command_flag; - uint8_t pdu_session_release_command_flag; - uint8_t established_pdu_sessions_flag; - uint32_t ue_rrc_inactivity_timer; - int8_t reestablishment_xid; + uint8_t e_rab_release_command_flag; + uint32_t ue_rrc_inactivity_timer; uint32_t ue_reestablishment_counter; uint32_t ue_reconfiguration_after_reestablishment_counter; NR_CellGroupId_t cellGroupId; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 87d786b773791127ad4193c5a37f58b3acfd439a..ee236e14084fd57e9bcf88e8d758c2af16f0b7b8 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -164,8 +164,7 @@ void ue_cxt_mod_send_e1ap(MessageDef *msg, void ue_cxt_mod_direct(MessageDef *msg, instance_t instance); -void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP); +void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid); void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 81a17afab1fcf81ec396838a66ab216790e9a90b..9c7a58c08161094e934f8477d06e1a35c8ec0639 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -106,8 +106,7 @@ extern RAN_CONTEXT_t RC; static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn); -mui_t rrc_gNB_mui = 0; -uint8_t first_rrcreconfiguration = 0; +mui_t rrc_gNB_mui = 0; ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// @@ -349,7 +348,9 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; gNB_RRC_INST *rrc = RC.nrrrc[instance]; unsigned char buf[1024]; - int size = do_RRCSetup(ue_context_pP, buf, rrc_gNB_get_next_transaction_identifier(instance), masterCellGroup, masterCellGroup_len, &rrc->configuration); + uint8_t xid = rrc_gNB_get_next_transaction_identifier(instance); + ue_p->xids[xid] = RRC_SETUP; + int size = do_RRCSetup(ue_context_pP, buf, xid, masterCellGroup, masterCellGroup_len, &rrc->configuration); AssertFatal(size > 0, "do_RRCSetup failed\n"); AssertFatal(size <= 1024, "memory corruption\n"); @@ -376,7 +377,7 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, } //----------------------------------------------------------------------------- -static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t module_id, rnti_t rnti, const int CC_id) +static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t module_id, rnti_t rnti, const int CC_id) //----------------------------------------------------------------------------- { LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n"); @@ -387,7 +388,9 @@ static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; unsigned char buf[1024]; - int size = do_RRCSetup(ue_context_pP, buf, rrc_gNB_get_next_transaction_identifier(module_id), NULL, 0, &rrc_instance_p->configuration); + uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); + ue_p->xids[xid] = RRC_SETUP_FOR_REESTABLISHMENT; + int size = do_RRCSetup(ue_context_pP, buf, xid, NULL, 0, &rrc_instance_p->configuration); AssertFatal(size > 0, "do_RRCSetup failed\n"); AssertFatal(size <= 1024, "memory corruption\n"); @@ -433,6 +436,7 @@ static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t .srb_id = CCCH }; rrc_instance_p->mac_rrc.dl_rrc_message_transfer(module_id, &dl_rrc); + return xid; } static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context_t *const ue_context_pP) @@ -492,11 +496,10 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co //----------------------------------------------------------------------------- { gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); - - /******************** Radio Bearer Config ********************/ gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; AssertFatal(ue_p->nb_of_pdusessions == 0, "logic bug: PDU sessions present before RRC Connection established\n"); + uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); + ue_p->xids[xid] = RRC_DEFAULT_RECONF; struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList)); @@ -583,9 +586,8 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co } } -void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP) { - +void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid) +{ gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; int qos_flow_index = 0; @@ -594,8 +596,6 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, uint8_t nb_drb_to_setup = rrc->configuration.drbs; long drb_priority[NGAP_MAX_DRBS_PER_UE]; - int xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); - if (!ue_p->DRB_configList) ue_p->DRB_configList = CALLOC(1, sizeof(*ue_p->DRB_configList)); else @@ -780,58 +780,53 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( rrc_gNB_ue_context_t *ue_context_pP) //----------------------------------------------------------------------------- { - NR_DRB_ToAddMod_t *DRB_config = NULL; - NR_DRB_ToAddModList_t **DRB_configList = NULL; + NR_DRB_ToAddMod_t *DRB_config = NULL; NR_DRB_ToAddModList_t *DRB_configList2 = NULL; struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL; - NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL; - int qos_flow_index = 0; - int i, j; - + int qos_flow_index = 0; uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - DRB_configList = &ue_p->DRB_configList; + ue_p->xids[xid] = RRC_DEDICATED_RECONF; DRB_configList2 = CALLOC(1, sizeof(NR_DRB_ToAddModList_t)); memset(DRB_configList2, 0, sizeof(NR_DRB_ToAddModList_t)); dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList)); - for (i = 0; i < ue_p->nb_of_modify_pdusessions; i++) { + for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { // bypass the new and already configured pdu sessions - if (ue_p->modify_pdusession[i].status >= PDU_SESSION_STATUS_DONE) { - ue_p->modify_pdusession[i].xid = xid; + if (ue_p->pduSession[i].status >= PDU_SESSION_STATUS_DONE) { + ue_p->pduSession[i].xid = xid; continue; } - if (ue_p->modify_pdusession[i].cause != NGAP_CAUSE_NOTHING) { + if (ue_p->pduSession[i].cause != NGAP_CAUSE_NOTHING) { // set xid of failure pdu session - ue_p->modify_pdusession[i].xid = xid; - ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED; + ue_p->pduSession[i].xid = xid; + ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED; continue; } // search exist DRB_config - for (j = 0; j < (*DRB_configList)->list.count; j++) { - if ((*DRB_configList)->list.array[j]->cnAssociation->choice.sdap_Config->pdu_Session == ue_p->modify_pdusession[i].param.pdusession_id) { - DRB_config = (*DRB_configList)->list.array[j]; + int j; + for (j = 0; i < NGAP_MAX_DRBS_PER_UE; j++) { + if (ue_p->established_drbs[j].status != DRB_INACTIVE + && ue_p->established_drbs[j].cnAssociation.sdap_config.pdusession_id == ue_p->pduSession[i].param.pdusession_id) break; - } } - if (DRB_config == NULL) { - ue_p->modify_pdusession[i].xid = xid; - ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED; - ue_p->modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_p->modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unspecified; - ue_p->nb_of_failed_pdusessions++; + if (j == NGAP_MAX_DRBS_PER_UE) { + 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; continue; } // Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping - for (qos_flow_index = 0; qos_flow_index < ue_p->modify_pdusession[i].param.nb_qos; qos_flow_index++) { - switch (ue_p->modify_pdusession[i].param.qos[qos_flow_index].fiveQI) { + for (qos_flow_index = 0; qos_flow_index < ue_p->pduSession[i].param.nb_qos; qos_flow_index++) { + switch (ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI) { case 1: //100ms case 2: //150ms case 3: //50ms @@ -845,12 +840,11 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( break; default: - LOG_E(NR_RRC, "not supported 5qi %lu\n", ue_p->modify_pdusession[i].param.qos[qos_flow_index].fiveQI); - ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED; - ue_p->modify_pdusession[i].xid = xid; - ue_p->modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_p->modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_not_supported_5QI_value; - ue_p->nb_of_failed_pdusessions++; + LOG_E(NR_RRC, "not supported 5qi %lu\n", ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI); + 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; continue; } @@ -860,24 +854,20 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( DRB_config->drb_Identity, i, qos_flow_index, - ue_p->modify_pdusession[i].param.qos[qos_flow_index].fiveQI); + ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI); } asn1cSeqAdd(&DRB_configList2->list, DRB_config); - ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_DONE; - ue_p->modify_pdusession[i].xid = xid; - - if (ue_p->modify_pdusession[i].param.nas_pdu.buffer != NULL) { - dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); - memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t)); - OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)ue_p->modify_pdusession[i].param.nas_pdu.buffer, ue_p->modify_pdusession[i].param.nas_pdu.length); - asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message); + ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; + ue_p->pduSession[i].xid = xid; - LOG_I(NR_RRC, "add NAS info with size %d (pdusession id %d)\n", ue_p->pduSession[i].param.nas_pdu.length, ue_p->modify_pdusession[i].param.pdusession_id); + if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { + asn1cSequenceAdd(dedicatedNAS_MessageList->list,NR_DedicatedNAS_Message_t, dedicatedNAS_Message); + OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)ue_p->pduSession[i].param.nas_pdu.buffer, ue_p->pduSession[i].param.nas_pdu.length); + LOG_I(NR_RRC, "add NAS info with size %d (pdusession id %d)\n", ue_p->pduSession[i].param.nas_pdu.length, ue_p->pduSession[i].param.pdusession_id); } else { - // TODO - LOG_E(NR_RRC, "no NAS info (pdusession id %d)\n", ue_p->modify_pdusession[i].param.pdusession_id); + LOG_W(NR_RRC, "no NAS info (pdusession id %d)\n", ue_p->pduSession[i].param.pdusession_id); } } @@ -907,11 +897,11 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n"); /* Free all NAS PDUs */ - for (i = 0; i < ue_p->nb_of_modify_pdusessions; i++) { - if (ue_p->modify_pdusession[i].param.nas_pdu.buffer != NULL) { + for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { + if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { /* Free the NAS PDU buffer and invalidate it */ - free(ue_p->modify_pdusession[i].param.nas_pdu.buffer); - ue_p->modify_pdusession[i].param.nas_pdu.buffer = NULL; + free(ue_p->pduSession[i].param.nas_pdu.buffer); + ue_p->pduSession[i].param.nas_pdu.buffer = NULL; } } @@ -986,14 +976,24 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( } uint8_t buffer[RRC_BUF_SIZE] = {0}; - int size = do_RRCReconfiguration(ctxt_pP, buffer, RRC_BUF_SIZE, xid, NULL, NULL, *DRB_Release_configList2, NULL, NULL, NULL, dedicatedNAS_MessageList, NULL, NULL, NULL, NULL, NULL); - - ue_p->pdu_session_release_command_flag = 1; - + int size = do_RRCReconfiguration(ctxt_pP, + buffer, + RRC_BUF_SIZE, + xid, + NULL, + NULL, + *DRB_Release_configList2, + NULL, + NULL, + NULL, + dedicatedNAS_MessageList, + NULL, + NULL, + NULL, + NULL, + NULL); LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n"); - ue_p->pdu_session_release_command_flag = 1; - /* Free all NAS PDUs */ if (nas_length > 0) { /* Free the NAS PDU buffer and invalidate it */ @@ -1207,16 +1207,18 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, SRB_configList = &(ue_p->SRB_configList); uint8_t buffer[RRC_BUF_SIZE] = {0}; + uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); + ue_p->xids[xid] = RRC_REESTABLISH; int size = do_RRCReestablishment(ctxt_pP, - ue_context_pP, - CC_id, - buffer, - RRC_BUF_SIZE, - rrc_gNB_get_next_transaction_identifier(module_id), - SRB_configList, - masterCellGroup_from_DU, - scc, - &rrc->carrier); + ue_context_pP, + CC_id, + buffer, + RRC_BUF_SIZE, + xid, + SRB_configList, + masterCellGroup_from_DU, + scc, + &rrc->carrier); LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", ue_p->rnti, size); @@ -1462,10 +1464,9 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx int i = 0; uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); + ue_p->xids[new_xid] = RRC_REESTABLISH_COMPLETE; ue_p->StatusRrc = NR_RRC_CONNECTED; ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - ue_p->reestablishment_xid = new_xid; - RRCReestablishmentComplete_fill_SRB2_configList(ctxt_pP, ue_context_pP, xid, new_xid); RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid); RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti); @@ -1751,14 +1752,14 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint ((cause == NR_ReestablishmentCause_otherFailure) ? "Other Failure" : (cause == NR_ReestablishmentCause_handoverFailure) ? "Handover Failure" : "reconfigurationFailure")); - + uint8_t xid = -1; if (physCellId != gnb_rrc_inst->carrier.physCellId) { /* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was received in this cell */ LOG_E(NR_RRC, " NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), fallback to RRC establishment\n", physCellId, gnb_rrc_inst->carrier.physCellId); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); + xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); break; } @@ -1772,7 +1773,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0x1 || rrcReestablishmentRequest.ue_Identity.c_RNTI > 0xffef) { /* c_RNTI range error should not happen */ LOG_E(NR_RRC, "NR_RRCReestablishmentRequest c_RNTI range error, fallback to RRC establishment\n"); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); + xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); break; } @@ -1782,7 +1783,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (ue_context_p == NULL) { LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n"); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, c_rnti, 0); + xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, c_rnti, 0); break; } // c-plane not end @@ -1797,7 +1798,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint UE->StatusRrc = NR_RRC_RECONFIGURED; protocol_ctxt_t ctxt_old_p; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p, module_id, GNB_FLAG_YES, c_rnti, 0, 0); - rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p, ue_context_p, UE->reestablishment_xid); + rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p, ue_context_p, xid); for (uint8_t pdusessionid = 0; pdusessionid < UE->nb_of_pdusessions; pdusessionid++) { if (UE->pduSession[pdusessionid].status == PDU_SESSION_STATUS_DONE) { @@ -1814,8 +1815,6 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint UE->ue_reestablishment_timer = 0; // UE->ue_release_timer_s1 = 0; UE->ue_release_timer_rrc = 0; - UE->reestablishment_xid = -1; - // Insert C-RNTI to map for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; @@ -1899,21 +1898,259 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, asn1cCallocOne(ue_ctxt->measResults, measurementReport->criticalExtensions.choice.measurementReport->measResults); } +static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, + const NR_RRCReestablishmentComplete_t *reestablishment_complete) +{ + rnti_t reestablish_rnti = 0; + gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; + rrc_gNB_ue_context_t *ue_context_p = NULL; + gNB_RRC_UE_t *UE = NULL; + // Select C-RNTI from map + for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { + nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; + LOG_I(NR_RRC, + "nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x, ctxt_pP->rntiMaybeUEid: %lx\n", + i, + nr_reestablish_rnti_map->ue_id, + nr_reestablish_rnti_map->c_rnti, + ctxt_pP->rntiMaybeUEid); + if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { + LOG_I(NR_RRC, + "Removing nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", + i, + nr_reestablish_rnti_map->ue_id, + nr_reestablish_rnti_map->c_rnti); + reestablish_rnti = nr_reestablish_rnti_map->c_rnti; + ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, reestablish_rnti); + UE = &ue_context_p->ue_context; + break; + } + } + + if (ue_context_p == NULL || UE == NULL) { + LOG_E(RRC, "no UE found for reestablishment. ERROR: should send reply\n"); + return -1; + } + + DevAssert(reestablishment_complete->criticalExtensions.present + == NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete); + rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP, + reestablish_rnti, + ue_context_p, + reestablishment_complete->rrc_TransactionIdentifier); + + nr_rrc_mac_remove_ue(reestablish_rnti); + + UE->ue_reestablishment_counter++; + + // UE->ue_release_timer = 0; + UE->ue_reestablishment_timer = 1; + // remove UE after 100 frames after NR_RRCReestablishmentRelease is triggered + UE->ue_reestablishment_timer_thres = 1000; + return 0; +} + +static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_p, + const NR_UECapabilityInformation_t *ue_cap_info) +{ + AssertFatal(ue_context_p != NULL, "Processing %s() for UE %lx, ue_context_p is NULL\n", __func__, ctxt_pP->rntiMaybeUEid); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + + LOG_I(NR_RRC, "got UE capabilities for UE %lx\n", ctxt_pP->rntiMaybeUEid); + int eutra_index = -1; + + if (ue_cap_info->criticalExtensions.present == NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation) { + const NR_UE_CapabilityRAT_ContainerList_t *ue_CapabilityRAT_ContainerList = + ue_cap_info->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList; + for (int i = 0; i < ue_CapabilityRAT_ContainerList->list.count; i++) { + const NR_UE_CapabilityRAT_Container_t *ue_cap_container = ue_CapabilityRAT_ContainerList->list.array[i]; + if (ue_cap_container->rat_Type == NR_RAT_Type_nr) { + if (UE->UE_Capability_nr) { + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); + UE->UE_Capability_nr = 0; + } + + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_NR_Capability, + (void **)&UE->UE_Capability_nr, + ue_cap_container->ue_CapabilityRAT_Container.buf, + ue_cap_container->ue_CapabilityRAT_Container.size, + 0, + 0); + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); + } + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT " Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); + UE->UE_Capability_nr = 0; + } + + UE->UE_Capability_size = ue_cap_container->ue_CapabilityRAT_Container.size; + if (eutra_index != -1) { + LOG_E(NR_RRC, "fatal: more than 1 eutra capability\n"); + exit(1); + } + eutra_index = i; + } + + if (ue_cap_container->rat_Type == NR_RAT_Type_eutra_nr) { + if (UE->UE_Capability_MRDC) { + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); + UE->UE_Capability_MRDC = 0; + } + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_MRDC_Capability, + (void **)&UE->UE_Capability_MRDC, + ue_cap_container->ue_CapabilityRAT_Container.buf, + ue_cap_container->ue_CapabilityRAT_Container.size, + 0, + 0); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); + } + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_FMT " Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); + UE->UE_Capability_MRDC = 0; + } + UE->UE_MRDC_Capability_size = ue_cap_container->ue_CapabilityRAT_Container.size; + } + + if (ue_cap_container->rat_Type == NR_RAT_Type_eutra) { + // TODO + } + } + + if (eutra_index == -1) + return -1; + } + + if (get_softmodem_params()->sa) { + rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(ctxt_pP, ue_context_p, ue_cap_info); + } + + // we send the UE capabilities request before RRC connection is complete, + // so we cannot have a PDU session yet + AssertFatal(UE->nb_of_pdusessions == 0, "logic bug: received capabilities while PDU session established\n"); + // TODO: send UE context modification response with UE capabilities to + // allow DU configure CellGroupConfig + rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + + return 0; +} + +static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_p, + const NR_RRCSetupComplete_t *setup_complete) +{ + if (!ue_context_p) { + LOG_I(NR_RRC, "Processing NR_RRCSetupComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); + return -1; + } + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + + NR_RRCSetupComplete_IEs_t *setup_complete_ies = setup_complete->criticalExtensions.choice.rrcSetupComplete; + + if (setup_complete_ies->ng_5G_S_TMSI_Value != NULL) { + if (setup_complete_ies->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI_Part2) { + if (setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size != 2) { + LOG_E(NR_RRC, + "wrong ng_5G_S_TMSI_Part2 size, expected 2, provided %lu", + (long unsigned int) + setup_complete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size); + return -1; + } + + if (UE->ng_5G_S_TMSI_Part1 != 0) { + UE->ng_5G_S_TMSI_Part2 = BIT_STRING_to_uint16(&setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2); + } + + /* TODO */ + } else if (setup_complete_ies->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI) { + if (setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size != 6) { + LOG_E(NR_RRC, + "wrong ng_5G_S_TMSI size, expected 6, provided %lu", + (long unsigned int)setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size); + return -1; + } + + uint64_t fiveg_s_TMSI = bitStr_to_uint64(&setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI); + LOG_I(NR_RRC, + "Received rrcSetupComplete, 5g_s_TMSI: 0x%lX, amf_set_id: 0x%lX(%ld), amf_pointer: 0x%lX(%ld), 5g TMSI: 0x%X \n", + fiveg_s_TMSI, + fiveg_s_TMSI >> 38, + fiveg_s_TMSI >> 38, + (fiveg_s_TMSI >> 32) & 0x3F, + (fiveg_s_TMSI >> 32) & 0x3F, + (uint32_t)fiveg_s_TMSI); + if (UE->Initialue_identity_5g_s_TMSI.presence) { + UE->Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38; + UE->Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F; + UE->Initialue_identity_5g_s_TMSI.fiveg_tmsi = (uint32_t)fiveg_s_TMSI; + } + } + } + + rrc_gNB_process_RRCSetupComplete(ctxt_pP, ue_context_p, setup_complete->criticalExtensions.choice.rrcSetupComplete); + LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " UE State = NR_RRC_CONNECTED \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + + UE->ue_release_timer = 0; + return 0; +} + +static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_p, + const NR_RRCReconfigurationComplete_t *reconfig_complete) +{ + LOG_I(NR_RRC, "Receive RRC Reconfiguration Complete message UE %lx\n", ctxt_pP->rntiMaybeUEid); + AssertFatal(ue_context_p != NULL, "Processing %s() for UE %lx, ue_context_p is NULL\n", __func__, ctxt_pP->rntiMaybeUEid); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + + uint8_t xid = reconfig_complete->rrc_TransactionIdentifier; + rrc_gNB_process_RRCReconfigurationComplete(ctxt_pP, ue_context_p, xid); + + if (get_softmodem_params()->sa) { + switch (UE->xids[xid]) { + case RRC_PDUSESSION_RELEASE: { + gtpv1u_gnb_delete_tunnel_req_t req = {0}; + gtpv1u_delete_ngu_tunnel(ctxt_pP->instance, &req); + // NGAP_PDUSESSION_RELEASE_RESPONSE + rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid); + } break; + case RRC_PDUSESSION_ESTABLISH: + if (UE->nb_of_pdusessions > 0) + rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP, ue_context_p, xid); + break; + case RRC_PDUSESSION_MODIFY: + rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(ctxt_pP, ue_context_p, xid); + break; + case RRC_FIRST_RECONF: + rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); + break; + default: + LOG_E(RRC, "Received unexpected xid: %d\n", xid); + } + } +} //----------------------------------------------------------------------------- -int -rrc_gNB_decode_dcch( - const protocol_ctxt_t *const ctxt_pP, - const rb_id_t Srb_id, - const uint8_t *const Rx_sdu, - const sdu_size_t sdu_sizeP -) +int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, + const rb_id_t Srb_id, + const uint8_t *const Rx_sdu, + const sdu_size_t sdu_sizeP) //----------------------------------------------------------------------------- { - asn_dec_rval_t dec_rval; - NR_UL_DCCH_Message_t *ul_dcch_msg = NULL; - uint8_t xid; gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; - int i; if ((Srb_id != 1) && (Srb_id != 2)) { LOG_E(NR_RRC, "Received message on SRB%ld, should not have ...\n", Srb_id); @@ -1922,38 +2159,27 @@ rrc_gNB_decode_dcch( } LOG_D(NR_RRC, "Decoding UL-DCCH Message\n"); - - //for (int i=0;i<sdu_sizeP;i++) printf("%02x ",Rx_sdu[i]); - //printf("\n"); - - dec_rval = uper_decode( - NULL, - &asn_DEF_NR_UL_DCCH_Message, - (void **)&ul_dcch_msg, - Rx_sdu, - sdu_sizeP, - 0, - 0); - - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); - } - { - for (i = 0; i < sdu_sizeP; i++) { + for (int i = 0; i < sdu_sizeP; i++) { LOG_T(NR_RRC, "%x.", Rx_sdu[i]); } LOG_T(NR_RRC, "\n"); } + NR_UL_DCCH_Message_t *ul_dcch_msg = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_UL_DCCH_Message, (void **)&ul_dcch_msg, Rx_sdu, sdu_sizeP, 0, 0); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E(NR_RRC, "Failed to decode UL-DCCH (%zu bytes)\n", dec_rval.consumed); return -1; } + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); + } + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) { switch (ul_dcch_msg->message.choice.c1->present) { @@ -1962,148 +2188,12 @@ rrc_gNB_decode_dcch( break; case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete: - LOG_I(NR_RRC, "Receive RRC Reconfiguration Complete message UE %lx\n", ctxt_pP->rntiMaybeUEid); - if(!ue_context_p) { - LOG_E(NR_RRC, "Processing NR_RRCReconfigurationComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); - break; - } - - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(Rx_sdu), sdu_sizeP, - "[MSG] RRC Connection Reconfiguration Complete\n"); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(RRCReconfigurationComplete) ---> RRC_gNB]\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - - if (ul_dcch_msg->message.choice.c1->present == NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete) { - if (ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->criticalExtensions.present == - NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete) - rrc_gNB_process_RRCReconfigurationComplete( - ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); - } - - if (get_softmodem_params()->sa) { - if (UE->pdu_session_release_command_flag == 1) { - xid = ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier; - UE->pdu_session_release_command_flag = 0; - //gtp tunnel delete - gtpv1u_gnb_delete_tunnel_req_t req={0}; - for(i = 0; i < NB_RB_MAX; i++) { - if (xid == UE->pduSession[i].xid) { - req.pdusession_id[req.num_pdusession++] = UE->gnb_gtp_psi[i]; - UE->gnb_gtp_teid[i] = 0; - memset(&UE->gnb_gtp_addrs[i], 0, sizeof(UE->gnb_gtp_addrs[i])); - UE->gnb_gtp_psi[i] = 0; - } - } - gtpv1u_delete_ngu_tunnel(ctxt_pP->instance, &req); - //NGAP_PDUSESSION_RELEASE_RESPONSE - rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid); - } else if (UE->established_pdu_sessions_flag != 1) { - if (UE->reestablishment_xid < 0) { - if (UE->nb_of_pdusessions > 0) { - rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); - } - } else { - UE->reestablishment_xid = -1; - } - } - if (UE->nb_of_modify_pdusessions > 0) { - rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); - UE->nb_of_modify_pdusessions = 0; - UE->nb_of_failed_pdusessions = 0; - memset(UE->modify_pdusession, 0, sizeof(UE->modify_pdusession)); - - for(int i = 0; i < NR_NB_RB_MAX; i++) { - UE->modify_pdusession[i].xid = -1; - } - } - } - if (first_rrcreconfiguration == 0){ - first_rrcreconfiguration = 1; - rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); - } - + handle_rrcReconfigurationComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete); break; case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete: - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing NR_RRCSetupComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); - break; - } - - LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC SetupComplete\n"); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(RRCSetupComplete) ---> RRC_gNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.present == - NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete) { - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value != NULL) { - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI_Part2) { - // ng-5G-S-TMSI-Part2 BIT STRING (SIZE (9)) - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size != 2) { - LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part2 size, expected 2, provided %lu", - (long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> - criticalExtensions.choice.rrcSetupComplete-> - ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size); - return -1; - } - - if (UE->ng_5G_S_TMSI_Part1 != 0) { - UE->ng_5G_S_TMSI_Part2 = - BIT_STRING_to_uint16(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2); - } - - /* TODO */ - } else if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI) { - // NG-5G-S-TMSI ::= BIT STRING (SIZE (48)) - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size != 6) { - LOG_E(NR_RRC, "wrong ng_5G_S_TMSI size, expected 6, provided %lu", - (long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> - criticalExtensions.choice.rrcSetupComplete-> - ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size); - return -1; - } - - uint64_t fiveg_s_TMSI = bitStr_to_uint64(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> - criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI); - LOG_I(NR_RRC, "Received rrcSetupComplete, 5g_s_TMSI: 0x%lX, amf_set_id: 0x%lX(%ld), amf_pointer: 0x%lX(%ld), 5g TMSI: 0x%X \n", - fiveg_s_TMSI, fiveg_s_TMSI >> 38, fiveg_s_TMSI >> 38, - (fiveg_s_TMSI >> 32) & 0x3F, (fiveg_s_TMSI >> 32) & 0x3F, - (uint32_t)fiveg_s_TMSI); - if (UE->Initialue_identity_5g_s_TMSI.presence == true) { - UE->Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38; - UE->Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F; - UE->Initialue_identity_5g_s_TMSI.fiveg_tmsi = (uint32_t)fiveg_s_TMSI; - } - } - } - - rrc_gNB_process_RRCSetupComplete( - ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.rrcSetupComplete); - LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" UE State = NR_RRC_CONNECTED \n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - } - - UE->ue_release_timer = 0; + if (handle_rrcSetupComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete) == -1) + return -1; break; case NR_UL_DCCH_MessageType__c1_PR_measurementReport: @@ -2114,43 +2204,41 @@ rrc_gNB_decode_dcch( rrc_gNB_process_MeasurementReport(ue_context_p, ul_dcch_msg->message.choice.c1->choice.measurementReport); break; - case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: - LOG_I(NR_RRC,"Recived RRC GNB UL Information Transfer \n"); - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); - break; - } + case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: + LOG_I(NR_RRC, "Recived RRC GNB UL Information Transfer \n"); + if (!ue_context_p) { + LOG_I(NR_RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); + break; + } - LOG_D(NR_RRC,"[MSG] RRC UL Information Transfer \n"); - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC UL Information Transfer \n"); + LOG_D(NR_RRC, "[MSG] RRC UL Information Transfer \n"); + LOG_DUMPMSG(RRC, DEBUG_RRC, (char *)Rx_sdu, sdu_sizeP, "[MSG] RRC UL Information Transfer \n"); - if (get_softmodem_params()->sa) { - rrc_gNB_send_NGAP_UPLINK_NAS(ctxt_pP, - ue_context_p, - ul_dcch_msg); - } - break; + if (get_softmodem_params()->sa) { + rrc_gNB_send_NGAP_UPLINK_NAS(ctxt_pP, ue_context_p, ul_dcch_msg); + } + break; - case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete: + case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete: // to avoid segmentation fault - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing securityModeComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); - break; - } + if (!ue_context_p) { + LOG_I(NR_RRC, "Processing securityModeComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); + break; + } LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" received securityModeComplete on UL-DCCH %d from UE\n", + PROTOCOL_NR_RRC_CTXT_UE_FMT " received securityModeComplete on UL-DCCH %d from UE\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), DCCH); LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + PROTOCOL_NR_RRC_CTXT_UE_FMT + " RLC RB %02d --- RLC_DATA_IND %d bytes " "(securityModeComplete) ---> RRC_eNB\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), DCCH, sdu_sizeP); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); } @@ -2159,178 +2247,35 @@ rrc_gNB_decode_dcch( rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); break; - case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure: - LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] NR RRC Security Mode Failure\n"); - LOG_W(NR_RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(securityModeFailure) ---> RRC_gNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); - } - - rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); - break; - - case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing ueCapabilityInformation UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); - break; - } - - LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] NR_RRC UECapablility Information\n"); - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" received ueCapabilityInformation on UL-DCCH %d from UE\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH); - LOG_D(RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(UECapabilityInformation) ---> RRC_eNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); - } - LOG_I(NR_RRC, "got UE capabilities for UE %lx\n", ctxt_pP->rntiMaybeUEid); - int eutra_index = -1; - - if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present == - NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation ) { - for(i = 0;i < ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count; i++){ - if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_nr){ - if (UE->UE_Capability_nr) { - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); - UE->UE_Capability_nr = 0; - } - - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_NR_Capability, - (void **)&UE->UE_Capability_nr, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.buf, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.size, - 0, - 0); - if(LOG_DEBUGFLAG(DEBUG_ASN1)){ - xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); - } - - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ - LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_UE_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); - UE->UE_Capability_nr = 0; - } - - UE->UE_Capability_size = ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.size; - if(eutra_index != -1){ - LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n"); - exit(1); - } - eutra_index = i; - } - - if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_eutra_nr){ - if (UE->UE_Capability_MRDC) { - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); - UE->UE_Capability_MRDC = 0; - } - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_MRDC_Capability, - (void **)&UE->UE_Capability_MRDC, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.buf, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.size, - 0, - 0); - - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); - } - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ - LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); - UE->UE_Capability_MRDC = 0; - } - UE->UE_MRDC_Capability_size = - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i] - ->ue_CapabilityRAT_Container.size; - } - - if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_eutra){ - //TODO - } - } - - if(eutra_index == -1) - break; - } - if (get_softmodem_params()->sa) { - rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(ctxt_pP, - ue_context_p, - ul_dcch_msg); - } - - // we send the UE capabilities request before RRC connection is complete, - // so we cannot have a PDU session yet - AssertFatal(UE->established_pdu_sessions_flag == 0, "logic bug: received capabilities while PDU session established\n"); - // TODO: send UE context modification response with UE capabilities to - // allow DU configure CellGroupConfig - rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); - - break; - - case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: { - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)Rx_sdu, sdu_sizeP, "[MSG] NR_RRC Connection Reestablishment Complete\n"); - LOG_I(NR_RRC, "RLC RB %02d --- RLC_DATA_IND %d bytes (rrcReestablishmentComplete) ---> RRC_gNB\n", DCCH, sdu_sizeP); - - rnti_t reestablish_rnti = 0; - - // Select C-RNTI from map - for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; - LOG_I(NR_RRC, "nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x, ctxt_pP->rntiMaybeUEid: %lx\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti, ctxt_pP->rntiMaybeUEid); - if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { - LOG_I(NR_RRC, "Removing nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); - reestablish_rnti = nr_reestablish_rnti_map->c_rnti; - ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, reestablish_rnti); - UE = &ue_context_p->ue_context; - break; - } - } + case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure: + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)Rx_sdu, sdu_sizeP, "[MSG] NR RRC Security Mode Failure\n"); + LOG_W(NR_RRC, + PROTOCOL_RRC_CTXT_UE_FMT + " RLC RB %02d --- RLC_DATA_IND %d bytes " + "(securityModeFailure) ---> RRC_gNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); - if (!ue_context_p) { - LOG_E(NR_RRC, "NR_RRCReestablishmentComplete without UE context, fault\n"); - break; + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); } - if (ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->criticalExtensions.present == NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete) { - rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP, reestablish_rnti, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->rrc_TransactionIdentifier); - - nr_rrc_mac_remove_ue(reestablish_rnti); + rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); + break; - UE->ue_reestablishment_counter++; - } + case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: + if (handle_ueCapabilityInformation(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation) + == -1) + return -1; + break; - // UE->ue_release_timer = 0; - UE->ue_reestablishment_timer = 1; - // remove UE after 100 frames after NR_RRCReestablishmentRelease is triggered - UE->ue_reestablishment_timer_thres = 1000; - } break; + case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: + if (handle_rrcReestablishmentComplete(ctxt_pP, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete) + == -1) + return -1; + break; default: break; @@ -2663,7 +2608,8 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i } // send the F1 response message up to update F1-U tunnel info - rrc->cucp_cuup.bearer_context_mod(&req, instance); + // it seems the rrc transaction id (xid) is not needed here + rrc->cucp_cuup.bearer_context_mod(&req, instance, 0); NR_CellGroupConfig_t *cellGroupConfig = NULL; diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.c b/openair2/RRC/NR/rrc_gNB_GTPV1U.c index 1322317b3e7704ec5a062b9c9db83d1ae04ba40c..e7bbe5835effa61b2cc90af9701c36cb578acd77 100644 --- a/openair2/RRC/NR/rrc_gNB_GTPV1U.c +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.c @@ -58,14 +58,14 @@ int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_ return -1; } for (int i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) { - ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i]; - ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr; - ue_context_p->ue_context.gnb_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i]; + ue_context_p->ue_context.nsa_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i]; + ue_context_p->ue_context.nsa_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr; + ue_context_p->ue_context.nsa_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i]; LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT " rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->enb_S1u_teid[i], - ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]], + ue_context_p->ue_context.nsa_gtp_teid[inde_list[i]], inde_list[i], i, create_tunnel_resp_pP->eps_bearer_id[i], @@ -90,14 +90,14 @@ int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ct } for (int i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) { - ue_context_p->ue_context.gnb_gtp_teid[i + offset] = create_tunnel_resp_pP->gnb_NGu_teid[i]; - ue_context_p->ue_context.gnb_gtp_addrs[i + offset] = create_tunnel_resp_pP->gnb_addr; - ue_context_p->ue_context.gnb_gtp_psi[i + offset] = create_tunnel_resp_pP->pdusession_id[i]; + ue_context_p->ue_context.pduSession[i + offset].param.gNB_teid_N3 = create_tunnel_resp_pP->gnb_NGu_teid[i]; + ue_context_p->ue_context.pduSession[i + offset].param.gNB_addr_N3 = create_tunnel_resp_pP->gnb_addr; + AssertFatal(ue_context_p->ue_context.pduSession[i + offset].param.pdusession_id == create_tunnel_resp_pP->pdusession_id[i], ""); LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT " nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, id %u, gtp addr len %d \n", + PROTOCOL_NR_RRC_CTXT_UE_FMT + " nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u) bearer UE context index %u, id %u, gtp addr len %d \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->gnb_NGu_teid[i], - ue_context_p->ue_context.gnb_gtp_teid[i + offset], i, create_tunnel_resp_pP->pdusession_id[i], create_tunnel_resp_pP->gnb_addr.length); diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 1f37210b9c25f403e760c6cf8f3c4f4b13eca5e4..102fb56091bce50a6c2f37d03a40791bf91e6ee5 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -319,7 +319,8 @@ static int decodePDUSessionResourceSetup(pdusession_t *session) /* mandatory PDUSessionType */ case NGAP_ProtocolIE_ID_id_PDUSessionType: - session->upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; + session->pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; + AssertFatal(session->pdu_session_type == PDUSessionType_ipv4, "To be developped: support not IPv4 sessions\n"); break; /* optional SecurityIndication */ @@ -405,7 +406,6 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t } nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt, &create_tunnel_resp, 0); - UE->established_pdu_sessions_flag = 1; } /* NAS PDU */ @@ -448,9 +448,11 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const c if (session->status == PDU_SESSION_STATUS_DONE) { pdu_sessions_done++; resp->pdusessions[pdusession].pdusession_id = session->param.pdusession_id; - resp->pdusessions[pdusession].gtp_teid = UE->gnb_gtp_teid[pdusession]; - memcpy(resp->pdusessions[pdusession].gNB_addr.buffer, UE->gnb_gtp_addrs[pdusession].buffer, 20); - resp->pdusessions[pdusession].gNB_addr.length = 4; + resp->pdusessions[pdusession].gtp_teid = session->param.gNB_teid_N3; + memcpy(resp->pdusessions[pdusession].gNB_addr.buffer, + session->param.gNB_addr_N3.buffer, + sizeof(resp->pdusessions[pdusession].gNB_addr.buffer)); + resp->pdusessions[pdusession].gNB_addr.length = 4; // Fixme: IPv4 hard coded here resp->pdusessions[pdusession].nb_of_qos_flow = session->param.nb_qos; for (int qos_flow_index = 0; qos_flow_index < session->param.nb_qos; qos_flow_index++) { resp->pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi = session->param.qos[qos_flow_index].qfi; @@ -679,10 +681,10 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( pdusession_setup_t *tmp = &resp->pdusessions[pdu_sessions_done]; tmp->pdusession_id = session->param.pdusession_id; tmp->nb_of_qos_flow = session->param.nb_qos; - tmp->gtp_teid = UE->gnb_gtp_teid[pdusession]; - tmp->gNB_addr.pdu_session_type = PDUSessionType_ipv4; - tmp->gNB_addr.length = UE->gnb_gtp_addrs[pdusession].length; - memcpy(tmp->gNB_addr.buffer, UE->gnb_gtp_addrs[pdusession].buffer, tmp->gNB_addr.length); + tmp->gtp_teid = session->param.gNB_teid_N3; + tmp->pdu_session_type = session->param.pdu_session_type; // FixMe: IPv4 hardcoded here + tmp->gNB_addr.length = session->param.gNB_addr_N3.length; + memcpy(tmp->gNB_addr.buffer, session->param.gNB_addr_N3.buffer, tmp->gNB_addr.length); for (int qos_flow_index = 0; qos_flow_index < tmp->nb_of_qos_flow; qos_flow_index++) { tmp->associated_qos_flows[qos_flow_index].qfi = session->param.qos[qos_flow_index].qfi; tmp->associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL; @@ -729,15 +731,13 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance) //------------------------------------------------------------------------------ { - gNB_RRC_INST *rrc; - rrc_gNB_ue_context_t *ue_context_p = NULL; protocol_ctxt_t ctxt={0}; ngap_pdusession_setup_req_t* msg=&NGAP_PDUSESSION_SETUP_REQ(msg_p); - ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], msg->gNB_ue_ngap_id); + 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; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); - rrc = RC.nrrrc[ctxt.module_id]; + gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, msg->gNB_ue_ngap_id); if (ue_context_p == NULL) { @@ -759,6 +759,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins pdusession_t *session = &pduSession->param; LOG_I(NR_RRC, "Adding pdusession %d, total nb of sessions %d\n", session->pdusession_id, UE->nb_of_pdusessions); session->pdusession_id = msg->pdusession_setup_params[i].pdusession_id; + session->pdu_session_type = msg->pdusession_setup_params[i].pdu_session_type; session->nas_pdu = msg->pdusession_setup_params[i].nas_pdu; session->pdusessionTransfer = msg->pdusession_setup_params[i].pdusessionTransfer; decodePDUSessionResourceSetup(session); @@ -818,7 +819,9 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins } } } - rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance); + int xid = rrc_gNB_get_next_transaction_identifier(instance); + UE->xids[xid] = RRC_PDUSESSION_ESTABLISH; + rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance, xid); return; } @@ -929,50 +932,46 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins gNB_RRC_UE_t *UE = &ue_context_p->ue_context; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); ctxt.eNB_index = 0; - uint8_t nb_of_failed_pdusessions = 0; - + bool all_failed = true; for (int i = 0; i < req->nb_pdusessions_tomodify; i++) { - int j; - for (j = 0; j < UE->nb_of_pdusessions; j++) - if (UE->modify_pdusession[j].param.pdusession_id == req->pdusession_modify_params[j].pdusession_id) + rrc_pdu_session_param_t *sess; + const pdusession_t *sessMod = req->pdusession_modify_params + i; + for (sess = UE->pduSession; sess < UE->pduSession + UE->nb_of_pdusessions; sess++) + if (sess->param.pdusession_id == sessMod->pdusession_id) break; - if (j == UE->nb_of_pdusessions) { - LOG_W(NR_RRC, "To finish, modify a not existing pdu session\n"); - // handle multiple pdu session id - LOG_D(NR_RRC, "handle multiple pdu session id \n"); - UE->modify_pdusession[j].status = PDU_SESSION_STATUS_NEW; - UE->modify_pdusession[j].param.pdusession_id = req->pdusession_modify_params[j].pdusession_id; - UE->modify_pdusession[j].cause = NGAP_CAUSE_RADIO_NETWORK; - UE->modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; - nb_of_failed_pdusessions++; + if (sess == UE->pduSession + UE->nb_of_pdusessions) { + LOG_W(NR_RRC, "Requested modification of non-existing PDU session, refusing modification\n"); + 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; } else { - UE->modify_pdusession[j].status = PDU_SESSION_STATUS_NEW; - UE->modify_pdusession[j].param.pdusession_id = req->pdusession_modify_params[i].pdusession_id; - UE->modify_pdusession[j].cause = NGAP_CAUSE_RADIO_NETWORK; - UE->modify_pdusession[j].cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances; - UE->modify_pdusession[j].status = PDU_SESSION_STATUS_NEW; - UE->modify_pdusession[j].param.pdusession_id = req->pdusession_modify_params[i].pdusession_id; - UE->modify_pdusession[j].cause = NGAP_CAUSE_NOTHING; - if (req->pdusession_modify_params[i].nas_pdu.buffer != NULL) { - UE->modify_pdusession[i].param.nas_pdu = req->pdusession_modify_params[i].nas_pdu; + 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->status = PDU_SESSION_STATUS_NEW; + sess->param.pdusession_id = sessMod->pdusession_id; + sess->cause = NGAP_CAUSE_NOTHING; + if (sessMod->nas_pdu.buffer != NULL) { + UE->pduSession[i].param.nas_pdu = sessMod->nas_pdu; } // Save new pdu session parameters, qos, upf addr, teid - decodePDUSessionResourceModify(&UE->modify_pdusession[j].param, UE->modify_pdusession[i].param.pdusessionTransfer); - UE->modify_pdusession[j].param.upf_addr = UE->pduSession[j].param.upf_addr; - UE->modify_pdusession[j].param.gtp_teid = UE->pduSession[j].param.gtp_teid; + decodePDUSessionResourceModify(&sess->param, UE->pduSession[i].param.pdusessionTransfer); + sess->param.UPF_addr_N3 = sessMod->upf_addr; + sess->param.UPF_teid_N3 = sessMod->gtp_teid; } } - UE->nb_of_modify_pdusessions = req->nb_pdusessions_tomodify - nb_of_failed_pdusessions; - UE->nb_of_failed_pdusessions = nb_of_failed_pdusessions; - - if (UE->nb_of_failed_pdusessions < UE->nb_of_modify_pdusessions) { + if (!all_failed) { LOG_D(NR_RRC, "generate RRCReconfiguration \n"); rrc_gNB_modify_dedicatedRRCReconfiguration(&ctxt, ue_context_p); - } else { // all pdu modification failed - LOG_I(NR_RRC, "pdu session modify failed, fill NGAP_PDUSESSION_MODIFY_RESP with the pdu session information that failed to modify \n"); - MessageDef *msg_fail_p = NULL; - msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP); + } else { + LOG_I(NR_RRC, + "pdu session modify failed, fill NGAP_PDUSESSION_MODIFY_RESP with the pdu session information that failed to modify \n"); + MessageDef *msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP); if (msg_fail_p == NULL) { LOG_E(NR_RRC, "itti_alloc_new_message failed, msg_fail_p is NULL \n"); return (-1); @@ -981,21 +980,16 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins msg->gNB_ue_ngap_id = req->gNB_ue_ngap_id; msg->nb_of_pdusessions = 0; - for (int i = 0; i < UE->nb_of_failed_pdusessions; i++) { - msg->pdusessions_failed[i].pdusession_id = UE->modify_pdusession[i].param.pdusession_id; - msg->pdusessions_failed[i].cause = UE->modify_pdusession[i].cause; - msg->pdusessions_failed[i].cause_value = UE->modify_pdusession[i].cause_value; + 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->nb_of_pdusessions_failed = UE->nb_of_failed_pdusessions; itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); - UE->nb_of_modify_pdusessions = 0; - UE->nb_of_failed_pdusessions = 0; - memset(UE->modify_pdusession, 0, sizeof(UE->modify_pdusession)); - return (0); } - - return 0; + return (0); } //------------------------------------------------------------------------------ @@ -1022,63 +1016,63 @@ rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP( resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; - for (int i = 0; i < UE->nb_of_modify_pdusessions; i++) { - if (xid != UE->modify_pdusession[i].xid) { - LOG_W(NR_RRC, "xid does not correspond (context pdu session index %d, status %d, xid %d/%d) \n ", i, UE->modify_pdusession[i].status, xid, UE->modify_pdusession[i].xid); + for (int i = 0; i < UE->nb_of_pdusessions; i++) { + if (xid != UE->pduSession[i].xid) { + LOG_W(NR_RRC, "xid does not correspond (context pdu session index %d, status %d, xid %d/%d) \n ", i, UE->pduSession[i].status, xid, UE->pduSession[i].xid); continue; } - if (UE->modify_pdusession[i].status == PDU_SESSION_STATUS_DONE) { - rrc_pdu_session_param_t *pduSession = find_pduSession(UE, UE->modify_pdusession[i].param.pdusession_id, false); + if (UE->pduSession[i].status == PDU_SESSION_STATUS_DONE) { + rrc_pdu_session_param_t *pduSession = find_pduSession(UE, UE->pduSession[i].param.pdusession_id, false); if (pduSession) { 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; - for (int qos_flow_index = 0; qos_flow_index < UE->modify_pdusession[i].param.nb_qos; qos_flow_index++) { - pduSession->param.qos[qos_flow_index] = UE->modify_pdusession[i].param.qos[qos_flow_index]; + 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]; } - resp->pdusessions[pdu_sessions_done].pdusession_id = UE->modify_pdusession[i].param.pdusession_id; - for (int qos_flow_index = 0; qos_flow_index < UE->modify_pdusession[i].param.nb_qos; qos_flow_index++) { - resp->pdusessions[pdu_sessions_done].qos[qos_flow_index].qfi = UE->modify_pdusession[i].param.qos[qos_flow_index].qfi; + resp->pdusessions[pdu_sessions_done].pdusession_id = UE->pduSession[i].param.pdusession_id; + for (int qos_flow_index = 0; qos_flow_index < UE->pduSession[i].param.nb_qos; qos_flow_index++) { + resp->pdusessions[pdu_sessions_done].qos[qos_flow_index].qfi = UE->pduSession[i].param.qos[qos_flow_index].qfi; } - resp->pdusessions[pdu_sessions_done].pdusession_id = UE->modify_pdusession[i].param.pdusession_id; - resp->pdusessions[pdu_sessions_done].nb_of_qos_flow = UE->modify_pdusession[i].param.nb_qos; + resp->pdusessions[pdu_sessions_done].pdusession_id = UE->pduSession[i].param.pdusession_id; + resp->pdusessions[pdu_sessions_done].nb_of_qos_flow = UE->pduSession[i].param.nb_qos; LOG_I(NR_RRC, - "Modify Resp (msg index %d, pdu session index %d, status %d, xid %d): nb_of_modify_pdusessions %d, pdusession_id %d \n ", + "Modify Resp (msg index %d, pdu session index %d, status %d, xid %d): nb_of_pduSessions %d, pdusession_id %d \n ", pdu_sessions_done, i, - UE->modify_pdusession[i].status, + UE->pduSession[i].status, xid, - UE->nb_of_modify_pdusessions, + UE->nb_of_pdusessions, resp->pdusessions[pdu_sessions_done].pdusession_id); pdu_sessions_done++; } else { - LOG_W(NR_RRC, "PDU SESSION modify of a not existing pdu session %d \n", UE->modify_pdusession[i].param.pdusession_id); - resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->modify_pdusession[i].param.pdusession_id; + 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; pdu_sessions_failed++; } - } else if ((UE->modify_pdusession[i].status == PDU_SESSION_STATUS_NEW) || (UE->modify_pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED)) { + } 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->modify_pdusession[i].status == PDU_SESSION_STATUS_FAILED) { - resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->modify_pdusession[i].param.pdusession_id; - resp->pdusessions_failed[pdu_sessions_failed].cause = UE->modify_pdusession[i].cause; - resp->pdusessions_failed[pdu_sessions_failed].cause_value = UE->modify_pdusession[i].cause_value; + } 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; pdu_sessions_failed++; } else LOG_W(NR_RRC, "Modify pdu session %d, unknown state %d \n ", - UE->modify_pdusession[i].param.pdusession_id, - UE->modify_pdusession[i].status); + UE->pduSession[i].param.pdusession_id, + UE->pduSession[i].status); } resp->nb_of_pdusessions = pdu_sessions_done; resp->nb_of_pdusessions_failed = pdu_sessions_failed; if (pdu_sessions_done > 0 || pdu_sessions_failed > 0) { - LOG_D(NR_RRC, "NGAP_PDUSESSION_MODIFY_RESP: sending the message: nb_of_pdusessions %d, total pdu session %d\n", UE->nb_of_modify_pdusessions, UE->nb_of_pdusessions); + LOG_D(NR_RRC, "NGAP_PDUSESSION_MODIFY_RESP: sending the message (total pdu session %d)\n", UE->nb_of_pdusessions); itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); } else { itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); @@ -1179,22 +1173,19 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE( itti_send_msg_to_task(TASK_NGAP, instance, msg); } -void -rrc_gNB_send_NGAP_UE_CAPABILITIES_IND( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - NR_UL_DCCH_Message_t *const ul_dcch_msg -) +void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + const NR_UECapabilityInformation_t *const ue_cap_info) //------------------------------------------------------------------------------ { - NR_UE_CapabilityRAT_ContainerList_t *ueCapabilityRATContainerList = ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList; - /* 4096 is arbitrary, should be big enough */ - void *buf; - NR_UERadioAccessCapabilityInformation_t rac = {0}; - gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; + NR_UE_CapabilityRAT_ContainerList_t *ueCapabilityRATContainerList = + ue_cap_info->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList; + void *buf; + NR_UERadioAccessCapabilityInformation_t rac = {0}; + gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; - if (ueCapabilityRATContainerList->list.count == 0) { - LOG_W(RRC, "[gNB %d][UE %x] bad UE capabilities\n", ctxt_pP->module_id, UE->rnti); + if (ueCapabilityRATContainerList->list.count == 0) { + LOG_W(RRC, "[gNB %d][UE %x] bad UE capabilities\n", ctxt_pP->module_id, UE->rnti); } int ret = uper_encode_to_new_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, NULL, ueCapabilityRATContainerList, &buf); @@ -1242,31 +1233,21 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( memset(resp, 0, sizeof(*resp)); resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; - for (int i = 0; i < NB_RB_MAX; i++) { + for (int i = 0; i < UE->nb_of_pdusessions; i++) { if (xid == UE->pduSession[i].xid) { resp->pdusession_release[pdu_sessions_released].pdusession_id = UE->pduSession[i].param.pdusession_id; pdu_sessions_released++; //clear memset(&UE->pduSession[i], 0, sizeof(*UE->pduSession)); + UE->pduSession[i].status = PDU_SESSION_STATUS_RELEASED; + LOG_W(NR_RRC, "Released pdu session, but code to finish to free memory\n"); } } resp->nb_of_pdusessions_released = pdu_sessions_released; - resp->nb_of_pdusessions_failed = UE->nb_release_of_pdusessions; - memcpy(resp->pdusessions_failed, UE->pdusessions_release_failed, sizeof(pdusession_failed_t) * UE->nb_release_of_pdusessions); - LOG_E(NR_RRC, "we have to pack the array!!!\n"); - UE->nb_of_pdusessions -= pdu_sessions_released; + resp->nb_of_pdusessions_failed = 0; LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_ID %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, pdu_sessions_released); itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); - - //clear xid - for(int i = 0; i < NB_RB_MAX; i++) { - UE->pduSession[i].xid = -1; - } - - //clear release pdusessions - UE->nb_release_of_pdusessions = 0; - memset(UE->pdusessions_release_failed, 0, sizeof(UE->pdusessions_release_failed)); } //------------------------------------------------------------------------------ @@ -1275,8 +1256,6 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_ { uint32_t gNB_ue_ngap_id; protocol_ctxt_t ctxt; - uint8_t xid; - uint8_t pdusession_release_drb = 0; ngap_pdusession_release_command_t *cmd = &NGAP_PDUSESSION_RELEASE_COMMAND(msg_p); gNB_ue_ngap_id = cmd->gNB_ue_ngap_id; if (cmd->nb_pdusessions_torelease > NGAP_MAX_PDUSESSION) { @@ -1293,18 +1272,21 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_ LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, gNB_ue_ngap_id); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); - xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id); LOG_I( NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %u release_pdusessions %d \n", cmd->amf_ue_ngap_id, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease); - + bool found = false; + uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id); + UE->xids[xid] = RRC_PDUSESSION_RELEASE; for (int pdusession = 0; pdusession < cmd->nb_pdusessions_torelease; pdusession++) { rrc_pdu_session_param_t *pduSession = find_pduSession(UE, cmd->pdusession_release_params[pdusession].pdusession_id, false); if (!pduSession) { - LOG_I(NR_RRC, "no pdusession_id \n"); - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].pdusession_id = cmd->pdusession_release_params[pdusession].pdusession_id; - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK; - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause_value = 30; - UE->nb_release_of_pdusessions++; + LOG_I(NR_RRC, "no pdusession_id, AMF requested to close it id=%d\n", cmd->pdusession_release_params[pdusession].pdusession_id); + 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; + pduSession->xid = xid; continue; } if (pduSession->status == PDU_SESSION_STATUS_FAILED) { @@ -1312,37 +1294,22 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_ continue; } if (pduSession->status == PDU_SESSION_STATUS_ESTABLISHED) { + found = true; LOG_I(NR_RRC, "RELEASE pdusession %d \n", pduSession->param.pdusession_id); pduSession->status = PDU_SESSION_STATUS_TORELEASE; pduSession->xid = xid; - pdusession_release_drb++; - continue; } - // pdusession_id status NG - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].pdusession_id = cmd->pdusession_release_params[pdusession].pdusession_id; - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK; - UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause_value = 0; - UE->nb_release_of_pdusessions++; } - if (pdusession_release_drb > 0) { + if (found) { // TODO RRCReconfiguration To UE LOG_I(NR_RRC, "Send RRCReconfiguration To UE \n"); rrc_gNB_generate_dedicatedRRCReconfiguration_release(&ctxt, ue_context_p, xid, cmd->nas_pdu.length, cmd->nas_pdu.buffer); } else { // gtp tunnel delete - LOG_I(NR_RRC, "gtp tunnel delete \n"); + LOG_I(NR_RRC, "gtp tunnel delete all tunnels for UE %04x\n", UE->rnti); gtpv1u_gnb_delete_tunnel_req_t req = {0}; req.ue_id = UE->rnti; - - for (int i = 0; i < NB_RB_MAX; i++) { - if (xid == UE->pduSession[i].xid) { - req.pdusession_id[req.num_pdusession++] = UE->gnb_gtp_psi[i]; - UE->gnb_gtp_teid[i] = 0; - memset(&UE->gnb_gtp_addrs[i], 0, sizeof(UE->gnb_gtp_addrs[i])); - UE->gnb_gtp_psi[i] = 0; - } - } gtpv1u_delete_ngu_tunnel(instance, &req); // NGAP_PDUSESSION_RELEASE_RESPONSE rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(&ctxt, ue_context_p, xid); diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h index a0c42dcaaf465e130363d5f12bd0b443381c6f83..25e79746328f6dd6834a9462ea3610f2a2be50f3 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.h +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -96,12 +96,9 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, uint32_t gNB_ue_ngap_id); -void -rrc_gNB_send_NGAP_UE_CAPABILITIES_IND( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - NR_UL_DCCH_Message_t *const ul_dcch_msg -); +void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + const NR_UECapabilityInformation_t *const ue_cap_info); int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance); diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 137ed695f5f3bd0c265d926936c79afbd6b3f846..b7f7e189ae7666c6aa1739053651c426389d2712 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -68,11 +68,8 @@ rrc_gNB_ue_context_t *rrc_gNB_allocate_new_ue_context(gNB_RRC_INST *rrc_instance } new_p->ue_context.gNB_ue_ngap_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator); - for(int i = 0; i < NB_RB_MAX; i++) { - new_p->ue_context.e_rab[i].xid = -1; + for(int i = 0; i < NB_RB_MAX; i++) new_p->ue_context.pduSession[i].xid = -1; - new_p->ue_context.modify_e_rab[i].xid = -1; - } LOG_I(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.gNB_ue_ngap_id); return(new_p); diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 250402a2cfa3ce97c0ee3db982dd05c3c8673a8b..a8d9241b7f5675c57822d646943cca7bb7f41c5f 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -411,11 +411,11 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { tmp.from_gnb=1; LOG_D(RRC, "ue_context->ue_context.nb_of_e_rabs %d will be deleted for rnti %d\n", ue_context->ue_context.nb_of_e_rabs, rnti); for (e_rab = 0; e_rab < ue_context->ue_context.nb_of_e_rabs; e_rab++) { - tmp.eps_bearer_id[tmp.num_erab++]= ue_context->ue_context.gnb_gtp_ebi[e_rab]; + tmp.eps_bearer_id[tmp.num_erab++]= ue_context->ue_context.nsa_gtp_ebi[e_rab]; // erase data - ue_context->ue_context.gnb_gtp_teid[e_rab] = 0; - memset(&ue_context->ue_context.gnb_gtp_addrs[e_rab], 0, sizeof(ue_context->ue_context.gnb_gtp_addrs[e_rab])); - ue_context->ue_context.gnb_gtp_ebi[e_rab] = 0; + ue_context->ue_context.nsa_gtp_teid[e_rab] = 0; + memset(&ue_context->ue_context.nsa_gtp_addrs[e_rab], 0, sizeof(ue_context->ue_context.nsa_gtp_addrs[e_rab])); + ue_context->ue_context.nsa_gtp_ebi[e_rab] = 0; } gtpv1u_delete_s1u_tunnel(rrc->module_id, &tmp); /* remove context */ diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 069f3ce48bb19ae80853043e74a2c2ee987e454a..15f4b4b37654dce04a70867b24695f37b7fe82c9 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -58,7 +58,7 @@ static void allocCopy(OCTET_STRING_t *out, ngap_pdu_t in) out->size = in.length; } -static void allocAddrCopy(BIT_STRING_t *out, ngap_transport_layer_addr_t in) +static void allocAddrCopy(BIT_STRING_t *out, transport_layer_addr_t in) { if (in.length) { out->buf = malloc(in.length); diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index d8e1dc231414f106d49504806fbed116628c725b..5a75b8953ae291be852835a3edac08b2dd60fb02 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -762,6 +762,7 @@ int gtpv1u_create_ngu_tunnel(const instance_t instance, create_tunnel_resp->gnb_NGu_teid[i]=teid; memcpy(create_tunnel_resp->gnb_addr.buffer,addr,sizeof(addr)); create_tunnel_resp->gnb_addr.length= sizeof(addr); + create_tunnel_resp->pdusession_id[i] = create_tunnel_req->pdusession_id[i]; } return !GTPNOK;