diff --git a/ci-scripts/conf_files/gNB_SA_CU.conf b/ci-scripts/conf_files/gNB_SA_CU.conf index a757bb8ccd..d619c8311b 100644 --- a/ci-scripts/conf_files/gNB_SA_CU.conf +++ b/ci-scripts/conf_files/gNB_SA_CU.conf @@ -169,7 +169,7 @@ gNBs = ////////// AMF parameters: - amf_ip_address = ( { ipv4 = "192.168.5.233"; + amf_ip_address = ( { ipv4 = "192.168.70.132"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -178,11 +178,10 @@ gNBs = NETWORK_INTERFACES : { - - GNB_INTERFACE_NAME_FOR_NG_AMF = "eth0"; - GNB_IPV4_ADDRESS_FOR_NG_AMF = "CI_GNB_IP_ADDR"; - GNB_INTERFACE_NAME_FOR_NGU = "eth0"; - GNB_IPV4_ADDRESS_FOR_NGU = "CI_GNB_IP_ADDR"; + GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24"; + GNB_INTERFACE_NAME_FOR_NGU = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 }; } diff --git a/common/ngran_types.h b/common/ngran_types.h index ddd1ec2cca..95ad167961 100644 --- a/common/ngran_types.h +++ b/common/ngran_types.h @@ -54,4 +54,7 @@ typedef enum { CPtype = 0, UPtype } E1_t; #define NODE_IS_DU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_DU || (nOdE_TyPe) == ngran_gNB_DU) #define NODE_IS_MBMS(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_MBMS_STA) #define GTPV1_U_PORT_NUMBER (2152) + +typedef enum { non_dynamic, dynamic } fiveQI_type_t; +#define maxSRBs 4 #endif diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index b7c19f6c8e..3f4930d02b 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -49,7 +49,7 @@ static int get_single_ue_rnti(void) return -1; // verify it exists in RRC as well - rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context(RC.nrrrc[0], ue->rnti); + rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], ue->rnti); if (!rrcue) return -1; @@ -82,7 +82,7 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt) ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n"); } - rrc_gNB_ue_context_t *ue = rrc_gNB_get_ue_context(RC.nrrrc[0], rnti); + rrc_gNB_ue_context_t *ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); if (!ue) ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); @@ -107,7 +107,7 @@ int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) } // verify it exists in RRC as well - rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context(RC.nrrrc[0], rnti); + rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); if (!rrcue) ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 941d95b044..7a88344efc 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -24,6 +24,7 @@ #ifndef E1AP_MESSAGES_TYPES_H #define E1AP_MESSAGES_TYPES_H +#include "common/ngran_types.h" #include "f1ap_messages_types.h" #include "ngap_messages_types.h" diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 70412e8368..87426eff98 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -29,7 +29,7 @@ #ifndef NGAP_MESSAGES_TYPES_H_ #define NGAP_MESSAGES_TYPES_H_ - +#include "common/ngran_types.h" #include "LTE_asn_constant.h" //-------------------------------------------------------------------------------------------// // Defines to access message fields. @@ -49,7 +49,7 @@ #define NGAP_UE_CTXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_resp #define NGAP_UE_CTXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_fail #define NGAP_PDUSESSION_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_resp -#define NGAP_PDUSESSION_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_req_fail +#define NGAP_PDUSESSION_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_request_fail #define NGAP_PDUSESSION_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_modify_resp #define NGAP_PATH_SWITCH_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_path_switch_req #define NGAP_PATH_SWITCH_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.ngap_path_switch_req_ack @@ -194,6 +194,13 @@ typedef enum ngap_rrc_establishment_cause_e { NGAP_RRC_CAUSE_LAST } ngap_rrc_establishment_cause_t; +typedef struct pdusession_level_qos_parameter_s { + uint8_t qfi; + uint64_t fiveQI; + fiveQI_type_t fiveQI_type; + ngap_allocation_retention_priority_t allocation_retention_priority; +} pdusession_level_qos_parameter_t; + typedef struct ngap_guami_s { uint16_t mcc; uint16_t mnc; @@ -242,7 +249,7 @@ typedef struct ngap_nas_pdu_s { uint8_t *buffer; /* Length of the octet string */ uint32_t length; -} ngap_nas_pdu_t, ngap_ue_radio_cap_t; +} ngap_pdu_t; typedef struct ngap_mobility_restriction_s{ ngap_plmn_identity_t serving_plmn; @@ -267,43 +274,22 @@ typedef struct ngap_transport_layer_addr_s { uint8_t buffer[20]; // in network byte order } ngap_transport_layer_addr_t; -#define TRANSPORT_LAYER_ADDR_COPY(dEST,sOURCE) \ - do { \ - AssertFatal(sOURCE.len <= 20); \ - memcpy(dEST.buffer, sOURCE.buffer, sOURCE.len); \ - dEST.length = sOURCE.length; \ - } while (0) - -typedef enum { - non_dynamic, - dynamic -} fiveQI_type_t; - -typedef struct pdusession_level_qos_parameter_s { - uint8_t qfi; - uint64_t fiveQI; - fiveQI_type_t fiveQI_type; - ngap_allocation_retention_priority_t allocation_retention_priority; -} pdusession_level_qos_parameter_t; - typedef struct pdusession_s { /* Unique pdusession_id for the UE. */ - uint8_t pdusession_id; - - uint8_t nb_qos; + int pdusession_id; + ngap_pdu_t nas_pdu; + ngap_pdu_t pdusessionTransfer; + uint8_t nb_qos; /* Quality of service for this pdusession */ pdusession_level_qos_parameter_t qos[QOSFLOW_MAX_VALUE]; - /* The NAS PDU should be forwarded by the RRC layer to the NAS layer */ - ngap_nas_pdu_t nas_pdu; /* The transport layer address for the IP packets */ - ngap_transport_layer_addr_t upf_addr; + ngap_transport_layer_addr_t upf_addr; /* S-GW Tunnel endpoint identifier */ - uint32_t gtp_teid; + 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]; + uint8_t used_drbs[NGAP_MAX_DRBS_PER_UE]; } pdusession_t; - typedef enum pdusession_qosflow_mapping_ind_e{ QOSFLOW_MAPPING_INDICATION_UL = 0, QOSFLOW_MAPPING_INDICATION_DL = 1, @@ -313,7 +299,7 @@ typedef enum pdusession_qosflow_mapping_ind_e{ typedef struct pdusession_associate_qosflow_s{ uint8_t qfi; pdusession_qosflow_mapping_ind_t qos_flow_mapping_ind; -}pdusession_associate_qosflow_t; +} pdusession_associate_qosflow_t; typedef struct pdusession_setup_s { /* Unique pdusession_id for the UE. */ @@ -332,36 +318,6 @@ typedef struct pdusession_setup_s { pdusession_associate_qosflow_t associated_qos_flows[QOSFLOW_MAX_VALUE]; } pdusession_setup_t; -typedef struct pdusession_tobe_added_s { - /* Unique pdusession_id for the UE. */ - uint8_t pdusession_id; - - /* Unique drb_ID for the UE. */ - uint8_t drb_ID; - - /* The transport layer address for the IP packets */ - ngap_transport_layer_addr_t upf_addr; - - /* S-GW Tunnel endpoint identifier */ - uint32_t gtp_teid; -} pdusession_tobe_added_t; - -typedef struct pdusession_admitted_tobe_added_s { - /* Unique pdusession_id for the UE. */ - uint8_t pdusession_id; - - /* Unique drb_ID for the UE. */ - uint8_t drb_ID; - - /* The transport layer address for the IP packets */ - ngap_transport_layer_addr_t gnb_addr; - - /* S-GW Tunnel endpoint identifier */ - uint32_t gtp_teid; -} pdusession_admitted_tobe_added_t; - - - typedef struct pdusession_tobeswitched_s { /* Unique pdusession_id for the UE. */ uint8_t pdusession_id; @@ -394,9 +350,12 @@ typedef enum ngap_Cause_e { NGAP_CAUSE_NAS, NGAP_CAUSE_PROTOCOL, NGAP_CAUSE_MISC, - /* Extensions may appear below */ - -} ngap_Cause_t; + NGAP_Cause_PR_choice_ExtensionS, + //Evilish manual duplicate of asn.1 grammar + //because it is human work, whereas it can be generated by machine + //and because humans manual copy creates bugs + //and we create multiple names for the same thing, that is a source of confusion +} ngap_Cause_t; typedef enum ngap_Cause_radio_network_e { NGAP_CAUSE_RADIO_NETWORK_UNSPECIFIED, @@ -453,7 +412,6 @@ typedef struct pdusession_failed_s { /* Unique pdusession_id for the UE. */ uint8_t pdusession_id; /* Cause of the failure */ - // cause_t cause; ngap_Cause_t cause; uint8_t cause_value; } pdusession_failed_t; @@ -541,7 +499,7 @@ typedef struct ngap_deregistered_gnb_ind_s { */ typedef struct ngap_nas_first_req_s { /* UE id for initial connection to NGAP */ - uint16_t ue_initial_id; + uint32_t gNB_ue_ngap_id; /* the chosen PLMN identity as index, see TS 36.331 6.2.2 RRC Connection * Setup Complete. This index here is zero-based, unlike the standard! */ @@ -551,7 +509,7 @@ typedef struct ngap_nas_first_req_s { ngap_rrc_establishment_cause_t establishment_cause; /* NAS PDU */ - ngap_nas_pdu_t nas_pdu; + ngap_pdu_t nas_pdu; /* If this flag is set NGAP layer is expecting the GUAMI. If = 0, * the temporary s-tmsi is used. @@ -561,15 +519,14 @@ typedef struct ngap_nas_first_req_s { typedef struct ngap_uplink_nas_s { /* Unique UE identifier within an gNB */ - uint32_t gNB_ue_ngap_id; - + uint32_t gNB_ue_ngap_id; /* NAS pdu */ - ngap_nas_pdu_t nas_pdu; + ngap_pdu_t nas_pdu; } ngap_uplink_nas_t; typedef struct ngap_ue_cap_info_ind_s { uint32_t gNB_ue_ngap_id; - ngap_ue_radio_cap_t ue_radio_cap; + ngap_pdu_t ue_radio_cap; } ngap_ue_cap_info_ind_t; typedef struct ngap_initial_context_setup_resp_s { @@ -594,7 +551,7 @@ typedef struct ngap_initial_context_setup_fail_s { typedef struct ngap_nas_non_delivery_ind_s { uint32_t gNB_ue_ngap_id; - ngap_nas_pdu_t nas_pdu; + ngap_pdu_t nas_pdu; /* TODO: add cause */ } ngap_nas_non_delivery_ind_t; @@ -621,33 +578,24 @@ typedef struct ngap_ue_ctxt_modification_resp_s { } ngap_ue_ctxt_modification_resp_t; typedef struct ngap_ue_release_complete_s { - uint32_t gNB_ue_ngap_id; - } ngap_ue_release_complete_t; //-------------------------------------------------------------------------------------------// // NGAP -> RRC messages typedef struct ngap_downlink_nas_s { /* UE id for initial connection to NGAP */ - uint16_t ue_initial_id; - - /* Unique UE identifier within an gNB */ - uint32_t gNB_ue_ngap_id; - + uint32_t gNB_ue_ngap_id; /* NAS pdu */ - ngap_nas_pdu_t nas_pdu; + ngap_pdu_t nas_pdu; } ngap_downlink_nas_t; typedef struct ngap_initial_context_setup_req_s { /* UE id for initial connection to NGAP */ - uint16_t ue_initial_id; - - /* gNB ue ngap id as initialized by NGAP layer */ uint32_t gNB_ue_ngap_id; - uint64_t amf_ue_ngap_id:40; + uint64_t amf_ue_ngap_id; /* UE aggregate maximum bitrate */ ngap_ambr_t ue_ambr; @@ -676,7 +624,7 @@ typedef struct ngap_initial_context_setup_req_s { /* Nas Pdu */ uint8_t nas_pdu_flag; - ngap_nas_pdu_t nas_pdu; + ngap_pdu_t nas_pdu; } ngap_initial_context_setup_req_t; @@ -702,17 +650,22 @@ typedef struct ngap_paging_ind_s { ngap_paging_priority_t paging_priority; } ngap_paging_ind_t; +typedef struct { + /* Unique pdusession_id for the UE. */ + int pdusession_id; + ngap_pdu_t nas_pdu; + ngap_pdu_t pdusessionTransfer; +} pdusession_setup_req_t; + typedef struct ngap_pdusession_setup_req_s { /* UE id for initial connection to NGAP */ - uint16_t ue_initial_id; + uint32_t gNB_ue_ngap_id; /* AMF UE id */ - uint64_t amf_ue_ngap_id:40; - - /* gNB ue ngap id as initialized by NGAP layer */ - uint32_t gNB_ue_ngap_id; + uint64_t amf_ue_ngap_id; /* S-NSSAI */ + // Fixme: illogical, nssai is part of each pdu session ngap_allowed_NSSAI_t allowed_nssai[8]; /* Number of pdusession to be setup in the list */ @@ -730,8 +683,7 @@ typedef struct ngap_pdusession_setup_req_s { } ngap_pdusession_setup_req_t; typedef struct ngap_pdusession_setup_resp_s { - uint32_t gNB_ue_ngap_id; - + uint32_t gNB_ue_ngap_id; /* Number of pdusession setup-ed in the list */ uint8_t nb_of_pdusessions; /* list of pdusession setup-ed by RRC layers */ @@ -744,7 +696,6 @@ typedef struct ngap_pdusession_setup_resp_s { } ngap_pdusession_setup_resp_t; typedef struct ngap_path_switch_req_s { - uint32_t gNB_ue_ngap_id; /* Number of pdusession setup-ed in the list */ @@ -754,13 +705,12 @@ typedef struct ngap_path_switch_req_s { pdusession_setup_t pdusessions_tobeswitched[NGAP_MAX_PDUSESSION]; /* AMF UE id */ - uint64_t amf_ue_ngap_id:40; + uint64_t amf_ue_ngap_id; ngap_guami_t ue_guami; uint16_t ue_initial_id; - - /* Security algorithms */ + /* Security algorithms */ ngap_security_capabilities_t security_capabilities; } ngap_path_switch_req_t; @@ -773,7 +723,7 @@ typedef struct ngap_path_switch_req_ack_s { uint32_t gNB_ue_ngap_id; /* AMF UE id */ - uint64_t amf_ue_ngap_id:40; + uint64_t amf_ue_ngap_id; /* UE aggregate maximum bitrate */ ngap_ambr_t ue_ambr; @@ -801,7 +751,7 @@ typedef struct ngap_pdusession_modification_ind_s { uint32_t gNB_ue_ngap_id; /* AMF UE id */ - uint64_t amf_ue_ngap_id:40; + uint64_t amf_ue_ngap_id; /* Number of pdusession setup-ed in the list */ uint8_t nb_of_pdusessions_tobemodified; @@ -830,10 +780,7 @@ typedef struct ngap_ue_release_command_s { typedef struct pdusession_release_s { /* Unique pdusession_id for the UE. */ uint8_t pdusession_id; - /* Octet string data */ - uint8_t *transfer_buffer; - /* Length of the octet string */ - uint32_t transfer_length; + ngap_pdu_t data; } pdusession_release_t; typedef struct ngap_ue_release_req_s { @@ -842,16 +789,13 @@ typedef struct ngap_ue_release_req_s { uint8_t nb_of_pdusessions; /* list of pdusession resource by RRC layers */ pdusession_release_t pdusessions[NGAP_MAX_PDUSESSION]; - ngap_Cause_t cause; + ngap_Cause_t cause; long cause_value; } ngap_ue_release_req_t, ngap_ue_release_resp_t; typedef struct ngap_pdusession_modify_req_s { - /* UE id for initial connection to NGAP */ - uint16_t ue_initial_id; - /* AMF UE id */ - uint64_t amf_ue_ngap_id:40; + uint64_t amf_ue_ngap_id; /* gNB ue ngap id as initialized by NGAP layer */ uint32_t gNB_ue_ngap_id; @@ -879,13 +823,13 @@ typedef struct ngap_pdusession_modify_resp_s { typedef struct ngap_pdusession_release_command_s { /* AMF UE id */ - uint64_t amf_ue_ngap_id:40; + uint64_t amf_ue_ngap_id; /* gNB ue ngap id as initialized by NGAP layer */ uint32_t gNB_ue_ngap_id; /* The NAS PDU should be forwarded by the RRC layer to the NAS layer */ - ngap_nas_pdu_t nas_pdu; + ngap_pdu_t nas_pdu; /* Number of pdusession to be released in the list */ uint8_t nb_pdusessions_torelease; @@ -897,7 +841,7 @@ typedef struct ngap_pdusession_release_command_s { typedef struct ngap_pdusession_release_resp_s { /* AMF UE id */ - uint64_t amf_ue_ngap_id:40; + uint64_t amf_ue_ngap_id; /* gNB ue ngap id as initialized by NGAP layer */ uint32_t gNB_ue_ngap_id; diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index c6308a4465..c3d5999b62 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -230,8 +230,7 @@ typedef struct protocol_ctxt_s { #define ENB_INSTANCE_TO_MODULE_ID( iNSTANCE )iNSTANCE //NR -#define GNB_MODULE_ID_TO_INSTANCE( mODULE_iD ) mODULE_iD -#define GNB_INSTANCE_TO_MODULE_ID( iNSTANCE )iNSTANCE +#define GNB_MODULE_ID_TO_INSTANCE(mODULE_iD) mODULE_iD #define MODULE_ID_TO_INSTANCE(mODULE_iD, iNSTANCE, eNB_fLAG) \ do { \ diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 2db1ecef65..caf97b680d 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -220,16 +220,15 @@ int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu if (encoded < 0) { LOG_E(E1AP, "%s: Failed to encode E1AP message\n", func); return -1; - } else { - MessageDef *message = itti_alloc_new_message((type==CPtype)?TASK_CUCP_E1:TASK_CUUP_E1, 0, SCTP_DATA_REQ); - sctp_data_req_t *s = &message->ittiMsg.sctp_data_req; - s->assoc_id = setupReq->assoc_id; - s->buffer = buffer; - s->buffer_length = encoded; - s->stream = stream; - LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func); - itti_send_msg_to_task(TASK_SCTP, 0 /*unused by callee*/, message); } + MessageDef *message = itti_alloc_new_message((type == CPtype) ? TASK_CUCP_E1 : TASK_CUUP_E1, 0, SCTP_DATA_REQ); + sctp_data_req_t *s = &message->ittiMsg.sctp_data_req; + s->assoc_id = setupReq->assoc_id; + s->buffer = buffer; + s->buffer_length = encoded; + s->stream = stream; + LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func); + itti_send_msg_to_task(TASK_SCTP, 0 /*unused by callee*/, message); return encoded; } diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index a04524f241..901932f54b 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -57,7 +57,7 @@ static void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_as f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams; f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams; f1ap_cu_data->default_sctp_stream_id = 0; - if (RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type != ngran_gNB_CUCP) { + if (RC.nrrrc[instance]->node_type != ngran_gNB_CUCP) { getCxt(CUtype, instance)->gtpInst = cu_task_create_gtpu_instance(IPaddrs); AssertFatal(getCxt(CUtype, instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener"); } else diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index fea0d9d91c..0cb476b2d7 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -947,13 +947,13 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, GNB_FLAG_YES, rnti, 0, 0, instance); - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], rnti); if (ue_context_p) { MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE); NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id; itti_send_msg_to_task(TASK_NGAP, instance, msg); - rrc_gNB_remove_ue_context(&ctxt, RC.nrrrc[instance], ue_context_p); + rrc_gNB_remove_ue_context(RC.nrrrc[instance], ue_context_p); } else { LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti); } @@ -1600,7 +1600,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); f1ap_ue_context_modification_resp->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; - LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id); + LOG_D(F1AP, "f1ap_ue_context_modification_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id); f1ap_ue_context_modification_resp->rnti = f1ap_get_rnti_by_du_id(CUtype, instance, f1ap_ue_context_modification_resp->gNB_DU_ue_id); diff --git a/openair2/F1AP/f1ap_itti_messaging.c b/openair2/F1AP/f1ap_itti_messaging.c index e45edcc3a3..12386b69d6 100644 --- a/openair2/F1AP/f1ap_itti_messaging.c +++ b/openair2/F1AP/f1ap_itti_messaging.c @@ -31,7 +31,7 @@ void f1ap_itti_send_sctp_data_req(bool isCu, instance_t instance, uint8_t *buffe sctp_data_req->assoc_id = f1ap_assoc_id(isCu,instance); sctp_data_req->buffer = buffer; sctp_data_req->buffer_length = buffer_length; - sctp_data_req->stream = stream; + sctp_data_req->stream = stream; LOG_D(F1AP, "Sending ITTI message to SCTP Task\n"); itti_send_msg_to_task(TASK_SCTP, instance, message_p); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index dd3f7e753a..c7d5b8614c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2810,10 +2810,12 @@ void nr_mac_update_timers(module_id_t module_id, NR_CellGroupConfig_t *cg = NULL; uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, //might be added prefix later + &asn_DEF_NR_CellGroupConfig, // might be added prefix later (void **)&cg, (uint8_t *)UE->cg_buf, - (UE->enc_rval.encoded+7)/8, 0, 0); + (UE->enc_rval.encoded + 7) / 8, + 0, + 0); UE->CellGroup = cg; if (LOG_DEBUGFLAG(DEBUG_ASN1)) { @@ -2918,13 +2920,8 @@ void send_initial_ul_rrc_message(module_id_t module_id, sdu_len, rnti); /* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */ - if (NODE_IS_DU(RC.nrrrc[module_id]->node_type)) { - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[module_id]); - ue_context_p->ue_id_rnti = rnti; - ue_context_p->ue_context.rnti = rnti; - ue_context_p->ue_context.random_ue_identity = rnti; - RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[module_id]->rrc_ue_head, ue_context_p); - } + if (NODE_IS_DU(RC.nrrrc[module_id]->node_type)) + rrc_gNB_create_ue_context(rnti, RC.nrrrc[module_id], rnti); const NR_ServingCellConfigCommon_t *scc = RC.nrrrc[module_id]->carrier.servingcellconfigcommon; const NR_ServingCellConfig_t *sccd = RC.nrrrc[module_id]->configuration.scd; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 7f7077088a..98d4cf8141 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -106,7 +106,7 @@ int dl_rrc_message_rrcSetup(module_id_t module_id, const f1ap_dl_rrc_message_t * /* TODO: drop the RRC context */ gNB_RRC_INST *rrc = RC.nrrrc[module_id]; - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, dl_rrc->rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, dl_rrc->rnti); gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; ue_p->SRB_configList = rrcSetup_ies->radioBearerConfig.srb_ToAddModList; ue_p->masterCellGroup = cellGroup; diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 0e56a5f572..4a88b153bd 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -162,8 +162,7 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, const rnti_t rntiP, const int dl_bwp_id, const int ul_bwp_id) { - - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[module_idP], rntiP); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[module_idP], rntiP); protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, GNB_FLAG_YES, rntiP, frameP, sub_frameP, 0); @@ -177,10 +176,7 @@ void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP, const frame_t frameP, const sub_frame_t subframeP, const rnti_t rntiP) { - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - ue_context_p = rrc_gNB_get_ue_context( - RC.nrrrc[Mod_instP], - rntiP); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[Mod_instP], rntiP); if (ue_context_p != NULL) { LOG_D(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP); @@ -195,8 +191,7 @@ void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP, const frame_t frameP, const sub_frame_t subframeP, const rnti_t rntiP) { - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[Mod_instP], rntiP); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[Mod_instP], rntiP); if (ue_context_p != NULL) { LOG_W(RRC,"Frame %d, Subframe %d: UE %x UL failure reset, deactivating timer\n",frameP,subframeP,rntiP); ue_context_p->ue_context.ul_failure_timer=0; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 198c361733..4f8ee98f58 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1298,27 +1298,24 @@ uint8_t do_NR_SecurityModeCommand( uint8_t *const buffer, const uint8_t Transaction_id, const uint8_t cipheringAlgorithm, - NR_IntegrityProtAlgorithm_t *integrityProtAlgorithm + NR_IntegrityProtAlgorithm_t integrityProtAlgorithm ) //------------------------------------------------------------------------------ { - NR_DL_DCCH_Message_t dl_dcch_msg; + NR_DL_DCCH_Message_t dl_dcch_msg={0}; asn_enc_rval_t enc_rval; - memset(&dl_dcch_msg,0,sizeof(NR_DL_DCCH_Message_t)); dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1; - dl_dcch_msg.message.choice.c1=CALLOC(1,sizeof(struct NR_DL_DCCH_MessageType__c1)); - dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_securityModeCommand; - dl_dcch_msg.message.choice.c1->choice.securityModeCommand = CALLOC(1, sizeof(struct NR_SecurityModeCommand)); - dl_dcch_msg.message.choice.c1->choice.securityModeCommand->rrc_TransactionIdentifier = Transaction_id; - dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.present = NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand; + asn1cCalloc(dl_dcch_msg.message.choice.c1, c1); + c1->present = NR_DL_DCCH_MessageType__c1_PR_securityModeCommand; + asn1cCalloc(c1->choice.securityModeCommand,scm); + scm->rrc_TransactionIdentifier = Transaction_id; + scm->criticalExtensions.present = NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand; - dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.choice.securityModeCommand = - CALLOC(1, sizeof(struct NR_SecurityModeCommand_IEs)); + asn1cCalloc(scm->criticalExtensions.choice.securityModeCommand,scmIE); // the two following information could be based on the mod_id - dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm + scmIE->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm = (NR_CipheringAlgorithm_t)cipheringAlgorithm; - dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm - = integrityProtAlgorithm; + asn1cCallocOne(scmIE->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm, integrityProtAlgorithm); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg); @@ -1332,7 +1329,7 @@ uint8_t do_NR_SecurityModeCommand( AssertFatal(enc_rval.encoded >0 , "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message,&dl_dcch_msg); LOG_D(NR_RRC, "[gNB %d] securityModeCommand for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8); // rrc_ue_process_ueCapabilityEnquiry(0,1000,&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry,0); @@ -1521,10 +1518,7 @@ int16_t do_RRCReconfiguration( } if(cellGroupConfig!=NULL){ - update_cellGroupConfig(cellGroupConfig, - ue_context_pP->local_uid, - ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, - configuration); + update_cellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.gNB_ue_ngap_id, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, NULL, @@ -1754,29 +1748,27 @@ do_NR_DLInformationTransfer( //------------------------------------------------------------------------------ { ssize_t encoded; - NR_DL_DCCH_Message_t dl_dcch_msg; - memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t)); + NR_DL_DCCH_Message_t dl_dcch_msg={0}; dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1; - dl_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_DCCH_MessageType__c1)); - dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer; + asn1cCalloc(dl_dcch_msg.message.choice.c1, c1); + c1->present = NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer; - dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer = CALLOC(1, sizeof(NR_DLInformationTransfer_t)); - dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->rrc_TransactionIdentifier = transaction_id; - dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->criticalExtensions.present = + asn1cCalloc(c1->choice.dlInformationTransfer, infoTransfer); + infoTransfer->rrc_TransactionIdentifier = transaction_id; + infoTransfer->criticalExtensions.present = NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer; - dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer-> - criticalExtensions.choice.dlInformationTransfer = CALLOC(1, sizeof(NR_DLInformationTransfer_IEs_t)); - dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer-> - criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); - dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer-> - criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message->buf = pdu_buffer; - dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer-> - criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message->size = pdu_length; + asn1cCalloc(infoTransfer->criticalExtensions.choice.dlInformationTransfer, dlInfoTransfer); + asn1cCalloc(dlInfoTransfer->dedicatedNAS_Message,msg); + // we will free the caller buffer, that is ok in the present code logic (else it will leak memory) but not natural, + // comprehensive code design + msg->buf = pdu_buffer; + msg->size = pdu_length; encoded = uper_encode_to_new_buffer (&asn_DEF_NR_DL_DCCH_Message, NULL, (void *) &dl_dcch_msg, (void **)buffer); AssertFatal(encoded > 0,"ASN1 message encoding failed (%s, %ld)!\n", "DLInformationTransfer", encoded); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message,&dl_dcch_msg ); LOG_D(NR_RRC,"DLInformationTransfer Encoded %zd bytes\n", encoded); //for (int i=0;iue_context.nb_of_pdusessions - 1; - pdu_session_param_t *pdu = ue_context_p->ue_context.pduSession + i; - create_tunnel_req.pdusession_id[0] = pdu->param.pdusession_id; - create_tunnel_req.incoming_rb_id[0] = i + 1; - create_tunnel_req.outgoing_qfi[0] = req->pduSession[i].DRBnGRanList[0].qosFlows[0].id; - memcpy(&create_tunnel_req.dst_addr[0].buffer, &pdu->param.upf_addr.buffer, sizeof(create_tunnel_req.dst_addr[0].buffer)); - create_tunnel_req.dst_addr[0].length = pdu->param.upf_addr.length; - create_tunnel_req.outgoing_teid[0] = pdu->param.gtp_teid; - - create_tunnel_req.num_tunnels = 1; - create_tunnel_req.ue_id = ue_context_p->ue_context.rnti; + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + LOG_W(NR_RRC, "recreate existing tunnels, while adding new ones\n"); + for (int i = 0; i < UE->nb_of_pdusessions; i++) { + rrc_pdu_session_param_t *pdu = UE->pduSession + i; + create_tunnel_req.pdusession_id[i] = pdu->param.pdusession_id; + create_tunnel_req.incoming_rb_id[i] = i + 1; + create_tunnel_req.outgoing_qfi[i] = req->pduSession[i].DRBnGRanList[0].qosFlows[0].id; + memcpy(&create_tunnel_req.dst_addr[i].buffer, &pdu->param.upf_addr.buffer, sizeof(create_tunnel_req.dst_addr[0].buffer)); + create_tunnel_req.dst_addr[i].length = pdu->param.upf_addr.length; + create_tunnel_req.outgoing_teid[i] = pdu->param.gtp_teid; + } + create_tunnel_req.num_tunnels = UE->nb_of_pdusessions; + create_tunnel_req.ue_id = UE->rnti; int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3, &create_tunnel_req, &create_tunnel_resp); if (ret != 0) { @@ -127,7 +128,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, return ret; } - nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_p, &create_tunnel_resp, i); + nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_p, &create_tunnel_resp, 0); uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; @@ -135,39 +136,27 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, uint8_t *kUPint = NULL; /* Derive the keys from kgnb */ if (DRB_configList != NULL) { - nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, - ue_context_p->ue_context.kgnb, - &kUPenc); - nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm, - ue_context_p->ue_context.kgnb, - &kUPint); + nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc); + nr_derive_key_up_int(UE->integrity_algorithm, UE->kgnb, &kUPint); } - nr_derive_key_rrc_enc(ue_context_p->ue_context.ciphering_algorithm, - ue_context_p->ue_context.kgnb, - &kRRCenc); - nr_derive_key_rrc_int(ue_context_p->ue_context.integrity_algorithm, - ue_context_p->ue_context.kgnb, - &kRRCint); + nr_derive_key_rrc_enc(UE->ciphering_algorithm, UE->kgnb, &kRRCenc); + nr_derive_key_rrc_int(UE->integrity_algorithm, UE->kgnb, &kRRCint); /* Refresh SRBs/DRBs */ - LOG_D(NR_RRC,"Configuring PDCP DRBs/SRBs for UE %x\n",ue_context_p->ue_context.rnti); + LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %x\n", UE->rnti); - nr_pdcp_add_srbs(ctxt_p->enb_flag, ctxt_p->rntiMaybeUEid, - SRB_configList, - (ue_context_p->ue_context.integrity_algorithm << 4) - | ue_context_p->ue_context.ciphering_algorithm, - kRRCenc, - kRRCint); - - nr_pdcp_add_drbs(ctxt_p->enb_flag, ctxt_p->rntiMaybeUEid, 0, + nr_pdcp_add_srbs(ctxt_p->enb_flag, ctxt_p->rntiMaybeUEid, SRB_configList, (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, kRRCenc, kRRCint); + + nr_pdcp_add_drbs(ctxt_p->enb_flag, + ctxt_p->rntiMaybeUEid, + 0, DRB_configList, - (ue_context_p->ue_context.integrity_algorithm << 4) - | ue_context_p->ue_context.ciphering_algorithm, + (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, kUPenc, kUPint, - get_softmodem_params()->sa ? ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); - + get_softmodem_params()->sa ? UE->masterCellGroup->rlc_BearerToAddModList : NULL); + return ret; } @@ -187,17 +176,18 @@ 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) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti); + 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_context_p->ue_context.rnti, 0, 0, 0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); fill_DRB_configList(&ctxt, ue_context_p); gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; // Fixme: xid not random, but almost! - NR_SRB_ToAddModList_t **SRB_configList2 = generateSRB2_confList(&ue_context_p->ue_context, ue_context_p->ue_context.SRB_configList, ue_context_p->ue_context.pduSession[0].xid); + NR_SRB_ToAddModList_t **SRB_configList2 = generateSRB2_confList(UE, UE->SRB_configList, UE->pduSession[0].xid); // GTP tunnel for UL - int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, ue_context_p->ue_context.DRB_configList, *SRB_configList2, rrc->e1_inst); + int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, UE->DRB_configList, *SRB_configList2, rrc->e1_inst); if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n"); if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) { @@ -208,7 +198,7 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; // GTP tunnel for DL - fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, ue_context_p->ue_context.rnti, remote_port, my_addr); + fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rnti, remote_port, my_addr); prepare_and_send_ue_context_modification_f1(ue_context_p, &resp); } diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index 069629db0b..a3311b2ee1 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -36,7 +36,7 @@ extern RAN_CONTEXT_t RC; static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti); + 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); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index c50bbbbe05..7da8b44af7 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -269,7 +269,7 @@ typedef struct pdu_session_param_s { uint8_t xid; // transaction_id ngap_Cause_t cause; uint8_t cause_value; -} __attribute__ ((__packed__)) pdu_session_param_t; +} rrc_pdu_session_param_t; typedef struct gNB_RRC_UE_s { uint8_t primaryCC_id; @@ -281,8 +281,7 @@ typedef struct gNB_RRC_UE_s { uint8_t DRB_active[NGAP_MAX_DRBS_PER_UE]; NR_SRB_INFO SI; - NR_SRB_INFO_TABLE_ENTRY Srb1; - NR_SRB_INFO_TABLE_ENTRY Srb2; + NR_SRB_INFO_TABLE_ENTRY Srb[maxSRBs]; // 3gpp max is 3 SRBs, number 1..3, we waste the entry 0 for code simplicity NR_MeasConfig_t *measConfig; NR_HANDOVER_INFO *handover_info; NR_MeasResults_t *measResults; @@ -332,7 +331,7 @@ typedef struct gNB_RRC_UE_s { /* Information from S1AP initial_context_setup_req */ uint32_t gNB_ue_s1ap_id :24; uint32_t gNB_ue_ngap_id; - uint64_t amf_ue_ngap_id:40; + uint64_t amf_ue_ngap_id; nr_rrc_guami_t ue_guami; ngap_security_capabilities_t security_capabilities; @@ -350,11 +349,11 @@ typedef struct gNB_RRC_UE_s { /* Number of e_rab to be modified in the list */ uint8_t nb_of_modify_pdusessions; uint8_t nb_of_failed_pdusessions; - pdu_session_param_t modify_pdusession[NR_NB_RB_MAX]; + 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]; - pdu_session_param_t pduSession[NGAP_MAX_PDU_SESSION]; + 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]; @@ -396,23 +395,13 @@ typedef struct gNB_RRC_UE_s { struct NR_PhysicalCellGroupConfig *physicalCellGroupConfig; /* Nas Pdu */ - uint8_t nas_pdu_flag; - ngap_nas_pdu_t nas_pdu; + ngap_pdu_t nas_pdu; } gNB_RRC_UE_t; typedef struct rrc_gNB_ue_context_s { /* Tree related data */ RB_ENTRY(rrc_gNB_ue_context_s) entries; - - /* Uniquely identifies the UE between MME and eNB within the eNB. - * This id is encoded on 24bits. - */ - ue_id_t ue_id_rnti; - - // another key for protocol layers but should not be used as a key for RB tree - uid_t local_uid; - /* UE id for initial connection to NGAP */ struct gNB_RRC_UE_s ue_context; } rrc_gNB_ue_context_t; @@ -492,13 +481,7 @@ typedef struct gNB_RRC_INST_s { eth_params_t eth_params_s; rrc_gNB_carrier_data_t carrier; uid_allocator_t uid_allocator; - RB_HEAD(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s) rrc_ue_head; // ue_context tree key search by rnti - int Nb_ue; - hash_table_t *initial_id2_s1ap_ids; // key is content is rrc_ue_s1ap_ids_t - hash_table_t *s1ap_id2_s1ap_ids ; // key is content is rrc_ue_s1ap_ids_t - hash_table_t *initial_id2_ngap_ids; - hash_table_t *ngap_id2_ngap_ids ; - + RB_HEAD(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s) rrc_ue_head; // ue_context tree key search by rnti /// NR cell id uint64_t nr_cellid; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index cac95239e5..eb2b73a642 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -64,11 +64,11 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge( rrc_gNB_ue_context_t *const ue_context_pP ); -struct rrc_gNB_ue_context_s *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP); +rrc_gNB_ue_context_t *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP); void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t * cg_config_info); -void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m); +void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m); void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti); @@ -163,12 +163,6 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP const int dl_bwp_id, const int ul_bwp_id); -int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, - const uint8_t *buffer, - int buffer_length, - const uint8_t *du_to_cu_rrc_container, - int du_to_cu_rrc_container_length); - void rrc_gNB_generate_dedicatedRRCReconfiguration_release( const protocol_ctxt_t *const ctxt_pP, @@ -217,9 +211,5 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, uint8_t *const kUPint, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); -int rrc_gNB_generate_pcch_msg(uint32_t tmsi, - uint8_t paging_drx, - instance_t instance, - uint8_t CC_id); - +int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id); #endif diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index e2c3b3d2d2..ba2402bf12 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -193,9 +193,10 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration pthread_mutex_unlock(&rrc->cell_info_mutex); if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) { - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc); - ue_context_p->ue_context.spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig)); - ue_context_p->ue_context.spCellConfig->spCellConfigDedicated = configuration->scd; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + UE->spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig)); + UE->spCellConfig->spCellConfigDedicated = configuration->scd; LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p); if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) { rrc_add_nsa_user(rrc,ue_context_p,NULL); @@ -241,14 +242,9 @@ static void openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_Rrc AssertFatal(NUMBER_OF_UE_MAX < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow"); AssertFatal(configuration!=NULL,"configuration input is null\n"); rrc->module_id = gnb_mod_idP; - rrc->Nb_ue = 0; rrc_gNB_CU_DU_init(rrc); uid_linear_allocator_init(&rrc->uid_allocator); RB_INIT(&rrc->rrc_ue_head); - rrc->initial_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); - rrc->s1ap_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); - rrc->initial_id2_ngap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); - rrc->ngap_id2_ngap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); rrc->configuration = *configuration; rrc->carrier.servingcellconfigcommon = configuration->scc; rrc->carrier.servingcellconfig = configuration->scd; @@ -324,27 +320,21 @@ void apply_macrlc_config_reest(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue } //----------------------------------------------------------------------------- -static void rrc_gNB_generate_RRCSetup(const protocol_ctxt_t *const ctxt_pP, +static void rrc_gNB_generate_RRCSetup(instance_t instance, + rnti_t rnti, rrc_gNB_ue_context_t *const ue_context_pP, const uint8_t *masterCellGroup, int masterCellGroup_len, NR_ServingCellConfigCommon_t *scc) //----------------------------------------------------------------------------- { - LOG_I(NR_RRC, "rrc_gNB_generate_RRCSetup for RNTI %04lx\n", ctxt_pP->rntiMaybeUEid); + LOG_I(NR_RRC, "rrc_gNB_generate_RRCSetup for RNTI %04x\n", rnti); gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; + gNB_RRC_INST *rrc = RC.nrrrc[instance]; unsigned char buf[1024]; const NR_ServingCellConfig_t *sccd = rrc->configuration.scd; - int size = do_RRCSetup(ue_context_pP, - buf, - rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), - masterCellGroup, - masterCellGroup_len, - scc, - sccd, - &rrc->configuration); + int size = do_RRCSetup(ue_context_pP, buf, rrc_gNB_get_next_transaction_identifier(instance), masterCellGroup, masterCellGroup_len, scc, sccd, &rrc->configuration); AssertFatal(size > 0, "do_RRCSetup failed\n"); AssertFatal(size <= 1024, "memory corruption\n"); @@ -359,7 +349,7 @@ static void rrc_gNB_generate_RRCSetup(const protocol_ctxt_t *const ctxt_pP, ue_context_pP->ue_context.ue_release_timer_thres = 1000; /* TODO: this should go through the E1 interface */ - nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, ue_context_pP->ue_context.SRB_configList, 0, NULL, NULL); + nr_pdcp_add_srbs(true, rnti, ue_context_pP->ue_context.SRB_configList, 0, NULL, NULL); f1ap_dl_rrc_message_t dl_rrc = { .old_gNB_DU_ue_id = 0xFFFFFF, @@ -368,31 +358,24 @@ static void rrc_gNB_generate_RRCSetup(const protocol_ctxt_t *const ctxt_pP, .rnti = ue_p->rnti, .srb_id = CCCH }; - rrc->mac_rrc.dl_rrc_message_transfer(ctxt_pP->module_id, &dl_rrc); + rrc->mac_rrc.dl_rrc_message_transfer(instance, &dl_rrc); } //----------------------------------------------------------------------------- -static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(const protocol_ctxt_t *const ctxt_pP, const int CC_id) +static void 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"); rrc_gNB_ue_context_t *ue_context_pP = NULL; - gNB_RRC_INST *rrc_instance_p = RC.nrrrc[ctxt_pP->module_id]; + gNB_RRC_INST *rrc_instance_p = RC.nrrrc[module_id]; const NR_ServingCellConfigCommon_t *scc=rrc_instance_p->carrier.servingcellconfigcommon; const NR_ServingCellConfig_t *sccd = rrc_instance_p->configuration.scd; - ue_context_pP = rrc_gNB_get_next_free_ue_context(ctxt_pP, rrc_instance_p, 0); + ue_context_pP = rrc_gNB_create_ue_context(rnti, rrc_instance_p, 0); 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(ctxt_pP->module_id), - NULL, - 0, - scc, - sccd, - &rrc_instance_p->configuration); + int size = do_RRCSetup(ue_context_pP, buf, rrc_gNB_get_next_transaction_identifier(module_id), NULL, 0, scc, sccd, &rrc_instance_p->configuration); AssertFatal(size > 0, "do_RRCSetup failed\n"); AssertFatal(size <= 1024, "memory corruption\n"); @@ -403,9 +386,7 @@ static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(const protoc size, "[MSG] RRC Setup\n"); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_D(NR_RRC, "RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB for rnti %04x\n", rnti); // update SCC and MIB/SIB (two calls) nr_mac_config_scc(RC.nrmac[rrc_instance_p->module_id], @@ -417,16 +398,15 @@ static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(const protoc nr_mac_config_mib(RC.nrmac[rrc_instance_p->module_id], &rrc_instance_p->carrier.mib); nr_mac_config_sib1(RC.nrmac[rrc_instance_p->module_id], rrc_instance_p->carrier.siblock1); - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - size); + LOG_I(NR_RRC, " [RAPROC] rnti: %04x Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", rnti, size); // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE ue_context_pP->ue_context.ue_release_timer = 1; // remove UE after 10 frames after RRCConnectionRelease is triggered ue_context_pP->ue_context.ue_release_timer_thres = 1000; // configure MAC - apply_macrlc_config(rrc_instance_p,ue_context_pP,ctxt_pP); + protocol_ctxt_t ctxt = {0}; + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, rnti, 0, 0); + apply_macrlc_config(rrc_instance_p, ue_context_pP, &ctxt); //nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, ue_context_pP->ue_context.SRB_configList, 0, NULL, NULL); //apply_pdcp_config(ue_context_pP,ctxt_pP); @@ -440,18 +420,18 @@ static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(const protoc .rnti = ue_p->rnti, .srb_id = CCCH }; - rrc_instance_p->mac_rrc.dl_rrc_message_transfer(ctxt_pP->module_id, &dl_rrc); + rrc_instance_p->mac_rrc.dl_rrc_message_transfer(module_id, &dl_rrc); } -static void rrc_gNB_generate_RRCReject(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP) +static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context_t *const ue_context_pP) //----------------------------------------------------------------------------- { LOG_I(NR_RRC, "rrc_gNB_generate_RRCReject \n"); - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; + gNB_RRC_INST *rrc = RC.nrrrc[module_id]; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; unsigned char buf[1024]; - int size = do_RRCReject(ctxt_pP->module_id, buf); + int size = do_RRCReject(module_id, buf); AssertFatal(size > 0, "do_RRCReject failed\n"); AssertFatal(size <= 1024, "memory corruption\n"); @@ -459,10 +439,7 @@ static void rrc_gNB_generate_RRCReject(const protocol_ctxt_t *const ctxt_pP, rrc (char *)buf, size, "[MSG] RRCReject \n"); - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating NR_RRCReject (bytes %d)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - size); + LOG_I(NR_RRC, " [RAPROC] ue %04x Logical Channel DL-CCCH, Generating NR_RRCReject (bytes %d)\n", ue_p->rnti, size); f1ap_dl_rrc_message_t dl_rrc = { .gNB_CU_ue_id = 0, @@ -475,7 +452,7 @@ static void rrc_gNB_generate_RRCReject(const protocol_ctxt_t *const ctxt_pP, rrc .execute_duplication = 1, .RAT_frequency_priority_information.en_dc = 0 }; - rrc->mac_rrc.dl_rrc_message_transfer(ctxt_pP->module_id, &dl_rrc); + rrc->mac_rrc.dl_rrc_message_transfer(module_id, &dl_rrc); } //----------------------------------------------------------------------------- @@ -487,9 +464,9 @@ static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p { LOG_A(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing NR_RRCSetupComplete from UE (SRB1 Active)\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - ue_context_pP->ue_context.Srb1.Active = 1; - ue_context_pP->ue_context.Srb1.Srb_info.Srb_id = 1; - ue_context_pP->ue_context.Srb2.Active = 0; + ue_context_pP->ue_context.Srb[1].Active = 1; + ue_context_pP->ue_context.Srb[1].Srb_info.Srb_id = 1; + ue_context_pP->ue_context.Srb[2].Active = 0; ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED; if (get_softmodem_params()->sa) { @@ -503,37 +480,28 @@ static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) //----------------------------------------------------------------------------- { - struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList - *dedicatedNAS_MessageList = NULL; - NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL; - + 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; - dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList)); + struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList)); /* Add all NAS PDUs to the list */ - for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { - if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) { - dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); - OCTET_STRING_fromBuf(dedicatedNAS_Message, - (char *)ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer, - ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length); - asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message); + for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { + if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { + asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg); + OCTET_STRING_fromBuf(msg, (char *)ue_p->pduSession[i].param.nas_pdu.buffer, ue_p->pduSession[i].param.nas_pdu.length); } - ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE; - LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", - i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE"); + ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; + LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE"); } - if (ue_context_pP->ue_context.nas_pdu_flag == 1) { - dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); - OCTET_STRING_fromBuf(dedicatedNAS_Message, - (char *)ue_context_pP->ue_context.nas_pdu.buffer, - ue_context_pP->ue_context.nas_pdu.length); - asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message); + if (ue_p->nas_pdu.length) { + asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg); + OCTET_STRING_fromBuf(msg, (char *)ue_p->nas_pdu.buffer, ue_p->nas_pdu.length); } /* If list is empty free the list and reset the address */ @@ -542,10 +510,8 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co dedicatedNAS_MessageList = NULL; } - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; NR_MeasConfig_t *measconfig = get_defaultMeasConfig(&rrc->configuration); - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; uint8_t buffer[RRC_BUF_SIZE] = {0}; int size = do_RRCReconfiguration(ctxt_pP, buffer, @@ -564,30 +530,26 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co NULL, ue_p->masterCellGroup); AssertFatal(size > 0, "cannot encode RRCReconfiguration in %s()\n", __func__); - LOG_W(RRC, "do_RRCReconfiguration(): size %d\n", size); + LOG_W(NR_RRC, "do_RRCReconfiguration(): size %d\n", size); if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, ue_p->masterCellGroup); } // suspicious if it is always malloced before ? - free(ue_context_pP->ue_context.nas_pdu.buffer); + free(ue_p->nas_pdu.buffer); LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n"); /* Free all NAS PDUs */ - for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { - if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) { - free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer); - ue_context_pP->ue_context.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(ue_p->pduSession[i].param.nas_pdu.buffer); + ue_p->pduSession[i].param.nas_pdu.buffer = NULL; } } - LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %x)\n", - ctxt_pP->module_id, - ctxt_pP->frame, - size, - ue_context_pP->ue_context.rnti); + LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti); switch (RC.nrrrc[ctxt_pP->module_id]->node_type) { case ngran_gNB_CU: case ngran_gNB_CUCP: @@ -616,16 +578,12 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; nr_mac_update_cellgroup(RC.nrmac[rrc->module_id], ue_p->rnti, ue_p->masterCellGroup); - uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup && - ue_context_pP->ue_context.masterCellGroup->spCellConfig && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ? - NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS; + uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated + && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList + ? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS + : NR_RRC_RECONFIGURATION_DELAY_MS; - nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, - ue_context_pP->ue_context.rnti, - *rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, - delay_ms); + nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms); } } @@ -633,135 +591,69 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) { gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - NR_DRB_ToAddModList_t **DRB_configList = NULL; - NR_DRB_ToAddModList_t **DRB_configList2 = NULL; - int qos_flow_index = 0; - int pdu_sessions_done = 0; + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + int qos_flow_index = 0; int i; uint8_t drb_id_to_setup_start = 0; uint8_t nb_drb_to_setup = rrc->configuration.drbs; long drb_priority[NGAP_MAX_DRBS_PER_UE]; - uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); + int xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); - DRB_configList = &ue_context_pP->ue_context.DRB_configList; - if (*DRB_configList) { - free(*DRB_configList); - } - *DRB_configList = CALLOC(1, sizeof(**DRB_configList)); - memset(*DRB_configList, 0, sizeof(**DRB_configList)); - - DRB_configList2 = &ue_context_pP->ue_context.DRB_configList2[xid]; - if (*DRB_configList2) { - free(*DRB_configList2); - } - *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); - memset(*DRB_configList2, 0, sizeof(**DRB_configList2)); - for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { - if (pdu_sessions_done >= ue_context_pP->ue_context.nb_of_pdusessions) { - break; - } - - if (ue_context_pP->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) { + if (!ue_p->DRB_configList) + ue_p->DRB_configList = CALLOC(1, sizeof(*ue_p->DRB_configList)); + else + memset(ue_p->DRB_configList, 0, sizeof(*ue_p->DRB_configList)); + if (!ue_p->DRB_configList2[xid]) + ue_p->DRB_configList2[xid] = CALLOC(1, sizeof(**ue_p->DRB_configList2)); + else + memset(ue_p->DRB_configList2[xid], 0, sizeof(**ue_p->DRB_configList2)); + for (i = 0; i < ue_p->nb_of_pdusessions; i++) { + if (ue_p->pduSession[i].status >= PDU_SESSION_STATUS_DONE) { continue; } - ue_context_pP->ue_context.pduSession[i].xid = xid; - + LOG_I(NR_RRC, "adding rnti %x pdusession %d, nb drb %d, xid %d\n", ue_p->rnti, ue_p->pduSession[i].param.pdusession_id, nb_drb_to_setup, xid); for(long drb_id_add = 1; drb_id_add <= nb_drb_to_setup; drb_id_add++){ uint8_t drb_id; - // Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping - for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[i].param.nb_qos; qos_flow_index++) { - switch (ue_context_pP->ue_context.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 ... 4: /* GBR */ - drb_id = next_available_drb(ue_p, &ue_context_pP->ue_context.pduSession[i], GBR_FLOW); + drb_id = next_available_drb(ue_p, &ue_p->pduSession[i], GBR_FLOW); break; case 5 ... 9: /* Non-GBR */ if(rrc->configuration.drbs > 1) /* Force the creation from gNB Conf file - Should be used only in noS1 mode and rfsim for testing purposes. */ - drb_id = next_available_drb(ue_p, &ue_context_pP->ue_context.pduSession[i], GBR_FLOW); + drb_id = next_available_drb(ue_p, &ue_p->pduSession[i], GBR_FLOW); else - drb_id = next_available_drb(ue_p, &ue_context_pP->ue_context.pduSession[i], NONGBR_FLOW); + drb_id = next_available_drb(ue_p, &ue_p->pduSession[i], NONGBR_FLOW); break; default: - LOG_E(NR_RRC,"not supported 5qi %lu\n", ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].fiveQI); - ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_FAILED; - pdu_sessions_done++; + 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; continue; } - - switch(ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].allocation_retention_priority.priority_level) { - case NGAP_PRIORITY_LEVEL_HIGHEST: - drb_priority[drb_id-1] = 1; - break; - case NGAP_PRIORITY_LEVEL_2: - drb_priority[drb_id-1] = 2; - break; - case NGAP_PRIORITY_LEVEL_3: - drb_priority[drb_id-1] = 3; - break; - case NGAP_PRIORITY_LEVEL_4: - drb_priority[drb_id-1] = 4; - break; - case NGAP_PRIORITY_LEVEL_5: - drb_priority[drb_id-1] = 5; - break; - case NGAP_PRIORITY_LEVEL_6: - drb_priority[drb_id-1] = 6; - break; - case NGAP_PRIORITY_LEVEL_7: - drb_priority[drb_id-1] = 7; - break; - case NGAP_PRIORITY_LEVEL_8: - drb_priority[drb_id-1] = 8; - break; - case NGAP_PRIORITY_LEVEL_9: - drb_priority[drb_id-1] = 9; - break; - case NGAP_PRIORITY_LEVEL_10: - drb_priority[drb_id-1] = 10; - break; - case NGAP_PRIORITY_LEVEL_11: - drb_priority[drb_id-1] = 11; - break; - case NGAP_PRIORITY_LEVEL_12: - drb_priority[drb_id-1] = 12; - break; - case NGAP_PRIORITY_LEVEL_13: - drb_priority[drb_id-1] = 13; - break; - case NGAP_PRIORITY_LEVEL_LOWEST: - drb_priority[drb_id-1] = 14; - break; - case NGAP_PRIORITY_LEVEL_NO_PRIORITY: - drb_priority[drb_id-1] = 15; - break; - - default: - LOG_E(NR_RRC,"Not supported priority level\n"); - break; + drb_priority[drb_id - 1] = ue_p->pduSession[i].param.qos[qos_flow_index].allocation_retention_priority.priority_level; + if (drb_priority[drb_id - 1] < 0 || drb_priority[drb_id - 1] > NGAP_PRIORITY_LEVEL_NO_PRIORITY) { + LOG_E(NR_RRC, "invalid allocation_retention_priority.priority_level %ld set to _NO_PRIORITY\n", drb_priority[drb_id - 1]); + drb_priority[drb_id - 1] = NGAP_PRIORITY_LEVEL_NO_PRIORITY; } if(drb_is_active(ue_p, drb_id)){ /* Non-GBR flow using the same DRB or a GBR flow with no available DRBs*/ nb_drb_to_setup--; } else { - NR_DRB_ToAddMod_t *DRB_config = generateDRB(ue_p, - drb_id, - &ue_context_pP->ue_context.pduSession[i], - rrc->configuration.enable_sdap, - rrc->security.do_drb_integrity, - rrc->security.do_drb_ciphering); - if (drb_id_to_setup_start == 0) drb_id_to_setup_start = DRB_config->drb_Identity; - asn1cSeqAdd(&(*DRB_configList)->list, DRB_config); - asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config); + NR_DRB_ToAddMod_t *DRB_config = generateDRB(ue_p, drb_id, &ue_p->pduSession[i], rrc->configuration.enable_sdap, rrc->security.do_drb_integrity, rrc->security.do_drb_ciphering); + if (drb_id_to_setup_start == 0) + drb_id_to_setup_start = DRB_config->drb_Identity; + asn1cSeqAdd(&ue_p->DRB_configList->list, DRB_config); + asn1cSeqAdd(&ue_p->DRB_configList2[xid]->list, DRB_config); } LOG_D(RRC, "DRB Priority %ld\n", drb_priority[drb_id]); // To supress warning for now } } - ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE; - ue_context_pP->ue_context.pduSession[i].xid = xid; + ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; + ue_p->pduSession[i].xid = xid; } } @@ -780,7 +672,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( int xid = -1; int drb_id_to_setup_start = 1; - NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList; + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList; int nb_drb_to_setup = DRB_configList->list.count; struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL; @@ -791,21 +684,21 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( NR_DRB_ToAddMod_t *DRB_config = DRB_configList->list.array[i]; if (drb_id_to_setup_start == 1) drb_id_to_setup_start = DRB_config->drb_Identity; - int j = ue_context_pP->ue_context.nb_of_pdusessions - 1; + int j = ue_p->nb_of_pdusessions - 1; AssertFatal(j >= 0, ""); - if (ue_context_pP->ue_context.pduSession[j].param.nas_pdu.buffer != NULL) { + if (ue_p->pduSession[j].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_context_pP->ue_context.pduSession[j].param.nas_pdu.buffer, ue_context_pP->ue_context.pduSession[j].param.nas_pdu.length); + OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)ue_p->pduSession[j].param.nas_pdu.buffer, ue_p->pduSession[j].param.nas_pdu.length); asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message); - LOG_I(NR_RRC, "add NAS info with size %d (pdusession idx %d)\n", ue_context_pP->ue_context.pduSession[j].param.nas_pdu.length, j); + LOG_I(NR_RRC, "add NAS info with size %d (pdusession idx %d)\n", ue_p->pduSession[j].param.nas_pdu.length, j); } else { // TODO LOG_E(NR_RRC, "no NAS info (pdusession idx %d)\n", j); } - xid = ue_context_pP->ue_context.pduSession[j].xid; + xid = ue_p->pduSession[j].xid; } /* If list is empty free the list and reset the address */ @@ -818,7 +711,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); // FIXME: fill_mastercellGroupConfig() won't fill the right priorities or // bearer IDs for the DRBs - fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); + fill_mastercellGroupConfig(cellGroupConfig, ue_p->masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); } else{ LOG_I(NR_RRC, "Master cell group originating from the DU \n"); @@ -827,7 +720,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( AssertFatal(xid > -1, "Invalid xid %d. No PDU sessions setup to configure.\n", xid); NR_SRB_ToAddModList_t *SRB_configList2 = NULL; - SRB_configList2 = ue_context_pP->ue_context.SRB_configList2[xid]; + SRB_configList2 = ue_p->SRB_configList2[xid]; uint8_t buffer[RRC_BUF_SIZE] = {0}; int size = do_RRCReconfiguration(ctxt_pP, @@ -849,20 +742,24 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Reconfiguration\n"); /* Free all NAS PDUs */ - for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { - if (ue_context_pP->ue_context.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_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer); - ue_context_pP->ue_context.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; } } - LOG_I(NR_RRC, - "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCReconfiguration (bytes %d, UE RNTI %x)\n", - ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti); LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", - ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); + ctxt_pP->frame, + ctxt_pP->module_id, + size, + ue_p->rnti, + rrc_gNB_mui, + ctxt_pP->module_id, + DCCH); nr_rrc_data_req( ctxt_pP, @@ -876,16 +773,12 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { nr_mac_update_cellgroup(RC.nrmac[rrc->module_id], ue_context_pP->ue_context.rnti, ue_context_pP->ue_context.masterCellGroup); - uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup && - ue_context_pP->ue_context.masterCellGroup->spCellConfig && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ? - NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS; + uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated + && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList + ? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS + : NR_RRC_RECONFIGURATION_DELAY_MS; - nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, - ue_context_pP->ue_context.rnti, - *rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, - delay_ms); + nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms); } } @@ -906,48 +799,48 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( int i, j; uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); - DRB_configList = &ue_context_pP->ue_context.DRB_configList; + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + DRB_configList = &ue_p->DRB_configList; 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_context_pP->ue_context.nb_of_modify_pdusessions; i++) { + for (i = 0; i < ue_p->nb_of_modify_pdusessions; i++) { // bypass the new and already configured pdu sessions - if (ue_context_pP->ue_context.modify_pdusession[i].status >= PDU_SESSION_STATUS_DONE) { - ue_context_pP->ue_context.modify_pdusession[i].xid = xid; + if (ue_p->modify_pdusession[i].status >= PDU_SESSION_STATUS_DONE) { + ue_p->modify_pdusession[i].xid = xid; continue; } - if (ue_context_pP->ue_context.modify_pdusession[i].cause != NGAP_CAUSE_NOTHING) { + if (ue_p->modify_pdusession[i].cause != NGAP_CAUSE_NOTHING) { // set xid of failure pdu session - ue_context_pP->ue_context.modify_pdusession[i].xid = xid; - ue_context_pP->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED; + ue_p->modify_pdusession[i].xid = xid; + ue_p->modify_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_context_pP->ue_context.modify_pdusession[i].param.pdusession_id) { + 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]; break; } } if (DRB_config == NULL) { - ue_context_pP->ue_context.modify_pdusession[i].xid = xid; - ue_context_pP->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED; - ue_context_pP->ue_context.modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_context_pP->ue_context.modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unspecified; - ue_context_pP->ue_context.nb_of_failed_pdusessions++; + 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++; continue; } // Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping - for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.modify_pdusession[i].param.nb_qos; qos_flow_index++) { - switch (ue_context_pP->ue_context.modify_pdusession[i].param.qos[qos_flow_index].fiveQI) { + 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) { case 1: //100ms case 2: //150ms case 3: //50ms @@ -961,41 +854,39 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( break; default: - LOG_E(NR_RRC,"not supported 5qi %lu\n", ue_context_pP->ue_context.modify_pdusession[i].param.qos[qos_flow_index].fiveQI); - ue_context_pP->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED; - ue_context_pP->ue_context.modify_pdusession[i].xid = xid; - ue_context_pP->ue_context.modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_context_pP->ue_context.modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_not_supported_5QI_value; - ue_context_pP->ue_context.nb_of_failed_pdusessions++; + 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++; continue; } - LOG_I(NR_RRC, "PDU SESSION ID %ld, DRB ID %ld (index %d), QOS flow %d, 5QI %ld \n", - DRB_config->cnAssociation->choice.sdap_Config->pdu_Session, - DRB_config->drb_Identity, i, - qos_flow_index, - ue_context_pP->ue_context.modify_pdusession[i].param.qos[qos_flow_index].fiveQI - ); + LOG_I(NR_RRC, + "PDU SESSION ID %ld, DRB ID %ld (index %d), QOS flow %d, 5QI %ld \n", + DRB_config->cnAssociation->choice.sdap_Config->pdu_Session, + DRB_config->drb_Identity, + i, + qos_flow_index, + ue_p->modify_pdusession[i].param.qos[qos_flow_index].fiveQI); } asn1cSeqAdd(&DRB_configList2->list, DRB_config); - ue_context_pP->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_DONE; - ue_context_pP->ue_context.modify_pdusession[i].xid = xid; + ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_DONE; + ue_p->modify_pdusession[i].xid = xid; - if (ue_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.buffer != NULL) { + 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_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.buffer, - ue_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.length); + 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); - LOG_I(NR_RRC,"add NAS info with size %d (pdusession id %d)\n",ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length, - ue_context_pP->ue_context.modify_pdusession[i].param.pdusession_id); + 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); } else { // TODO - LOG_E(NR_RRC,"no NAS info (pdusession id %d)\n", ue_context_pP->ue_context.modify_pdusession[i].param.pdusession_id); + LOG_E(NR_RRC, "no NAS info (pdusession id %d)\n", ue_p->modify_pdusession[i].param.pdusession_id); } } @@ -1025,20 +916,24 @@ 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_context_pP->ue_context.nb_of_modify_pdusessions; i++) { - if (ue_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.buffer != NULL) { + for (i = 0; i < ue_p->nb_of_modify_pdusessions; i++) { + if (ue_p->modify_pdusession[i].param.nas_pdu.buffer != NULL) { /* Free the NAS PDU buffer and invalidate it */ - free(ue_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.buffer); - ue_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.buffer = NULL; + free(ue_p->modify_pdusession[i].param.nas_pdu.buffer); + ue_p->modify_pdusession[i].param.nas_pdu.buffer = NULL; } } - LOG_I(NR_RRC, - "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCReconfiguration (bytes %d, UE RNTI %x)\n", - ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti); LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", - ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); + ctxt_pP->frame, + ctxt_pP->module_id, + size, + ue_p->rnti, + rrc_gNB_mui, + ctxt_pP->module_id, + DCCH); nr_rrc_data_req( ctxt_pP, @@ -1050,16 +945,12 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( PDCP_TRANSMISSION_MODE_CONTROL); if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { - uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup && - ue_context_pP->ue_context.masterCellGroup->spCellConfig && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ? - NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS; + uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated + && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList + ? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS + : NR_RRC_RECONFIGURATION_DELAY_MS; - nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, - ue_context_pP->ue_context.rnti, - *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, - delay_ms); + nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms); } } @@ -1079,15 +970,16 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL; NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL; + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - DRB_Release_configList2 = &ue_context_pP->ue_context.DRB_Release_configList2[xid]; + DRB_Release_configList2 = &ue_p->DRB_Release_configList2[xid]; if (*DRB_Release_configList2) { free(*DRB_Release_configList2); } *DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2)); for(i = 0; i < NB_RB_MAX; i++) { - if((ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pduSession[i].xid == xid) { + if ((ue_p->pduSession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_p->pduSession[i].xid == xid) { DRB_release = CALLOC(1, sizeof(NR_DRB_Identity_t)); *DRB_release = i+1; asn1cSeqAdd(&(*DRB_Release_configList2)->list, DRB_release); @@ -1111,11 +1003,11 @@ 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_context_pP->ue_context.pdu_session_release_command_flag = 1; + ue_p->pdu_session_release_command_flag = 1; LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n"); - ue_context_pP->ue_context.pdu_session_release_command_flag = 1; + ue_p->pdu_session_release_command_flag = 1; /* Free all NAS PDUs */ if (nas_length > 0) { @@ -1123,12 +1015,16 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( free(nas_buffer); } - LOG_I(NR_RRC, - "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE RNTI %x)\n", - ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti); LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", - ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); + ctxt_pP->frame, + ctxt_pP->module_id, + size, + ue_p->rnti, + rrc_gNB_mui, + ctxt_pP->module_id, + DCCH); nr_rrc_data_req( ctxt_pP, DCCH, @@ -1139,16 +1035,12 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( PDCP_TRANSMISSION_MODE_CONTROL); if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { - uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup && - ue_context_pP->ue_context.masterCellGroup->spCellConfig && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ? - NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS; + uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated + && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList + ? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS + : NR_RRC_RECONFIGURATION_DELAY_MS; - nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, - ue_context_pP->ue_context.rnti, - *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, - delay_ms); + nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms); } } @@ -1156,45 +1048,33 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( /* * Process the RRC Reconfiguration Complete from the UE */ -void -rrc_gNB_process_RRCReconfigurationComplete( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - const uint8_t xid -) +static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, const uint8_t xid) { int drb_id; uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; uint8_t *kUPenc = NULL; uint8_t *kUPint = NULL; - NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; - NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; - NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList2[xid]; + NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList2[xid]; + NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_p->DRB_Release_configList2[xid]; NR_DRB_Identity_t *drb_id_p = NULL; // uint8_t nr_DRB2LCHAN[8]; - ue_context_pP->ue_context.ue_reestablishment_timer = 0; + ue_p->ue_reestablishment_timer = 0; /* Derive the keys from kgnb */ if (DRB_configList != NULL) { - nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kgnb, - &kUPenc); - nr_derive_key_up_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kgnb, - &kUPint); + nr_derive_key_up_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kUPenc); + nr_derive_key_up_int(ue_p->integrity_algorithm, ue_p->kgnb, &kUPint); } - nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kgnb, - &kRRCenc); - nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kgnb, - &kRRCint); + nr_derive_key_rrc_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kRRCenc); + nr_derive_key_rrc_int(ue_p->integrity_algorithm, ue_p->kgnb, &kRRCint); /* Refresh SRBs/DRBs */ - LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_context_pP->ue_context.rnti); + LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_p->rnti); ue_id_t reestablish_ue_id = 0; if (DRB_configList && DRB_configList->list.array[0]->reestablishPDCP && *DRB_configList->list.array[0]->reestablishPDCP == NR_DRB_ToAddMod__reestablishPDCP_true) { @@ -1212,51 +1092,44 @@ rrc_gNB_process_RRCReconfigurationComplete( } } - nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, SRB_configList, (ue_context_pP->ue_context.integrity_algorithm << 4) | ue_context_pP->ue_context.ciphering_algorithm, kRRCenc, kRRCint); + nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, SRB_configList, (ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm, kRRCenc, kRRCint); nr_pdcp_add_drbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, reestablish_ue_id, DRB_configList, - (ue_context_pP->ue_context.integrity_algorithm << 4) | ue_context_pP->ue_context.ciphering_algorithm, + (ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm, kUPenc, kUPint, - get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); + get_softmodem_params()->sa ? ue_p->masterCellGroup->rlc_BearerToAddModList : NULL); /* Refresh SRBs/DRBs */ if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { - LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %04x\n",ue_context_pP->ue_context.rnti); + LOG_D(NR_RRC, "Configuring RLC DRBs/SRBs for UE %04x\n", ue_p->rnti); nr_rrc_rlc_config_asn1_req(ctxt_pP, SRB_configList, // NULL, DRB_configList, DRB_Release_configList2, - get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); + get_softmodem_params()->sa ? ue_p->masterCellGroup->rlc_BearerToAddModList : NULL); } /* Set the SRB active in UE context */ if (SRB_configList != NULL) { for (int i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { if (SRB_configList->list.array[i]->srb_Identity == 1) { - ue_context_pP->ue_context.Srb1.Active = 1; - ue_context_pP->ue_context.Srb1.Srb_info.Srb_id = 1; + ue_p->Srb[1].Active = 1; + ue_p->Srb[1].Srb_info.Srb_id = 1; } else if (SRB_configList->list.array[i]->srb_Identity == 2) { - ue_context_pP->ue_context.Srb2.Active = 1; - ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; - LOG_I(NR_RRC,"[gNB %d] Frame %d CC %d: SRB2 is now active\n", - ctxt_pP->module_id, - ctxt_pP->frame, - ue_context_pP->ue_context.primaryCC_id); + ue_p->Srb[2].Active = 1; + ue_p->Srb[2].Srb_info.Srb_id = 2; + LOG_I(NR_RRC, "[gNB %d] Frame %d CC %d : SRB2 is now active\n", ctxt_pP->module_id, ctxt_pP->frame, ue_p->primaryCC_id); } else { - LOG_W(NR_RRC,"[gNB %d] Frame %d CC %d: invalid SRB identity %ld\n", - ctxt_pP->module_id, - ctxt_pP->frame, - ue_context_pP->ue_context.primaryCC_id, - SRB_configList->list.array[i]->srb_Identity); + LOG_W(NR_RRC, "[gNB %d] Frame %d CC %d: invalid SRB identity %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ue_p->primaryCC_id, SRB_configList->list.array[i]->srb_Identity); } } free(SRB_configList); - ue_context_pP->ue_context.SRB_configList2[xid] = NULL; + ue_p->SRB_configList2[xid] = NULL; } /* Loop through DRBs and establish if necessary */ @@ -1272,8 +1145,8 @@ rrc_gNB_process_RRCReconfigurationComplete( (int)DRB_configList->list.array[i]->drb_Identity); //(int)*DRB_configList->list.array[i]->pdcp_Config->moreThanOneRLC->primaryPath.logicalChannel); - if (ue_context_pP->ue_context.DRB_active[drb_id - 1] == 0) { - ue_context_pP->ue_context.DRB_active[drb_id - 1] = DRB_ACTIVE; + if (ue_p->DRB_active[drb_id - 1] == 0) { + ue_p->DRB_active[drb_id - 1] = DRB_ACTIVE; LOG_D(NR_RRC, "[gNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity); @@ -1287,7 +1160,7 @@ rrc_gNB_process_RRCReconfigurationComplete( // rrc_mac_config_req_eNB } else { // remove LCHAN from MAC/PHY - if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { + if (ue_p->DRB_active[drb_id] == 1) { /* TODO : It may be needed if gNB goes into full stack working. */ // DRB has just been removed so remove RLC + PDCP for DRB /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE, @@ -1300,18 +1173,18 @@ rrc_gNB_process_RRCReconfigurationComplete( nr_DRB2LCHAN[i]);*/ } - //ue_context_pP->ue_context.DRB_active[drb_id] = 0; + // ue_p->DRB_active[drb_id] = 0; LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); // rrc_mac_config_req_eNB - } // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) + } // end else of if (ue_p->DRB_active[drb_id] == 0) } // end if (DRB_configList->list.array[i]) } // end for (int i = 0; i < DRB_configList->list.count; i++) free(DRB_configList); - ue_context_pP->ue_context.DRB_configList2[xid] = NULL; + ue_p->DRB_configList2[xid] = NULL; } // end if DRB_configList != NULL if(DRB_Release_configList2 != NULL) { @@ -1320,14 +1193,14 @@ rrc_gNB_process_RRCReconfigurationComplete( drb_id_p = DRB_Release_configList2->list.array[i]; drb_id = *drb_id_p; - if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { - ue_context_pP->ue_context.DRB_active[drb_id] = 0; + if (ue_p->DRB_active[drb_id] == 1) { + ue_p->DRB_active[drb_id] = 0; } } } free(DRB_Release_configList2); - ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL; + ue_p->DRB_Release_configList2[xid] = NULL; } } @@ -1347,13 +1220,14 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, module_id_t module_id = ctxt_pP->module_id; gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; int enable_ciphering = 0; + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; // Need to drop spCellConfig when there is a RRCReestablishment // Save spCellConfig in spCellConfigReestablishment to recover after Reestablishment is completed - ue_context_pP->ue_context.spCellConfigReestablishment = ue_context_pP->ue_context.masterCellGroup->spCellConfig; - ue_context_pP->ue_context.masterCellGroup->spCellConfig = NULL; + ue_p->spCellConfigReestablishment = ue_p->masterCellGroup->spCellConfig; + ue_p->masterCellGroup->spCellConfig = NULL; - SRB_configList = &(ue_context_pP->ue_context.SRB_configList); + SRB_configList = &(ue_p->SRB_configList); uint8_t buffer[RRC_BUF_SIZE] = {0}; int size = do_RRCReestablishment(ctxt_pP, @@ -1367,7 +1241,7 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, scc, &rrc->carrier); - LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " [RAPROC] Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), size); + LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", ue_p->rnti, size); #if (0) /* TODO : It may be needed if gNB goes into full stack working. */ UE = find_nr_UE(module_id, rnti); @@ -1377,7 +1251,7 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, /* Reject UE after 10 frames, NR_RRCReestablishmentReject is triggered */ RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 100; } else { - LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " Generating NR_RRCReestablishment without UE_id(MAC) rnti %x\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), rnti); + LOG_E(NR_RRC, " Generating NR_RRCReestablishment without UE_id(MAC) rnti %x\n", rnti); } #endif @@ -1386,11 +1260,11 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, uint8_t *kUPenc = NULL; /* Derive the keys from kgnb */ if (SRB_configList != NULL) { - nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kgnb, &kUPenc); + nr_derive_key_up_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kUPenc); } - nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kgnb, &kRRCenc); - nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kgnb, &kRRCint); + nr_derive_key_rrc_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kRRCenc); + nr_derive_key_rrc_int(ue_p->integrity_algorithm, ue_p->kgnb, &kRRCint); /* Configure SRB1 for UE */ if (*SRB_configList != NULL) { @@ -1403,20 +1277,19 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, NULL, NULL); } - LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_D(NR_RRC, "UE %04x --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", ue_p->rnti); } } // if (*SRB_configList != NULL) - LOG_I(NR_RRC, "Set PDCP security RNTI %04lx nca %ld nia %d in RRCReestablishment\n", ctxt_pP->rntiMaybeUEid, ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.integrity_algorithm); - pdcp_config_set_security( - ctxt_pP, - NULL, /* pdcp_pP not used anymore in NR */ - DCCH, - DCCH + 2, - enable_ciphering ? ue_context_pP->ue_context.ciphering_algorithm | (ue_context_pP->ue_context.integrity_algorithm << 4) : 0 | (ue_context_pP->ue_context.integrity_algorithm << 4), - kRRCenc, - kRRCint, - kUPenc); + LOG_I(NR_RRC, "Set PDCP security RNTI %04lx nca %ld nia %d in RRCReestablishment\n", ctxt_pP->rntiMaybeUEid, ue_p->ciphering_algorithm, ue_p->integrity_algorithm); + pdcp_config_set_security(ctxt_pP, + NULL, /* pdcp_pP not used anymore in NR */ + DCCH, + DCCH + 2, + enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4), + kRRCenc, + kRRCint, + kUPenc); if (!NODE_IS_CU(rrc->node_type)) { apply_macrlc_config_reest(rrc, ue_context_pP, ctxt_pP, ctxt_pP->rntiMaybeUEid); @@ -1429,12 +1302,11 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, const rnti_t reestablish_rnti, rrc_gNB_ue_context_t *ue_context_pP, const uint8_t xid) //----------------------------------------------------------------------------- { - LOG_I(NR_RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, processing NR_RRCReestablishmentComplete from UE (SRB1 Active)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel UL-DCCH, processing NR_RRCReestablishmentComplete from UE (SRB1 Active)\n", ue_p->rnti); - NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList; - NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; + NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList; + NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList; NR_SRB_ToAddModList_t **SRB_configList2 = NULL; NR_DRB_ToAddModList_t **DRB_configList2 = NULL; NR_SRB_ToAddMod_t *SRB2_config = NULL; @@ -1444,10 +1316,10 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); int ret = 0; - ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED; - ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - ue_context_pP->ue_context.reestablishment_xid = new_xid; - SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid]; + 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; + SRB_configList2 = &ue_p->SRB_configList2[xid]; // get old configuration of SRB2 if (*SRB_configList2 != NULL) { @@ -1458,7 +1330,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) { if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) { - LOG_D(NR_RRC, "get SRB2_config from (ue_context_pP->ue_context.SRB_configList2[%d])\n", xid); + LOG_D(NR_RRC, "get SRB2_config from (ue_p->SRB_configList2[%d])\n", xid); SRB2_config = (*SRB_configList2)->list.array[i]; SRB2_config->reestablishPDCP = CALLOC(1, sizeof(*SRB2_config->reestablishPDCP)); *SRB2_config->reestablishPDCP = NR_SRB_ToAddMod__reestablishPDCP_true; @@ -1470,12 +1342,12 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx // SRB2_config = CALLOC(1, sizeof(*SRB2_config)); // SRB2_config->srb_Identity = 2; - SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[new_xid]); - DRB_configList2 = &(ue_context_pP->ue_context.DRB_configList2[new_xid]); + SRB_configList2 = &(ue_p->SRB_configList2[new_xid]); + DRB_configList2 = &(ue_p->DRB_configList2[new_xid]); if (*SRB_configList2) { free(*SRB_configList2); - LOG_D(NR_RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", new_xid); + LOG_D(NR_RRC, "free(ue_p->SRB_configList2[%d])\n", new_xid); } *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); @@ -1484,9 +1356,8 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx // Add SRB2 to SRB configuration list asn1cSeqAdd(&SRB_configList->list, SRB2_config); asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config); - LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList\n", - SRB2_config->srb_Identity); - LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n", SRB2_config->srb_Identity, new_xid); + LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList\n", SRB2_config->srb_Identity); + LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList2[%d]\n", SRB2_config->srb_Identity, new_xid); } else { // SRB configuration list only contains SRB1. LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n"); @@ -1494,13 +1365,13 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx if (*DRB_configList2) { free(*DRB_configList2); - LOG_D(NR_RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", new_xid); + LOG_D(NR_RRC, "free(ue_p->DRB_configList2[%d])\n", new_xid); } *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); if (DRB_configList != NULL) { - LOG_D(NR_RRC, "get DRB_config from (ue_context_pP->ue_context.DRB_configList)\n"); + LOG_D(NR_RRC, "get DRB_config from (ue_p->DRB_configList)\n"); for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) { DRB_config = DRB_configList->list.array[i]; @@ -1510,47 +1381,23 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx } } - ue_context_pP->ue_context.Srb1.Active = 1; - //ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; + ue_p->Srb[1].Active = 1; + // ue_p->Srb[2].Srb_info.Srb_id = 2; if (get_softmodem_params()->sa) { - hashtable_rc_t h_rc; - int j; - rrc_ue_ngap_ids_t *rrc_ue_ngap_ids_p = NULL; - uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id; - uint32_t gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; - gNB_RRC_INST *rrc_instance_p = RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]; - - if (gNB_ue_ngap_id > 0) { - h_rc = hashtable_get(rrc_instance_p->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_id, (void **)&rrc_ue_ngap_ids_p); - - if (h_rc == HASH_TABLE_OK) { - rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rntiMaybeUEid; - } - } - - if (ue_initial_id != 0) { - h_rc = hashtable_get(rrc_instance_p->initial_id2_ngap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_ngap_ids_p); - - if (h_rc == HASH_TABLE_OK) { - rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rntiMaybeUEid; - } - } - + AssertFatal(false, "rework identity mapping \n"); gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; /* Save e RAB information for later */ - - for ( j = 0, i = 0; i < NB_RB_MAX; i++) { - if (ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_DONE) { - create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pduSession[i].param.pdusession_id; + int j; + for (j = 0, i = 0; i < NB_RB_MAX; i++) { + if (ue_p->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_p->pduSession[i].status == PDU_SESSION_STATUS_DONE) { + create_tunnel_req.pdusession_id[j] = ue_p->pduSession[i].param.pdusession_id; create_tunnel_req.incoming_rb_id[j] = i+1; - create_tunnel_req.outgoing_teid[j] = ue_context_pP->ue_context.pduSession[i].param.gtp_teid; + create_tunnel_req.outgoing_teid[j] = ue_p->pduSession[i].param.gtp_teid; // to be developped, use the first QFI only - create_tunnel_req.outgoing_qfi[j] = ue_context_pP->ue_context.pduSession[i].param.qos[0].qfi; - memcpy(create_tunnel_req.dst_addr[j].buffer, - ue_context_pP->ue_context.pduSession[i].param.upf_addr.buffer, - sizeof(uint8_t)*20); - create_tunnel_req.dst_addr[j].length = ue_context_pP->ue_context.pduSession[i].param.upf_addr.length; + create_tunnel_req.outgoing_qfi[j] = ue_p->pduSession[i].param.qos[0].qfi; + memcpy(create_tunnel_req.dst_addr[j].buffer, ue_p->pduSession[i].param.upf_addr.buffer, sizeof(uint8_t) * 20); + create_tunnel_req.dst_addr[j].length = ue_p->pduSession[i].param.upf_addr.length; j++; } } @@ -1563,39 +1410,20 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx reestablish_rnti); if ( ret != 0 ) { - LOG_E(NR_RRC,"gtpv1u_update_ngu_tunnel failed,start to release UE %x\n",reestablish_rnti); - - // update s1u tunnel failed,reset rnti? - if (gNB_ue_ngap_id > 0) { - h_rc = hashtable_get(rrc_instance_p->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_id, (void **)&rrc_ue_ngap_ids_p); - - if (h_rc == HASH_TABLE_OK ) { - rrc_ue_ngap_ids_p->ue_rnti = reestablish_rnti; - } - } - - if (ue_initial_id != 0) { - h_rc = hashtable_get(rrc_instance_p->initial_id2_ngap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_ngap_ids_p); - - if (h_rc == HASH_TABLE_OK ) { - rrc_ue_ngap_ids_p->ue_rnti = reestablish_rnti; - } - } - - ue_context_pP->ue_context.ue_release_timer_s1 = 1; - ue_context_pP->ue_context.ue_release_timer_thres_s1 = 100; - ue_context_pP->ue_context.ue_release_timer = 0; - ue_context_pP->ue_context.ue_reestablishment_timer = 0; - ue_context_pP->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ - ue_context_pP->ue_context.ul_failure_timer = 0; + LOG_E(NR_RRC, "gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti); + ue_p->ue_release_timer_s1 = 1; + ue_p->ue_release_timer_thres_s1 = 100; + ue_p->ue_release_timer = 0; + ue_p->ue_reestablishment_timer = 0; + ue_p->ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ + ue_p->ul_failure_timer = 0; return; } } /* Update RNTI in ue_context */ - LOG_I(NR_RRC, "Updating UEid from %04x to %lx\n", ue_context_pP->ue_context.rnti, ctxt_pP->rntiMaybeUEid); - ue_context_pP->ue_id_rnti = ctxt_pP->rntiMaybeUEid; // here ue_id_rnti is just a key, may be something else - ue_context_pP->ue_context.rnti = ctxt_pP->rntiMaybeUEid; + LOG_I(NR_RRC, "Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid); + rrc_gNB_update_ue_context_rnti(ctxt_pP->rntiMaybeUEid, RC.nrrrc[ctxt_pP->module_id], ue_p->gNB_ue_ngap_id); if (get_softmodem_params()->sa) { uint8_t send_security_mode_command = false; @@ -1607,31 +1435,29 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx } uint8_t drb_id_to_setup_start = DRB_configList ? DRB_configList->list.array[0]->drb_Identity : 1; - uint8_t nb_drb_to_setup = DRB_configList ? DRB_configList->list.count : ue_context_pP->ue_context.nb_of_pdusessions; + uint8_t nb_drb_to_setup = DRB_configList ? DRB_configList->list.count : ue_p->nb_of_pdusessions; /* TODO: hardcoded to 13 for the time being, to be changed? */ long drb_priority[NGAP_MAX_DRBS_PER_UE] = {13}; /* Add all NAS PDUs to the list */ - for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { - + for (i = 0; i < ue_p->nb_of_pdusessions; i++) { /* TODO parameters yet to process ... */ /* TODO should test if pdu session are Ok before! */ - ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE; - ue_context_pP->ue_context.pduSession[i].xid = xid; - LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", - i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE"); + ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; + ue_p->pduSession[i].xid = xid; + LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE"); } gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); // Revert spCellConfig stored in spCellConfigReestablishment before had been dropped during RRC Reestablishment - ue_context_pP->ue_context.masterCellGroup->spCellConfig = ue_context_pP->ue_context.spCellConfigReestablishment; - ue_context_pP->ue_context.spCellConfigReestablishment = NULL; - cellGroupConfig->spCellConfig = ue_context_pP->ue_context.masterCellGroup->spCellConfig; - cellGroupConfig->physicalCellGroupConfig = ue_context_pP->ue_context.masterCellGroup->physicalCellGroupConfig; + ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment; + ue_p->spCellConfigReestablishment = NULL; + cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig; +cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig; - fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); + fill_mastercellGroupConfig(cellGroupConfig, ue_p->masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); for(i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) { cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC = CALLOC(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC)); @@ -1659,11 +1485,11 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n"); /* Free all NAS PDUs */ - for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { - if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) { + for (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_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer); - ue_context_pP->ue_context.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; } } @@ -1671,13 +1497,13 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx LOG_E(NR_RRC, "RRC decode err!!! do_RRCReconfiguration\n"); return; } else { - LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti); LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfiguration to UE %04x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, - ue_context_pP->ue_context.rnti, + ue_p->rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); @@ -1687,16 +1513,12 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx } if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { - uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup && - ue_context_pP->ue_context.masterCellGroup->spCellConfig && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ? - NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS; + uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated + && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList + ? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS + : NR_RRC_RECONFIGURATION_DELAY_MS; - nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, - ue_context_pP->ue_context.rnti, - *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, - delay_ms); + nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms); } } //----------------------------------------------------------------------------- @@ -1707,8 +1529,9 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP const int ul_bwp_id) { uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - NR_CellGroupConfig_t *masterCellGroup = ue_context_pP->ue_context.masterCellGroup; + NR_CellGroupConfig_t *masterCellGroup = ue_p->masterCellGroup; if (dl_bwp_id > 0) { *masterCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id = dl_bwp_id; *masterCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = dl_bwp_id; @@ -1746,95 +1569,75 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP PDCP_TRANSMISSION_MODE_CONTROL); if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { - uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup && - ue_context_pP->ue_context.masterCellGroup->spCellConfig && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated && - ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ? - NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS; + uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated + && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList + ? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS + : NR_RRC_RECONFIGURATION_DELAY_MS; - nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, - ue_context_pP->ue_context.rnti, - *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, - delay_ms); + nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms); } return 0; } /*------------------------------------------------------------------------------*/ -int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, - const uint8_t *buffer, - int buffer_length, - const uint8_t *du_to_cu_rrc_container, - int du_to_cu_rrc_container_len) +static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint8_t *buffer, int buffer_length, const uint8_t *du_to_cu_rrc_container, int du_to_cu_rrc_container_len) { module_id_t Idx; asn_dec_rval_t dec_rval; - NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; + NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; + gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[module_id]; NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL; - NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest; - uint64_t random_value = 0; + NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest; - LOG_I(NR_RRC, "Decoding CCCH: RNTI %04lx, inst %ld, payload_size %d\n", ctxt_pP->rntiMaybeUEid, ctxt_pP->instance, buffer_length); + LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", rnti, buffer_length); dec_rval = uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **) &ul_ccch_msg, buffer, buffer_length, 0, 0); if (dec_rval.code != RC_OK || dec_rval.consumed == 0) { - LOG_E(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_E(NR_RRC, " FATAL Error in receiving CCCH\n"); return -1; } - if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { - switch (ul_ccch_msg->message.choice.c1->present) { + if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { + switch (ul_ccch_msg->message.choice.c1->present) { case NR_UL_CCCH_MessageType__c1_PR_NOTHING: /* TODO */ - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_FMT" Received PR_NOTHING on UL-CCCH-Message\n", - PROTOCOL_NR_RRC_CTXT_ARGS(ctxt_pP)); + LOG_I(NR_RRC, "Received PR_NOTHING on UL-CCCH-Message\n"); break; case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: - LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %lx)\n", ctxt_pP->rntiMaybeUEid); - ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid); + LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, rnti); if (ue_context_p != NULL) { - rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_p); + LOG_W(NR_RRC, "Got RRC setup request for a already registered RNTI %x, dropping the old one and give up this rrcSetupRequest\n", ue_context_p->ue_context.rnti); + rrc_gNB_remove_ue_context(gnb_rrc_inst, ue_context_p); } else { rrcSetupRequest = &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest; if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { /* randomValue BIT STRING (SIZE (39)) */ if (rrcSetupRequest->ue_Identity.choice.randomValue.size != 5) { // 39-bit random value - LOG_E(NR_RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", - (long unsigned int)rrcSetupRequest->ue_Identity.choice.randomValue.size); + LOG_E(NR_RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", (long unsigned int)rrcSetupRequest->ue_Identity.choice.randomValue.size); return -1; } - - memcpy(((uint8_t *) & random_value) + 3, - rrcSetupRequest->ue_Identity.choice.randomValue.buf, - rrcSetupRequest->ue_Identity.choice.randomValue.size); + uint64_t random_value = 0; + memcpy(((uint8_t *)&random_value) + 3, rrcSetupRequest->ue_Identity.choice.randomValue.buf, rrcSetupRequest->ue_Identity.choice.randomValue.size); /* if there is already a registered UE (with another RNTI) with this random_value, - * the current one must be removed from MAC/PHY (zombie UE) - */ - if ((ue_context_p = rrc_gNB_ue_context_random_exist(RC.nrrrc[ctxt_pP->module_id], random_value))) { - LOG_W(NR_RRC, - "new UE rnti %lx (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n", - ctxt_pP->rntiMaybeUEid, - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ul_failure_timer = 20000; + * the current one must be removed from MAC/PHY (zombie UE) + */ + if ((ue_context_p = rrc_gNB_ue_context_random_exist(gnb_rrc_inst, random_value))) { + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + LOG_W(NR_RRC, "new UE rnti (coming with random value) is already there, removing UE %x from MAC/PHY\n", rnti); + UE->ul_failure_timer = 20000; } - ue_context_p = rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], random_value); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value); } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { /* TODO */ /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ /* ng-5G-S-TMSI-Part1 BIT STRING (SIZE (39)) */ if (rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size != 5) { - LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part1 size, expected 5, provided %lu \n", - (long unsigned int)rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); + LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part1 size, expected 5, provided %lu \n", (long unsigned int)rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); return -1; } @@ -1844,91 +1647,82 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.buf, // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); - if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(RC.nrrrc[ctxt_pP->module_id], s_tmsi_part1))) { - LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, ue_context_p %p, old rnti %x => %lx\n", ue_context_p, ue_context_p->ue_context.rnti, ctxt_pP->rntiMaybeUEid); + if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(gnb_rrc_inst, s_tmsi_part1))) { + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, old rnti %04x => %04x\n", UE->rnti, rnti); // TODO: MAC structures should not be accessed directly from the RRC! An implementation using the F1 interface should be developed. - gNB_MAC_INST *nrmac=RC.nrmac[ctxt_pP->module_id]; //WHAT A BEAUTIFULL RACE CONDITION !!! - mac_remove_nr_ue(nrmac, ue_context_p->ue_context.rnti); + if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) { + gNB_MAC_INST *nrmac = RC.nrmac[module_id]; // why MAC instances match RRC instances ? + mac_remove_nr_ue(nrmac, UE->rnti); + } /* replace rnti in the context */ - /* for that, remove the context from the RB tree */ - RB_REMOVE(rrc_nr_ue_tree_s, &RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); - /* and insert again, after changing rnti everywhere it has to be changed */ - ue_context_p->ue_id_rnti = ctxt_pP->rntiMaybeUEid; - ue_context_p->ue_context.rnti = ctxt_pP->rntiMaybeUEid; - RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); + UE->rnti = rnti; /* reset timers */ - ue_context_p->ue_context.ul_failure_timer = 0; - ue_context_p->ue_context.ue_release_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - ue_context_p->ue_context.ue_release_timer_s1 = 0; - ue_context_p->ue_context.ue_release_timer_rrc = 0; + UE->ul_failure_timer = 0; + UE->ue_release_timer = 0; + UE->ue_reestablishment_timer = 0; + UE->ue_release_timer_s1 = 0; + UE->ue_release_timer_rrc = 0; } else { - LOG_I(NR_RRC, " 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 to %p => %ld\n", - ue_context_p, s_tmsi_part1); - - ue_context_p = rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], s_tmsi_part1); + LOG_I(NR_RRC, "UE %04x 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 => %ld\n", rnti, s_tmsi_part1); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, s_tmsi_part1); if (ue_context_p == NULL) { - LOG_E(RRC, "%s:%d:%s: rrc_gNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__); - } - - if (ue_context_p != NULL) { - ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = true; - ue_context_p->ue_context.ng_5G_S_TMSI_Part1 = s_tmsi_part1; + LOG_E(NR_RRC, "rrc_gNB_get_next_free_ue_context returned NULL\n"); + return -1; } + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + UE->Initialue_identity_5g_s_TMSI.presence = true; + UE->ng_5G_S_TMSI_Part1 = s_tmsi_part1; } } else { /* TODO */ - memcpy(((uint8_t *) & random_value) + 3, - rrcSetupRequest->ue_Identity.choice.randomValue.buf, - rrcSetupRequest->ue_Identity.choice.randomValue.size); + uint64_t random_value = 0; + memcpy(((uint8_t *)&random_value) + 3, rrcSetupRequest->ue_Identity.choice.randomValue.buf, rrcSetupRequest->ue_Identity.choice.randomValue.size); - rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], random_value); - LOG_E(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_gNB_generate_RRCReject(ctxt_pP, rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid)); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value); + LOG_E(NR_RRC, "RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE %04x\n", rnti); + rrc_gNB_generate_RRCReject(module_id, ue_context_p); break; } - - ue_context_p->ue_context.establishment_cause = rrcSetupRequest->establishmentCause; + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + UE = &ue_context_p->ue_context; + UE->establishment_cause = rrcSetupRequest->establishmentCause; rrc_gNB_generate_RRCSetup( - ctxt_pP, rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid), du_to_cu_rrc_container, du_to_cu_rrc_container_len, gnb_rrc_inst->carrier.servingcellconfigcommon); + module_id, rnti, rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, rnti), du_to_cu_rrc_container, du_to_cu_rrc_container_len, gnb_rrc_inst->carrier.servingcellconfigcommon); } break; case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest: - LOG_I(NR_RRC, "receive rrcResumeRequest message \n"); + LOG_I(NR_RRC, "receive rrcResumeRequest message \n"); break; case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: { - LOG_I(NR_RRC, "Received rrcReestablishmentRequest message\n"); LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(buffer), buffer_length, "[MSG] RRC Reestablishment Request\n"); - LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT "MAC_gNB--- MAC_DATA_IND (rrcReestablishmentRequest on SRB0) --> RRC_gNB\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrcReestablishmentRequest = ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest; + const NR_ReestablishmentCause_t cause = rrcReestablishmentRequest.reestablishmentCause; + const long physCellId = rrcReestablishmentRequest.ue_Identity.physCellId; LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT " NR_RRCReestablishmentRequest cause %s\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - ((rrcReestablishmentRequest.reestablishmentCause == NR_ReestablishmentCause_otherFailure) ? "Other Failure" - : (rrcReestablishmentRequest.reestablishmentCause == NR_ReestablishmentCause_handoverFailure) ? "Handover Failure" - : "reconfigurationFailure")); + "UE %04x NR_RRCReestablishmentRequest cause %s\n", + rnti, + ((cause == NR_ReestablishmentCause_otherFailure) ? "Other Failure" + : (cause == NR_ReestablishmentCause_handoverFailure) ? "Handover Failure" + : "reconfigurationFailure")); - if (rrcReestablishmentRequest.ue_Identity.physCellId != RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId) { + 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, - PROTOCOL_NR_RRC_CTXT_UE_FMT " NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), fallback to RRC establishment\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - rrcReestablishmentRequest.ue_Identity.physCellId, - RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); + " 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); break; } - LOG_I(NR_RRC, "physCellId: %ld\n", rrcReestablishmentRequest.ue_Identity.physCellId); + LOG_I(NR_RRC, "physCellId: %ld\n", physCellId); for (int i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) { LOG_D(NR_RRC, "rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[%d] = %x\n", i, rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[i]); @@ -1938,26 +1732,24 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, 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(ctxt_pP, 0); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); break; } rnti_t c_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI; LOG_I(NR_RRC, "c_RNTI: %04x\n", c_rnti); - ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, c_rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, c_rnti); + 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(ctxt_pP, 0); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, c_rnti, 0); break; } - -#if (0) - /* TODO : It may be needed if gNB goes into full stack working. */ - int UE_id = find_nr_UE_id(ctxt_pP->module_id, c_rnti); - +#if 0 + int UE_id = find_nr_UE_id(gnb_rrc_inst, c_rnti); if (UE_id == -1) { - LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " NR_RRCReestablishmentRequest without UE_id(MAC) rnti %x, fallback to RRC establishment\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), c_rnti); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); + LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without MAC context, rnti %04x, fallback to RRC establishment\n", c_rnti); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); break; } @@ -1972,91 +1764,87 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, } if (previous_rnti != 0) { - UE_id = find_nr_UE_id(ctxt_pP->module_id, previous_rnti); - + UE_id = find_nr_UE_id(gnb_rrc_inst, previous_rnti); if (UE_id == -1) { - LOG_E(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT " RRCReestablishmentRequest without UE_id(MAC) previous rnti %x, fallback to RRC establishment\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - previous_rnti); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); + LOG_E(NR_RRC,"RRCReestablishmentRequest without mac context previous rnti %04x, nex rnti %04x, fallback to RRC establishment\n", + previous_rnti, c_rnti); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); break; } } #endif // c-plane not end - if ((ue_context_p->ue_context.StatusRrc != NR_RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == NR_ReestablishmentCause_spare1)) { + if ((UE->StatusRrc != NR_RRC_RECONFIGURED) && (UE->reestablishment_cause == NR_ReestablishmentCause_spare1)) { LOG_E(NR_RRC, "NR_RRCReestablishmentRequest (UE %x c-plane is not end), RRC establishment failed\n", c_rnti); /* TODO RRC Release ? */ break; } - if (ue_context_p->ue_context.ue_reestablishment_timer > 0) { - LOG_E(NR_RRC, "RRRCReconfigurationComplete(Previous) don't receive, delete the Previous UE,\nprevious Status %d, new Status NR_RRC_RECONFIGURED\n", ue_context_p->ue_context.StatusRrc); - ue_context_p->ue_context.StatusRrc = NR_RRC_RECONFIGURED; + if (UE->ue_reestablishment_timer > 0) { + LOG_E(NR_RRC, "RRRCReconfigurationComplete(Previous) don't receive, delete the Previous UE,\nprevious Status %d, new Status NR_RRC_RECONFIGURED\n", UE->StatusRrc); + UE->StatusRrc = NR_RRC_RECONFIGURED; protocol_ctxt_t ctxt_old_p; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p, ctxt_pP->instance, GNB_FLAG_YES, c_rnti, ctxt_pP->frame, ctxt_pP->subframe); - rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p, ue_context_p, ue_context_p->ue_context.reestablishment_xid); + 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); - for (uint8_t pdusessionid = 0; pdusessionid < ue_context_p->ue_context.nb_of_pdusessions; pdusessionid++) { - if (ue_context_p->ue_context.pduSession[pdusessionid].status == PDU_SESSION_STATUS_DONE) { - ue_context_p->ue_context.pduSession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED; + for (uint8_t pdusessionid = 0; pdusessionid < UE->nb_of_pdusessions; pdusessionid++) { + if (UE->pduSession[pdusessionid].status == PDU_SESSION_STATUS_DONE) { + UE->pduSession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED; } else { - ue_context_p->ue_context.pduSession[pdusessionid].status = PDU_SESSION_STATUS_FAILED; + UE->pduSession[pdusessionid].status = PDU_SESSION_STATUS_FAILED; } } } /* reset timers */ - ue_context_p->ue_context.ul_failure_timer = 0; - ue_context_p->ue_context.ue_release_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - // ue_context_p->ue_context.ue_release_timer_s1 = 0; - ue_context_p->ue_context.ue_release_timer_rrc = 0; - ue_context_p->ue_context.reestablishment_xid = -1; + UE->ul_failure_timer = 0; + UE->ue_release_timer = 0; + 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 = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[i]; + nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; LOG_I(NR_RRC, "Insert nr_reestablish_rnti_map[%d] UEid: %lx, RNTI: %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); if (nr_reestablish_rnti_map->ue_id == 0) { - nr_reestablish_rnti_map->ue_id = ctxt_pP->rntiMaybeUEid; + nr_reestablish_rnti_map->ue_id = rnti; nr_reestablish_rnti_map->c_rnti = c_rnti; - LOG_I(NR_RRC, "Insert nr_reestablish_rnti_map[%d] UEid: %lx, RNTI: %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); + LOG_W(NR_RRC, "Insert nr_reestablish_rnti_map[%d] UEid: %lx, RNTI: %04x bug in UEid to fix \n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); break; } } - ue_context_p->ue_context.reestablishment_cause = rrcReestablishmentRequest.reestablishmentCause; - LOG_D(NR_RRC, "Accept RRCReestablishmentRequest from UE physCellId %ld cause %ld\n", rrcReestablishmentRequest.ue_Identity.physCellId, ue_context_p->ue_context.reestablishment_cause); + UE->reestablishment_cause = cause; + LOG_D(NR_RRC, "Accept RRCReestablishmentRequest from UE physCellId %ld cause %ld\n", physCellId, cause); - ue_context_p->ue_context.primaryCC_id = 0; - //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; - Idx = DCCH; - // SRB1 - ue_context_p->ue_context.Srb1.Active = 1; - ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx; - rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0]); - rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1]); - // SRB2: set it to go through SRB1 with id 1 (DCCH) - ue_context_p->ue_context.Srb2.Active = 1; - ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx; - rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0]); - rrc_init_nr_srb_param(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1]); - - rrc_gNB_generate_RRCReestablishment(ctxt_pP, ue_context_p, du_to_cu_rrc_container, gnb_rrc_inst->carrier.servingcellconfigcommon, 0); + UE->primaryCC_id = 0; + // LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; + Idx = DCCH; + // SRB1 + UE->Srb[1].Active = 1; + UE->Srb[1].Srb_info.Srb_id = Idx; + rrc_init_nr_srb_param(&UE->Srb[1].Srb_info.Lchan_desc[0]); + rrc_init_nr_srb_param(&UE->Srb[1].Srb_info.Lchan_desc[1]); + // SRB2: set it to go through SRB1 with id 1 (DCCH) + UE->Srb[2].Active = 1; + UE->Srb[2].Srb_info.Srb_id = Idx; + rrc_init_nr_srb_param(&UE->Srb[2].Srb_info.Lchan_desc[0]); + rrc_init_nr_srb_param(&UE->Srb[2].Srb_info.Lchan_desc[1]); + protocol_ctxt_t ctxt = {.rntiMaybeUEid = UE->rnti, .module_id = module_id, .instance = module_id, .enb_flag = 1, .eNB_index = module_id}; + rrc_gNB_generate_RRCReestablishment(&ctxt, ue_context_p, du_to_cu_rrc_container, gnb_rrc_inst->carrier.servingcellconfigcommon, 0); LOG_I(NR_RRC, "CALLING RLC CONFIG SRB1 (rbid %d)\n", Idx); } break; case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: - LOG_I(NR_RRC, "receive rrcSystemInfoRequest message \n"); + LOG_I(NR_RRC, "UE %04x receive rrcSystemInfoRequest message \n", rnti); /* TODO */ break; default: - LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Unknown message\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_E(NR_RRC, "UE %04x Unknown message\n", rnti); break; } } @@ -2116,24 +1904,18 @@ rrc_gNB_decode_dcch( //----------------------------------------------------------------------------- { asn_dec_rval_t dec_rval; - NR_UL_DCCH_Message_t *ul_dcch_msg = NULL; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; + 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, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received message on SRB%ld, should not have ...\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - Srb_id); + LOG_E(NR_RRC, "Received message on SRB%ld, should not have ...\n", Srb_id); } else { - LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received message on SRB%ld\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - Srb_id); + LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id); } - LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Decoding UL-DCCH Message\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_D(NR_RRC, "Decoding UL-DCCH Message\n"); //for (int i=0;imodule_id], ctxt_pP->rntiMaybeUEid); + 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) { case NR_UL_DCCH_MessageType__c1_PR_NOTHING: - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_FMT" Received PR_NOTHING on UL-DCCH-Message\n", - PROTOCOL_NR_RRC_CTXT_ARGS(ctxt_pP)); + LOG_I(NR_RRC, "Received PR_NOTHING on UL-DCCH-Message\n"); break; case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete: @@ -2202,43 +1981,41 @@ rrc_gNB_decode_dcch( } if (get_softmodem_params()->sa) { - if(ue_context_p->ue_context.pdu_session_release_command_flag == 1) { + if (UE->pdu_session_release_command_flag == 1) { xid = ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier; - ue_context_p->ue_context.pdu_session_release_command_flag = 0; + 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_context_p->ue_context.pduSession[i].xid) { - req.pdusession_id[req.num_pdusession++] = - ue_context_p->ue_context.gnb_gtp_psi[i]; - ue_context_p->ue_context.gnb_gtp_teid[i] = 0; - memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i])); - ue_context_p->ue_context.gnb_gtp_psi[i] = 0; + 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_context_p->ue_context.established_pdu_sessions_flag != 1) { - if (ue_context_p->ue_context.reestablishment_xid < 0) { - if (ue_context_p->ue_context.nb_of_pdusessions > 0) { + } 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); - ue_context_p->ue_context.nb_of_pdusessions = 0; } } else { - ue_context_p->ue_context.reestablishment_xid = -1; + UE->reestablishment_xid = -1; } } - if (ue_context_p->ue_context.nb_of_modify_pdusessions > 0) { + 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_context_p->ue_context.nb_of_modify_pdusessions = 0; - ue_context_p->ue_context.nb_of_failed_pdusessions = 0; - memset(ue_context_p->ue_context.modify_pdusession, 0, sizeof(ue_context_p->ue_context.modify_pdusession)); + 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_context_p->ue_context.modify_pdusession[i].xid = -1; + UE->modify_pdusession[i].xid = -1; } } } @@ -2280,11 +2057,9 @@ rrc_gNB_decode_dcch( return -1; } - if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 != 0) { - ue_context_p->ue_context.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); + 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 */ @@ -2306,10 +2081,10 @@ rrc_gNB_decode_dcch( 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_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == true) { - ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38; - ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F; - ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi = (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; } } } @@ -2322,7 +2097,7 @@ rrc_gNB_decode_dcch( PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); } - ue_context_p->ue_context.ue_release_timer = 0; + UE->ue_release_timer = 0; break; case NR_UL_DCCH_MessageType__c1_PR_measurementReport: @@ -2424,30 +2199,33 @@ rrc_gNB_decode_dcch( 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_context_p->ue_context.UE_Capability_nr){ - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); - ue_context_p->ue_context.UE_Capability_nr = 0; + 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_context_p->ue_context.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); + &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_context_p->ue_context.UE_Capability_nr); + 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_context_p->ue_context.UE_Capability_nr); - ue_context_p->ue_context.UE_Capability_nr = 0; + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); + UE->UE_Capability_nr = 0; } - ue_context_p->ue_context.UE_Capability_size = - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; + 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); @@ -2457,29 +2235,33 @@ rrc_gNB_decode_dcch( 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_context_p->ue_context.UE_Capability_MRDC){ - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); - ue_context_p->ue_context.UE_Capability_MRDC = 0; - } - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_MRDC_Capability, - (void**)&ue_context_p->ue_context.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 (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_context_p->ue_context.UE_Capability_MRDC); - } + 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_context_p->ue_context.UE_Capability_MRDC); - ue_context_p->ue_context.UE_Capability_MRDC = 0; + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); + UE->UE_Capability_MRDC = 0; } - ue_context_p->ue_context.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; + 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 == @@ -2497,14 +2279,13 @@ rrc_gNB_decode_dcch( ul_dcch_msg); } - if(!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)){ - if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { + if (!NODE_IS_CU(gnb_rrc_inst->node_type)) { + if (UE->established_pdu_sessions_flag == 1) { rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p, NULL); } else { rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); } - } - else{ + } else { /*Generate a UE context setup request message towards the DU to provide the UE *capability info and get the updates on master cell group config from the DU*/ MessageDef *message_p; @@ -2513,13 +2294,13 @@ rrc_gNB_decode_dcch( //UE_IDs will be extracted from F1AP layer req->gNB_CU_ue_id = 0; req->gNB_DU_ue_id = 0; - req->rnti = ue_context_p->ue_context.rnti; - req->mcc = RC.nrrrc[ctxt_pP->module_id]->configuration.mcc[0]; - req->mnc = RC.nrrrc[ctxt_pP->module_id]->configuration.mnc[0]; - req->mnc_digit_length = RC.nrrrc[ctxt_pP->module_id]->configuration.mnc_digit_length[0]; - req->nr_cellid = RC.nrrrc[ctxt_pP->module_id]->nr_cellid; + req->rnti = UE->rnti; + req->mcc = gnb_rrc_inst->configuration.mcc[0]; + req->mnc = gnb_rrc_inst->configuration.mnc[0]; + req->mnc_digit_length = gnb_rrc_inst->configuration.mnc_digit_length[0]; + req->nr_cellid = gnb_rrc_inst->nr_cellid; - if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { + if (UE->established_pdu_sessions_flag == 1) { /*Instruction towards the DU for SRB2 configuration*/ req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t)); req->srbs_to_be_setup_length = 1; @@ -2534,11 +2315,11 @@ rrc_gNB_decode_dcch( LOG_I(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length); DRBs[0].drb_id = 1; DRBs[0].rlc_mode = RLC_MODE_AM; - DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt_pP->module_id]->eth_params_s.my_addr); - DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt_pP->module_id]->eth_params_s.my_portd; + DRBs[0].up_ul_tnl[0].tl_address = inet_addr(gnb_rrc_inst->eth_params_s.my_addr); + DRBs[0].up_ul_tnl[0].port = gnb_rrc_inst->eth_params_s.my_portd; DRBs[0].up_ul_tnl_length = 1; - DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt_pP->module_id]->eth_params_s.remote_addr); - DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt_pP->module_id]->eth_params_s.remote_portd; + DRBs[0].up_dl_tnl[0].tl_address = inet_addr(gnb_rrc_inst->eth_params_s.remote_addr); + DRBs[0].up_dl_tnl[0].port = gnb_rrc_inst->eth_params_s.remote_portd; DRBs[0].up_dl_tnl_length = 1; } if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present == @@ -2565,49 +2346,42 @@ rrc_gNB_decode_dcch( itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_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, - PROTOCOL_RRC_CTXT_UE_FMT - " RLC RB %02d --- RLC_DATA_IND %d bytes " - "(rrcReestablishmentComplete) ---> RRC_gNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); + 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 = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[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(RC.nrrrc[ctxt_pP->module_id], reestablish_rnti); + ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, reestablish_rnti); break; } } if (!ue_context_p) { - LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " NR_RRCReestablishmentComplete without UE context, falt\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_E(NR_RRC, "NR_RRCReestablishmentComplete without UE context, fault\n"); break; } #if (0) /* TODO : It may be needed if gNB goes into full stack working. */ // clear - int UE_id = find_nr_UE_id(ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid); + int UE_id = find_nr_UE_id(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid); if (UE_id == -1) { LOG_E(NR_RRC, PROTOCOL_RRC_CTXT_UE_FMT " NR_RRCReestablishmentComplete without UE_id(MAC) rnti %lx, fault\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ctxt_pP->rntiMaybeUEid); break; } - RC.nrmac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; + RC.nrmac[gnb_rrc_inst]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; #endif if (ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->criticalExtensions.present == NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete) { @@ -2619,10 +2393,10 @@ rrc_gNB_decode_dcch( ue_context_p->ue_context.ue_reestablishment_counter++; } - // ue_context_p->ue_context.ue_release_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 1; + // UE->ue_release_timer = 0; + UE->ue_reestablishment_timer = 1; // remove UE after 100 frames after NR_RRCReestablishmentRelease is triggered - ue_context_p->ue_context.ue_reestablishment_timer_thres = 1000; + UE->ue_reestablishment_timer_thres = 1000; } break; default: @@ -2747,14 +2521,7 @@ void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t i = 0; LOG_W(RRC, "initial UL RRC message nr_cellid %ld does not match RRC's %ld\n", ul_rrc->nr_cellid, RC.nrrrc[0]->nr_cellid); } - protocol_ctxt_t ctxt = { 0 }; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, i, GNB_FLAG_YES, ul_rrc->crnti, 0, 0); - - nr_rrc_gNB_decode_ccch(&ctxt, - ul_rrc->rrc_container, - ul_rrc->rrc_container_length, - ul_rrc->du2cu_rrc_container, - ul_rrc->du2cu_rrc_container_length); + nr_rrc_gNB_decode_ccch(i, ul_rrc->crnti, ul_rrc->rrc_container, ul_rrc->rrc_container_length, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length); if (ul_rrc->rrc_container) free(ul_rrc->rrc_container); @@ -2774,11 +2541,13 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC rrc_remove_nsa_user(rrc, m->rnti); } -static int rrc_process_DU_DL(MessageDef *msg_p, const char *msg_name, instance_t instance) { +static int rrc_process_DU_DL(MessageDef *msg_p, instance_t instance) +{ NRDuDlReq_t * req=&NRDuDlReq(msg_p); protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid); + gNB_RRC_INST *rrc = RC.nrrrc[instance]; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (req->srb_id == 0) { AssertFatal(0 == 1, "should pass through dl_rrc_message()\n"); @@ -2831,19 +2600,18 @@ static int rrc_process_DU_DL(MessageDef *msg_p, const char *msg_name, instance_ if (SRB_configList != NULL) { for (i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { if (SRB_configList->list.array[i]->srb_Identity == 1 ) { - ue_context_p->ue_context.Srb1.Active=1; - } else if (SRB_configList->list.array[i]->srb_Identity == 2 ) { - ue_context_p->ue_context.Srb2.Active=1; - ue_context_p->ue_context.Srb2.Srb_info.Srb_id=2; - LOG_I(F1AP, "[DU %d] SRB2 is now active\n",ctxt.module_id); - } else { - LOG_W(F1AP, "[DU %d] invalide SRB identity %ld\n",ctxt.module_id, - SRB_configList->list.array[i]->srb_Identity); - } - } - } - - if (DRB_configList != NULL) { + UE->Srb[1].Active = 1; + } else if (SRB_configList->list.array[i]->srb_Identity == 2) { + UE->Srb[2].Active = 1; + UE->Srb[2].Srb_info.Srb_id = 2; + LOG_I(F1AP, "[DU %d] SRB2 is now active\n", ctxt.module_id); + } else { + LOG_W(F1AP, "[DU %d] invalide SRB identity %ld\n", ctxt.module_id, SRB_configList->list.array[i]->srb_Identity); + } + } + } + + if (DRB_configList != NULL) { for (i = 0; i < DRB_configList->list.count; i++) { // num max DRB (11-3-8) if (DRB_configList->list.array[i]) { drb_id = (int)DRB_configList->list.array[i]->drb_Identity; @@ -2855,8 +2623,8 @@ static int rrc_process_DU_DL(MessageDef *msg_p, const char *msg_name, instance_ // (int)*DRB_configList->list.array[i]->logicalChannelIdentity); - if (ue_context_p->ue_context.DRB_active[drb_id] == 0) { - ue_context_p->ue_context.DRB_active[drb_id] = 1; + if (UE->DRB_active[drb_id] == 0) { + UE->DRB_active[drb_id] = 1; // logicalChannelIdentity // rrc_mac_config_req_eNB } @@ -2963,13 +2731,13 @@ static int rrc_process_DU_DL(MessageDef *msg_p, const char *msg_name, instance_ return 0; } -static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const char *msg_name, instance_t instance){ - +static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, instance_t instance) +{ f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_SETUP_REQ(msg_p); - protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id]; - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid); + gNB_RRC_INST *rrc = RC.nrrrc[instance]; + gNB_MAC_INST *mac = RC.nrmac[instance]; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; MessageDef *message_p; message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP); f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(message_p); @@ -2997,30 +2765,29 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == NR_RAT_Type_nr){ LOG_I(NR_RRC, "DU received NR_RAT_Type_nr UE capabilities Info through the UE Context Setup Request from the CU \n"); - if(ue_context_p->ue_context.UE_Capability_nr){ - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); - ue_context_p->ue_context.UE_Capability_nr = 0; + 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_context_p->ue_context.UE_Capability_nr, - ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, - ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, - 0,0); + &asn_DEF_NR_UE_NR_Capability, + (void **)&UE->UE_Capability_nr, + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, + 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_context_p->ue_context.UE_Capability_nr); + 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),dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); - ue_context_p->ue_context.UE_Capability_nr = 0; + LOG_E(NR_RRC, "UE %04x Failed to decode nr UE capabilities (%zu bytes)\n", req->rnti, dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); + UE->UE_Capability_nr = 0; } - ue_context_p->ue_context.UE_Capability_size = - ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; + UE->UE_Capability_size = ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; if(NR_index != -1){ LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n"); exit(1); @@ -3031,28 +2798,27 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == NR_RAT_Type_eutra_nr){ LOG_I(NR_RRC, "DU received NR_RAT_Type_eutra_nr UE capabilities Info through the UE Context Setup Request from the CU \n"); - if(ue_context_p->ue_context.UE_Capability_MRDC){ - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); - ue_context_p->ue_context.UE_Capability_MRDC = 0; + 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_context_p->ue_context.UE_Capability_MRDC, - ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, - ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, - 0,0); + &asn_DEF_NR_UE_MRDC_Capability, + (void **)&UE->UE_Capability_MRDC, + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, + 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_context_p->ue_context.UE_Capability_MRDC); + 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),dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); - ue_context_p->ue_context.UE_Capability_MRDC = 0; + LOG_E(NR_RRC, "UE %04x Failed to decode nr UE capabilities (%zu bytes)\n", req->rnti, dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); + UE->UE_Capability_MRDC = 0; } - ue_context_p->ue_context.UE_MRDC_Capability_size = - ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; + UE->UE_MRDC_Capability_size = ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; } if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == @@ -3070,11 +2836,11 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha uint8_t SRBs_before_new_addition = 0; if(req->srbs_to_be_setup_length>0){ - if(ue_context_p->ue_context.SRB_configList == NULL){ + if (UE->SRB_configList == NULL) { LOG_W(NR_RRC, "The SRB list of the UE context is empty before the addition of new SRB at the DU \n"); - ue_context_p->ue_context.SRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.SRB_configList)); + UE->SRB_configList = CALLOC(1, sizeof(*UE->SRB_configList)); } - SRB_configList = ue_context_p->ue_context.SRB_configList; + SRB_configList = UE->SRB_configList; SRBs_before_new_addition = SRB_configList->list.count; for (int i=0; isrbs_to_be_setup_length; i++){ SRB2_config = CALLOC(1, sizeof(*SRB2_config)); @@ -3090,10 +2856,10 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha uint8_t nb_drb_to_setup = 0; long drb_priority[NGAP_MAX_DRBS_PER_UE]; if(req->drbs_to_be_setup_length>0){ - if(ue_context_p->ue_context.DRB_configList == NULL){ - ue_context_p->ue_context.DRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.DRB_configList)); + if (UE->DRB_configList == NULL) { + UE->DRB_configList = CALLOC(1, sizeof(*UE->DRB_configList)); } - DRB_configList = ue_context_p->ue_context.DRB_configList; + DRB_configList = UE->DRB_configList; nb_drb_to_setup = req->drbs_to_be_setup_length; for (int i=0; idrbs_to_be_setup_length; i++){ DRB_config = CALLOC(1, sizeof(*DRB_config)); @@ -3124,8 +2890,8 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length>0) // FIXME: fill_mastercellGroupConfig() won't fill the right priorities or // bearer IDs for the DRBs - fill_mastercellGroupConfig(cellGroupConfig, ue_context_p->ue_context.masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); - + fill_mastercellGroupConfig(cellGroupConfig, UE->masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); + protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; apply_macrlc_config(rrc, ue_context_p, &ctxt); if(req->rrc_container_length > 0){ @@ -3141,7 +2907,7 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha /* Fill the UE context setup response ITTI message to send to F1AP */ resp->gNB_CU_ue_id = req->gNB_CU_ue_id; - resp->rnti = ctxt.rntiMaybeUEid; + resp->rnti = req->rnti; if(DRB_configList){ if(DRB_configList->list.count > 0){ resp->drbs_to_be_setup = calloc(1,DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t)); @@ -3179,26 +2945,27 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha resp->du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t)); resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024); asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, - NULL, - ue_context_p->ue_context.masterCellGroup, //(void *)cellGroupConfig, - resp->du_to_cu_rrc_information->cellGroupConfig, - 1024); + NULL, + UE->masterCellGroup, //(void *)cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig, + 1024); if (enc_rval.encoded == -1) { LOG_E(F1AP,"Could not encode ue_context.masterCellGroup, failed element %s\n",enc_rval.failed_type->name); exit(-1); } resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3; free(cellGroupConfig); - itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p); + itti_send_msg_to_task(TASK_DU_F1, instance, message_p); } -static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, const char *msg_name, instance_t instance){ - +static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, instance_t instance) +{ f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id]; - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; MessageDef *message_p; message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_MODIFICATION_RESP(message_p); @@ -3211,11 +2978,11 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co uint8_t SRBs_before_new_addition = 0; if(req->srbs_to_be_setup_length>0){ - if(ue_context_p->ue_context.SRB_configList == NULL){ + if (UE->SRB_configList == NULL) { LOG_W(NR_RRC, "The SRB list of the UE context is empty before the addition of new SRB at the DU \n"); - ue_context_p->ue_context.SRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.SRB_configList)); + UE->SRB_configList = CALLOC(1, sizeof(*UE->SRB_configList)); } - SRB_configList = ue_context_p->ue_context.SRB_configList; + SRB_configList = UE->SRB_configList; SRBs_before_new_addition = SRB_configList->list.count; for (int i=0; isrbs_to_be_setup_length; i++){ SRB2_config = CALLOC(1, sizeof(*SRB2_config)); @@ -3230,10 +2997,10 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co int drb_id_to_setup_start = 0; long drb_priority[NGAP_MAX_DRBS_PER_UE]; if(req->drbs_to_be_setup_length>0){ - if(ue_context_p->ue_context.DRB_configList == NULL){ - ue_context_p->ue_context.DRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.DRB_configList)); + if (UE->DRB_configList == NULL) { + UE->DRB_configList = CALLOC(1, sizeof(*UE->DRB_configList)); } - DRB_configList = ue_context_p->ue_context.DRB_configList; + DRB_configList = UE->DRB_configList; for (int i=0; idrbs_to_be_setup_length; i++){ DRB_config = CALLOC(1, sizeof(*DRB_config)); DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id; @@ -3262,24 +3029,18 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co if(req->srbs_to_be_setup_length>0 || req->drbs_to_be_setup_length>0){ cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - fill_mastercellGroupConfig(cellGroupConfig, - ue_context_p->ue_context.masterCellGroup, - rrc->um_on_default_drb, - drb_id_to_setup_start < 2 ? 1 : 0, - drb_id_to_setup_start, - req->drbs_to_be_setup_length, - drb_priority); - apply_macrlc_config(rrc, ue_context_p, &ctxt); + fill_mastercellGroupConfig(cellGroupConfig, UE->masterCellGroup, rrc->um_on_default_drb, drb_id_to_setup_start < 2 ? 1 : 0, drb_id_to_setup_start, req->drbs_to_be_setup_length, drb_priority); + apply_macrlc_config(rrc, ue_context_p, &ctxt); } if(req->ReconfigComplOutcome == RRCreconf_failure){ LOG_W(NR_RRC, "CU reporting RRC Reconfiguration failure \n"); } else if(req->ReconfigComplOutcome == RRCreconf_success){ LOG_I(NR_RRC, "CU reporting RRC Reconfiguration success \n"); - if(ue_context_p->ue_context.DRB_configList!=NULL){ + if (UE->DRB_configList != NULL) { LOG_I(NR_RRC, "Send first DDD buffer status reporting towards the CU through an ITTI message to gtp-u \n"); - uint8_t drb_id = ue_context_p->ue_context.DRB_configList->list.array[0]->drb_Identity; - rnti_t rnti = ue_context_p->ue_context.rnti; + uint8_t drb_id = UE->DRB_configList->list.array[0]->drb_Identity; + rnti_t rnti = UE->rnti; int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(rnti, drb_id + 3); LOG_I(NR_RRC, "Reported in DDD drb_id:%d, rnti:%d\n", drb_id, rnti); MessageDef *msg = itti_alloc_new_message_sized(TASK_RRC_GNB, 0, GTPV1U_DU_BUFFER_REPORT_REQ, @@ -3290,7 +3051,6 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co req->buffer_availability = rlc_tx_buffer_space; //10000000; //Hardcoding to be removed and read the actual RLC buffer availability instead extern instance_t DUuniqInstance; itti_send_msg_to_task(TASK_GTPV1_U, DUuniqInstance, msg); - } } @@ -3333,21 +3093,22 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co resp->du_to_cu_rrc_information = calloc(1,sizeof(du_to_cu_rrc_information_t)); resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024); asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, - NULL, - ue_context_p->ue_context.masterCellGroup, //(void *)cellGroupConfig, - resp->du_to_cu_rrc_information->cellGroupConfig, - 1024); + NULL, + UE->masterCellGroup, //(void *)cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig, + 1024); resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3; //} itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p); } -static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const char *msg_name, instance_t instance){ - +static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance_t instance) +{ f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; NR_CellGroupConfig_t *cellGroupConfig = NULL; asn_dec_rval_t dec_rval = uper_decode_complete( NULL, @@ -3364,29 +3125,26 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch } //xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, cellGroupConfig); - if(ue_context_p->ue_context.masterCellGroup == NULL){ - ue_context_p->ue_context.masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t)); + if (UE->masterCellGroup == NULL) { + UE->masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t)); } if(cellGroupConfig->rlc_BearerToAddModList!=NULL){ - if(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList != NULL){ - int ue_ctxt_rlc_Bearers = ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list.count; + if (UE->masterCellGroup->rlc_BearerToAddModList != NULL) { + int ue_ctxt_rlc_Bearers = UE->masterCellGroup->rlc_BearerToAddModList->list.count; for(int i=ue_ctxt_rlc_Bearers; irlc_BearerToAddModList->list.count; i++){ - asn1cSeqAdd(&ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list, - cellGroupConfig->rlc_BearerToAddModList->list.array[i-ue_ctxt_rlc_Bearers]); + asn1cSeqAdd(&UE->masterCellGroup->rlc_BearerToAddModList->list, cellGroupConfig->rlc_BearerToAddModList->list.array[i - ue_ctxt_rlc_Bearers]); } - } - else{ + } else { LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n"); - ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); - memcpy(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, - sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + UE->masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + memcpy(UE->masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); } } if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, ue_context_p->ue_context.masterCellGroup); + xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup); } - if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { + if (UE->established_pdu_sessions_flag == 1) { fill_DRB_configList(&ctxt, ue_context_p); rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig); } else { @@ -3395,20 +3153,20 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch free(cellGroupConfig->rlc_BearerToAddModList); free(cellGroupConfig); - } -static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, const char *msg_name, instance_t instance){ - +static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance) +{ f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; e1ap_bearer_setup_req_t req = {0}; - req.numPDUSessionsMod = ue_context_p->ue_context.nb_of_pdusessions; - req.gNB_cu_cp_ue_id = ue_context_p->ue_context.gNB_ue_ngap_id; - req.rnti = ue_context_p->ue_context.rnti; + req.numPDUSessionsMod = UE->nb_of_pdusessions; + req.gNB_cu_cp_ue_id = UE->gNB_ue_ngap_id; + req.rnti = UE->rnti; for (int i=0; i < req.numPDUSessionsMod; i++) { req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; for (int j=0; j < resp->drbs_to_be_setup_length; j++) { @@ -3442,28 +3200,25 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, c } //xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, cellGroupConfig); - if(ue_context_p->ue_context.masterCellGroup == NULL){ - ue_context_p->ue_context.masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t)); + if (UE->masterCellGroup == NULL) { + UE->masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t)); } if(cellGroupConfig->rlc_BearerToAddModList!=NULL){ - if(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList != NULL){ - int ue_ctxt_rlc_Bearers = ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list.count; + if (UE->masterCellGroup->rlc_BearerToAddModList != NULL) { + int ue_ctxt_rlc_Bearers = UE->masterCellGroup->rlc_BearerToAddModList->list.count; for(int i=ue_ctxt_rlc_Bearers; irlc_BearerToAddModList->list.count; i++){ - asn1cSeqAdd(&ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list, - cellGroupConfig->rlc_BearerToAddModList->list.array[i-ue_ctxt_rlc_Bearers]); + asn1cSeqAdd(&UE->masterCellGroup->rlc_BearerToAddModList->list, cellGroupConfig->rlc_BearerToAddModList->list.array[i - ue_ctxt_rlc_Bearers]); } - } - else{ + } else { LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n"); - ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); - memcpy(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, - sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + UE->masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + memcpy(UE->masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); } } LOG_I(NR_RRC, "Updated master cell group configuration stored at the UE context of the CU:\n"); if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, ue_context_p->ue_context.masterCellGroup); + xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup); } rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig); @@ -3632,19 +3387,20 @@ static int get_dl_mimo_layers(const gNB_RRC_INST *rrc, const NR_UE_NR_Capability void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { MessageDef *msg; + gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; rrc_gNB_ue_context_t *ue_context_p = NULL; - RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head)) { - ctxt_pP->rntiMaybeUEid = ue_context_p->ue_id_rnti; - gNB_MAC_INST *nrmac=RC.nrmac[ctxt_pP->module_id]; //WHAT A BEAUTIFULL RACE CONDITION !!! + RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc->rrc_ue_head) + { + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + ctxt_pP->rntiMaybeUEid = UE->rnti; - if (ue_context_p->ue_context.ul_failure_timer > 0) { - ue_context_p->ue_context.ul_failure_timer++; + if (UE->ul_failure_timer > 0) { + UE->ul_failure_timer++; - if (ue_context_p->ue_context.ul_failure_timer >= 20000) { + if (UE->ul_failure_timer >= 20000) { // remove UE after 20 seconds after MAC (or else) has indicated UL failure - LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", - ue_context_p->ue_context.rnti); - if(ue_context_p->ue_context.StatusRrc >= NR_RRC_CONNECTED){ + LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", UE->rnti); + if (UE->StatusRrc >= NR_RRC_CONNECTED) { rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ( ctxt_pP->module_id, ue_context_p, @@ -3652,26 +3408,28 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST); } - // Remove here the MAC and RRC context when RRC is not connected or gNB is not connected to CN5G - if(ue_context_p->ue_context.StatusRrc < NR_RRC_CONNECTED || ue_context_p->ue_context.gNB_ue_ngap_id == 0) { - if(!NODE_IS_CU(RC.nrrrc[ctxt_pP->instance]->node_type)){ - mac_remove_nr_ue(nrmac, ctxt_pP->rntiMaybeUEid); + // Remove here the MAC and RRC context when RRC is not connected + if (UE->StatusRrc < NR_RRC_CONNECTED) { + if (!NODE_IS_CU(rrc->node_type)) { + gNB_MAC_INST *nrmac = RC.nrmac[ctxt_pP->module_id]; // WHAT A BEAUTIFULL RACE CONDITION !!! + mac_remove_nr_ue(nrmac, UE->rnti); rrc_rlc_remove_ue(ctxt_pP); pdcp_remove_UE(ctxt_pP); /* remove RRC UE Context */ - ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); + ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, UE->rnti); if (ue_context_p) { - rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p); - LOG_I(NR_RRC, "remove UE %lx \n", ctxt_pP->rntiMaybeUEid); + LOG_I(NR_RRC, "remove UE %04x \n", UE->rnti); + rrc_gNB_remove_ue_context(rrc, ue_context_p); + break; // We must not access this UE context } } // In case of CU trigger UE context release command towards the DU - else{ + else { MessageDef *message_p; message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); f1ap_ue_context_release_cmd_t *rel_cmd=&F1AP_UE_CONTEXT_RELEASE_CMD (message_p); - rel_cmd->rnti = ctxt_pP->rntiMaybeUEid; + rel_cmd->rnti = UE->rnti; rel_cmd->cause = F1AP_CAUSE_RADIO_NETWORK; rel_cmd->cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, message_p); @@ -3682,25 +3440,24 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { } } - if (ue_context_p->ue_context.ue_release_timer_rrc > 0) { - ue_context_p->ue_context.ue_release_timer_rrc++; + if (UE->ue_release_timer_rrc > 0) { + UE->ue_release_timer_rrc++; - if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) { - LOG_I(NR_RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", - ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ue_release_timer_rrc = 0; - mac_remove_nr_ue(nrmac, ctxt_pP->rntiMaybeUEid); + if (UE->ue_release_timer_rrc >= UE->ue_release_timer_thres_rrc) { + LOG_I(NR_RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", UE->rnti); + UE->ue_release_timer_rrc = 0; + if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) { + gNB_MAC_INST *nrmac = RC.nrmac[ctxt_pP->module_id]; // WHAT A BEAUTIFULL RACE CONDITION !!! + mac_remove_nr_ue(nrmac, UE->rnti); + } rrc_rlc_remove_ue(ctxt_pP); pdcp_remove_UE(ctxt_pP); - newGtpuDeleteAllTunnels(ctxt_pP->instance, ctxt_pP->rntiMaybeUEid); + newGtpuDeleteAllTunnels(ctxt_pP->instance, UE->rnti); /* remove RRC UE Context */ - ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); - if (ue_context_p) { - rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p); - LOG_I(NR_RRC, "remove UE %lx \n", ctxt_pP->rntiMaybeUEid); - } + LOG_I(NR_RRC, "remove UE %04x \n", UE->rnti); + rrc_gNB_remove_ue_context(rrc, ue_context_p); break; // break RB_FOREACH } } @@ -3741,14 +3498,15 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex /*Generate a UE context modification request message towards the DU to instruct the DU *for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/ + 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_context_p->ue_context.rnti, 0, 0, 0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); // TODO: So many hard codings MessageDef *message_p; message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(message_p); - req->rnti = ue_context_p->ue_context.rnti; + req->rnti = UE->rnti; req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0]; req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0]; req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0]; @@ -3780,10 +3538,10 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { // Find the UE context from UE ID and send ITTI message to F1AP to send UE context modification message to DU - uint16_t ue_initial_id = 0; // Making an invalid UE initial ID - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, resp->gNB_cu_cp_ue_id); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], resp->gNB_cu_cp_ue_id); + 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_context_p->ue_context.rnti, 0, 0, 0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0}; create_tunnel_resp.num_tunnels = resp->numPDUSessions; @@ -3834,9 +3592,10 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) rrc_gNB_ue_context_t *ue_context_p = NULL; /* cast is necessary to eliminate warning "discards ‘const’ qualifier" */ - RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &((gNB_RRC_INST *)rrc)->rrc_ue_head) { - const rnti_t rnti = ue_context_p->ue_id_rnti; + RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &((gNB_RRC_INST *)rrc)->rrc_ue_head) + { const gNB_RRC_UE_t *ue_ctxt = &ue_context_p->ue_context; + const rnti_t rnti = ue_ctxt->rnti; fprintf(f, "NR RRC UE rnti %04x:", rnti); @@ -3865,8 +3624,7 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// void *rrc_gnb_task(void *args_p) { - MessageDef *msg_p; - const char *msg_name_p; + MessageDef *msg_p; instance_t instance; int result; //SRB_INFO *srb_info_p; @@ -3883,9 +3641,9 @@ void *rrc_gnb_task(void *args_p) { while (1) { // Wait for a message itti_receive_msg(TASK_RRC_GNB, &msg_p); - msg_name_p = ITTI_MSG_NAME(msg_p); + const char *msg_name_p = ITTI_MSG_NAME(msg_p); instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); - + LOG_D(NR_RRC, "Received Msg %s\n", msg_name_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: LOG_W(NR_RRC, " *** Exiting NR_RRC thread\n"); @@ -3935,53 +3693,50 @@ void *rrc_gnb_task(void *args_p) { break; case NGAP_DOWNLINK_NAS: - rrc_gNB_process_NGAP_DOWNLINK_NAS(msg_p, msg_name_p, instance, &rrc_gNB_mui); + rrc_gNB_process_NGAP_DOWNLINK_NAS(msg_p, instance, &rrc_gNB_mui); break; case NGAP_PDUSESSION_SETUP_REQ: - rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(msg_p, msg_name_p, instance); + rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(msg_p, instance); break; case NGAP_PDUSESSION_MODIFY_REQ: - rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(msg_p, msg_name_p, instance); + rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(msg_p, instance); break; case NGAP_PDUSESSION_RELEASE_COMMAND: - rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(msg_p, msg_name_p, instance); + rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(msg_p, instance); break; /* Messages from gNB app */ case NRRRC_CONFIGURATION_REQ: - LOG_I(NR_RRC, "[gNB %ld] Received %s : %p\n", instance, msg_name_p,&NRRRC_CONFIGURATION_REQ(msg_p)); - openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(instance), &NRRRC_CONFIGURATION_REQ(msg_p)); + openair_rrc_gNB_configuration(instance, &NRRRC_CONFIGURATION_REQ(msg_p)); break; /* Messages from F1AP task */ case F1AP_SETUP_REQ: - AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type), - "should not receive F1AP_SETUP_REQUEST, need call by CU!\n"); - LOG_I(NR_RRC,"[gNB %ld] Received %s : %p\n", instance, msg_name_p, &F1AP_SETUP_REQ(msg_p)); + AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type), "should not receive F1AP_SETUP_REQUEST, need call by CU!\n"); rrc_gNB_process_f1_setup_req(&F1AP_SETUP_REQ(msg_p)); break; case NR_DU_RRC_DL_INDICATION: - rrc_process_DU_DL(msg_p, msg_name_p, instance); + rrc_process_DU_DL(msg_p, instance); break; case F1AP_UE_CONTEXT_SETUP_REQ: - rrc_DU_process_ue_context_setup_request(msg_p, msg_name_p, instance); + rrc_DU_process_ue_context_setup_request(msg_p, instance); break; case F1AP_UE_CONTEXT_SETUP_RESP: - rrc_CU_process_ue_context_setup_response(msg_p, msg_name_p, instance); + rrc_CU_process_ue_context_setup_response(msg_p, instance); break; case F1AP_UE_CONTEXT_MODIFICATION_RESP: - rrc_CU_process_ue_context_modification_response(msg_p, msg_name_p, instance); + rrc_CU_process_ue_context_modification_response(msg_p, instance); break; case F1AP_UE_CONTEXT_MODIFICATION_REQ: - rrc_DU_process_ue_context_modification_request(msg_p, msg_name_p, instance); + rrc_DU_process_ue_context_modification_request(msg_p, instance); break; case F1AP_UE_CONTEXT_RELEASE_CMD: @@ -3992,7 +3747,7 @@ void *rrc_gnb_task(void *args_p) { /* Messages from X2AP */ case X2AP_ENDC_SGNB_ADDITION_REQ: LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n"); - rrc_gNB_process_AdditionRequestInformation(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ(msg_p)); + rrc_gNB_process_AdditionRequestInformation(instance, &X2AP_ENDC_SGNB_ADDITION_REQ(msg_p)); break; case X2AP_ENDC_SGNB_RECONF_COMPLETE: @@ -4000,37 +3755,35 @@ void *rrc_gnb_task(void *args_p) { break; case NGAP_INITIAL_CONTEXT_SETUP_REQ: - rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p, msg_name_p, instance); + rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p, instance); break; case X2AP_ENDC_SGNB_RELEASE_REQUEST: LOG_I(NR_RRC, "Received ENDC sgNB release request from X2AP \n"); - rrc_gNB_process_release_request(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_RELEASE_REQUEST(msg_p)); + rrc_gNB_process_release_request(instance, &X2AP_ENDC_SGNB_RELEASE_REQUEST(msg_p)); break; case X2AP_ENDC_DC_OVERALL_TIMEOUT: - rrc_gNB_process_dc_overall_timeout(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_DC_OVERALL_TIMEOUT(msg_p)); + rrc_gNB_process_dc_overall_timeout(instance, &X2AP_ENDC_DC_OVERALL_TIMEOUT(msg_p)); break; case NGAP_UE_CONTEXT_RELEASE_REQ: - rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(msg_p, msg_name_p, instance); + rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(msg_p, instance); break; case NGAP_UE_CONTEXT_RELEASE_COMMAND: - rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p, msg_name_p, instance); + rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p, instance); break; case E1AP_SETUP_REQ: - LOG_I(NR_RRC, "Received E1AP_SETUP_REQ for instance %d\n", (int)instance); rrc_gNB_process_e1_setup_req(&E1AP_SETUP_REQ(msg_p), instance); break; case E1AP_BEARER_CONTEXT_SETUP_RESP: - LOG_I(NR_RRC, "Received E1AP_BEARER_CONTEXT_SETUP_RESP for instance %d\n", (int)instance); rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance); case NGAP_PAGING_IND: - rrc_gNB_process_PAGING_IND(msg_p, msg_name_p, instance); + rrc_gNB_process_PAGING_IND(msg_p, instance); break; default: @@ -4054,27 +3807,20 @@ rrc_gNB_generate_SecurityModeCommand( { uint8_t buffer[100]; uint8_t size; + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; T(T_ENB_RRC_SECURITY_MODE_COMMAND, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rntiMaybeUEid)); - NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_context_pP->ue_context.integrity_algorithm; - size = do_NR_SecurityModeCommand( - ctxt_pP, - buffer, - rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), - ue_context_pP->ue_context.ciphering_algorithm, - &integrity_algorithm); + NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_p->integrity_algorithm; + size = do_NR_SecurityModeCommand(ctxt_pP, buffer, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), ue_p->ciphering_algorithm, integrity_algorithm); LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Security Mode Command\n"); - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - size); + LOG_I(NR_RRC, "UE %04x Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", ue_p->rnti, size); switch (RC.nrrrc[ctxt_pP->module_id]->node_type) { case ngran_gNB_CU: case ngran_gNB_CUCP: // create an ITTI message - memcpy(ue_context_pP->ue_context.Srb1.Srb_info.Tx_buffer.Payload, buffer, size); - ue_context_pP->ue_context.Srb1.Srb_info.Tx_buffer.payload_size = size; + memcpy(ue_p->Srb[1].Srb_info.Tx_buffer.Payload, buffer, size); + ue_p->Srb[1].Srb_info.Tx_buffer.payload_size = size; LOG_I(NR_RRC,"calling rrc_data_req :securityModeCommand\n"); nr_rrc_data_req(ctxt_pP, @@ -4186,10 +3932,12 @@ rrc_gNB_generate_RRCRelease( { uint8_t buffer[RRC_BUF_SIZE] = {0}; int size = do_NR_RRCRelease(buffer, RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id)); - ue_context_pP->ue_context.ue_reestablishment_timer = 0; - ue_context_pP->ue_context.ue_release_timer = 0; - ue_context_pP->ue_context.ul_failure_timer = 0; - ue_context_pP->ue_context.ue_release_timer_rrc = 0; + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + + ue_p->ue_reestablishment_timer = 0; + ue_p->ue_release_timer = 0; + ue_p->ul_failure_timer = 0; + ue_p->ue_release_timer_rrc = 0; LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCRelease (bytes %d)\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), @@ -4220,8 +3968,8 @@ rrc_gNB_generate_RRCRelease( buffer, PDCP_TRANSMISSION_MODE_CONTROL); - rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_context_pP->ue_context.gNB_ue_ngap_id); - ue_context_pP->ue_context.ue_release_timer_rrc = 1; + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_p->gNB_ue_ngap_id); + ue_p->ue_release_timer_rrc = 1; } } diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.c b/openair2/RRC/NR/rrc_gNB_GTPV1U.c index d2831dcf5b..1322317b3e 100644 --- a/openair2/RRC/NR/rrc_gNB_GTPV1U.c +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.c @@ -44,68 +44,64 @@ extern RAN_CONTEXT_t RC; -int -rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( - const protocol_ctxt_t *const ctxt_pP, - const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, - uint8_t *inde_list -) { - int i; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - - if (create_tunnel_resp_pP) { - LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - create_tunnel_resp_pP->num_tunnels); - ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); - - for (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]; - 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]], - inde_list[i], - i, - create_tunnel_resp_pP->eps_bearer_id[i], - create_tunnel_resp_pP->enb_addr.length); - } - - return 0; - } else { +int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, uint8_t *inde_list) +{ + if (!create_tunnel_resp_pP) { + LOG_E(NR_RRC, "create_tunnel_resp_pP error\n"); return -1; } + + LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); + if (!ue_context_p) { + LOG_E(NR_RRC, "UE table error\n"); + 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]; + 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]], + inde_list[i], + i, + create_tunnel_resp_pP->eps_bearer_id[i], + create_tunnel_resp_pP->enb_addr.length); + } + + return 0; } int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, int offset) { - int i; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - - if (create_tunnel_resp_pP) { - LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - create_tunnel_resp_pP->num_tunnels); - ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); - - for (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]; - 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_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); - } - - return 0; - } else { + if (!create_tunnel_resp_pP) { + LOG_E(NR_RRC, "create_tunnel_resp_pP error\n"); return -1; } + + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); + if (!ue_context_p) { + LOG_E(NR_RRC, "UE table error\n"); + return -1; + } + + 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]; + 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_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); + } + + return 0; } diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index cb24040c9e..262bfec2a9 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -54,16 +54,21 @@ #include "RRC/NR/MESSAGES/asn1_msg.h" #include "NR_UERadioAccessCapabilityInformation.h" #include "NR_UE-CapabilityRAT-ContainerList.h" -#include "NGAP_Cause.h" #include "NGAP_CauseRadioNetwork.h" #include "f1ap_messages_types.h" #include "openair2/E1AP/e1ap_asnc.h" - +#include "NGAP_asn_constant.h" +#include "NGAP_PDUSessionResourceSetupRequestTransfer.h" +#include "NGAP_PDUSessionResourceModifyRequestTransfer.h" +#include "NGAP_ProtocolIE-Field.h" +#include "NGAP_GTPTunnel.h" +#include "NGAP_QosFlowSetupRequestItem.h" +#include "NGAP_QosFlowAddOrModifyRequestItem.h" +#include "NGAP_NonDynamic5QIDescriptor.h" +#include "conversions.h" +#include "RRC/NR/rrc_gNB_radio_bearers.h" extern RAN_CONTEXT_t RC; -/* Value to indicate an invalid UE initial id */ -static const uint16_t UE_INITIAL_ID_INVALID = 0; - /* Masks for NGAP Encryption algorithms, NEA0 is always supported (not coded) */ static const uint16_t NGAP_ENCRYPTION_NEA1_MASK = 0x8000; static const uint16_t NGAP_ENCRYPTION_NEA2_MASK = 0x4000; @@ -76,190 +81,7 @@ static const uint16_t NGAP_INTEGRITY_NIA3_MASK = 0x2000; #define INTEGRITY_ALGORITHM_NONE NR_IntegrityProtAlgorithm_nia0 -/*! \fn uint16_t get_next_ue_initial_id(uint8_t mod_id) - *\brief provide an UE initial ID for NGAP initial communication. - *\param mod_id Instance ID of gNB. - *\return the UE initial ID. - */ -//------------------------------------------------------------------------------ -static uint16_t -get_next_ue_initial_id( - const module_id_t mod_id -) -//------------------------------------------------------------------------------ -{ - static uint16_t ue_initial_id[NUMBER_OF_gNB_MAX]; - ue_initial_id[mod_id]++; - - /* Never use UE_INITIAL_ID_INVALID this is the invalid id! */ - if (ue_initial_id[mod_id] == UE_INITIAL_ID_INVALID) { - ue_initial_id[mod_id]++; - } - - return ue_initial_id[mod_id]; -} - -//------------------------------------------------------------------------------ -/* -* Get the UE NG struct containing hashtables NG_id/UE_id. -* Is also used to set the NG_id of the UE, depending on inputs. -*/ -struct rrc_ue_ngap_ids_s * -rrc_gNB_NGAP_get_ue_ids( - gNB_RRC_INST *const rrc_instance_pP, - const uint16_t ue_initial_id, - const uint32_t gNB_ue_ngap_idP -) -//------------------------------------------------------------------------------ -{ - rrc_ue_ngap_ids_t *result = NULL; - rrc_ue_ngap_ids_t *result2 = NULL; - /*****************************/ - instance_t instance = 0; - ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; - ngap_gNB_ue_context_t *ue_desc_p = NULL; - rrc_gNB_ue_context_t *ue_context_p = NULL; - /*****************************/ - hashtable_rc_t h_rc; - - if (ue_initial_id != UE_INITIAL_ID_INVALID) { - h_rc = hashtable_get(rrc_instance_pP->initial_id2_ngap_ids, (hash_key_t)ue_initial_id, (void **)&result); - - if (h_rc == HASH_TABLE_OK) { - if (gNB_ue_ngap_idP > 0) { - h_rc = hashtable_get(rrc_instance_pP->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_idP, (void **)&result2); - - if (h_rc != HASH_TABLE_OK) { // this case is equivalent to associate gNB_ue_ngap_idP and ue_initial_id - result2 = malloc(sizeof(*result2)); - - if (NULL != result2) { - *result2 = *result; - result2->gNB_ue_ngap_id = gNB_ue_ngap_idP; - result->gNB_ue_ngap_id = gNB_ue_ngap_idP; - h_rc = hashtable_insert(rrc_instance_pP->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_idP, result2); - - if (h_rc != HASH_TABLE_OK) { - LOG_E(NGAP, "[gNB %ld] Error while hashtable_insert in ngap_id2_ngap_ids gNB_ue_ngap_idP %"PRIu32"\n", - rrc_instance_pP - RC.nrrrc[0], - gNB_ue_ngap_idP); - } - } - } else { // here we should check that the association was done correctly - if ((result->ue_initial_id != result2->ue_initial_id) || (result->gNB_ue_ngap_id != result2->gNB_ue_ngap_id)) { - LOG_E(NGAP, "[gNB %ld] Error while hashtable_get, two rrc_ue_ngap_ids_t that should be equal, are not:\n \ - ue_initial_id 1 = %"PRIu16",\n \ - ue_initial_id 2 = %"PRIu16",\n \ - gNB_ue_ngap_idP 1 = %"PRIu32",\n \ - gNB_ue_ngap_idP 2 = %"PRIu32"\n", - rrc_instance_pP - RC.nrrrc[0], - result->ue_initial_id, - result2->ue_initial_id, - result->gNB_ue_ngap_id, - result2->gNB_ue_ngap_id); - // Still return *result - } - } - } // end if if (gNB_ue_ngap_idP > 0) - } else { // end if (h_rc == HASH_TABLE_OK) - LOG_E(NGAP, "[gNB %ld] In hashtable_get, couldn't find in initial_id2_ngap_ids ue_initial_id %"PRIu16"\n", - rrc_instance_pP - RC.nrrrc[0], - ue_initial_id); - return NULL; - /* - * At the moment this is written, this case shouldn't (cannot) happen and is equivalent to an error. - * One could try to find the struct instance based on ngap_id2_ngap_ids and gNB_ue_ngap_idP (if > 0), - * but this behavior is not expected at the moment. - */ - } // end else (h_rc != HASH_TABLE_OK) - } else { // end if (ue_initial_id != UE_INITIAL_ID_INVALID) - if (gNB_ue_ngap_idP > 0) { - h_rc = hashtable_get(rrc_instance_pP->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_idP, (void **)&result); - - if (h_rc != HASH_TABLE_OK) { - /* - * This case is uncommon, but can happen when: - * -> if the first NAS message was a Detach Request (non exhaustiv), the UE RRC context exist - * but is not associated with gNB_ue_ngap_id - * -> ... (?) - */ - LOG_E(NGAP, "[gNB %ld] In hashtable_get, couldn't find in ngap_id2_ngap_ids gNB_ue_ngap_idP %"PRIu32", trying to find it through NGAP context\n", - rrc_instance_pP - RC.nrrrc[0], - gNB_ue_ngap_idP); - instance = GNB_MODULE_ID_TO_INSTANCE(rrc_instance_pP - RC.nrrrc[0]); // get gNB instance - ngap_gNB_instance_p = ngap_gNB_get_instance(instance); // get ngap_gNB_instance - - if (ngap_gNB_instance_p != NULL) { - ue_desc_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, gNB_ue_ngap_idP); // get s1ap_eNB_ue_context - } else { - LOG_E(NGAP, "[gNB instance %ld] Couldn't find the gNB NGAP context\n", - instance); - return NULL; - } - - if (ue_desc_p != NULL) { - struct ngap_gNB_ue_context_s *ngap_ue_context_p = NULL; - - if ((ngap_ue_context_p = RB_REMOVE(ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head, ue_desc_p)) != NULL) { - LOG_E(NR_RRC, "Removed UE context gNB_ue_ngap_id %u\n", ngap_ue_context_p->gNB_ue_ngap_id); - ngap_gNB_free_ue_context(ngap_ue_context_p); - } else { - LOG_E(NR_RRC, "Removing UE context gNB_ue_ngap_id %u: did not find context\n",ue_desc_p->gNB_ue_ngap_id); - } - - return NULL; //skip the operation below to avoid loop - result = rrc_gNB_NGAP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, gNB_ue_ngap_idP); - - if (ue_desc_p->ue_initial_id != UE_INITIAL_ID_INVALID) { - result = rrc_gNB_NGAP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, gNB_ue_ngap_idP); - - if (result != NULL) { - ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], result->ue_rnti); - - if ((ue_context_p != NULL) && (ue_context_p->ue_context.gNB_ue_ngap_id == 0)) { - ue_context_p->ue_context.gNB_ue_ngap_id = gNB_ue_ngap_idP; - } else { - LOG_E(NR_RRC, "[gNB %ld] Incoherence between RRC context and NGAP context (%d != %d) for UE RNTI %d or UE RRC context doesn't exist\n", - rrc_instance_pP - RC.nrrrc[0], - (ue_context_p==NULL)?99999:ue_context_p->ue_context.gNB_ue_ngap_id, - gNB_ue_ngap_idP, - result->ue_rnti); - } - } - } else { - LOG_E(NGAP, "[gNB %ld] NGAP context found but ue_initial_id is invalid (0)\n", rrc_instance_pP - RC.nrrrc[0]); - return NULL; - } - } else { - LOG_E(NGAP, "[gNB %ld] In hashtable_get, couldn't find in ngap_id2_ngap_ids gNB_ue_ngap_idP %"PRIu32", because ue_initial_id is invalid in NGAP context\n", - rrc_instance_pP - RC.nrrrc[0], - gNB_ue_ngap_idP); - return NULL; - } - } // end if (h_rc != HASH_TABLE_OK) - } // end if (gNB_ue_ngap_idP > 0) - } // end else (ue_initial_id == UE_INITIAL_ID_INVALID) - - return result; -} - -//------------------------------------------------------------------------------ -struct rrc_gNB_ue_context_s * -rrc_gNB_get_ue_context_from_ngap_ids( - const instance_t instanceP, - const uint16_t ue_initial_idP, - const uint32_t gNB_ue_ngap_idP -) -//------------------------------------------------------------------------------ -{ - rrc_ue_ngap_ids_t *temp = NULL; - temp = rrc_gNB_NGAP_get_ue_ids(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instanceP)], ue_initial_idP, gNB_ue_ngap_idP); - - if (temp != NULL) { - return rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instanceP)], temp->ue_rnti); - } - - return NULL; -} +static int rrc_gNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP, ngap_security_capabilities_t *security_capabilities_pP); /*! \fn void process_gNB_security_key (const protocol_ctxt_t* const ctxt_pP, eNB_RRC_UE_t * const ue_context_pP, uint8_t *security_key) *\brief save security key. @@ -277,17 +99,19 @@ void process_gNB_security_key ( { char ascii_buffer[65]; uint8_t i; + gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; + /* Saves the security key */ - memcpy (ue_context_pP->ue_context.kgnb, security_key_pP, SECURITY_KEY_LENGTH); - memset (ue_context_pP->ue_context.nh, 0, SECURITY_KEY_LENGTH); - ue_context_pP->ue_context.nh_ncc = -1; + memcpy(UE->kgnb, security_key_pP, SECURITY_KEY_LENGTH); + memset(UE->nh, 0, SECURITY_KEY_LENGTH); + UE->nh_ncc = -1; for (i = 0; i < 32; i++) { - sprintf(&ascii_buffer[2 * i], "%02X", ue_context_pP->ue_context.kgnb[i]); + sprintf(&ascii_buffer[2 * i], "%02X", UE->kgnb[i]); } ascii_buffer[2 * i] = '\0'; - LOG_I(NR_RRC, "[gNB %d][UE %x] Saved security key %s\n", ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ascii_buffer); + LOG_I(NR_RRC, "[gNB %d][UE %x] Saved security key %s\n", ctxt_pP->module_id, UE->rnti, ascii_buffer); } //------------------------------------------------------------------------------ @@ -306,20 +130,15 @@ nr_rrc_pdcp_config_security( uint8_t *kUPenc = NULL; //uint8_t *k_kdf = NULL; static int print_keys= 1; + gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; /* Derive the keys from kgnb */ - if (SRB_configList != NULL) { - nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kgnb, - &kUPenc); + if (UE->Srb[1].Active || UE->Srb[2].Active) { + nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc); } - nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kgnb, - &kRRCenc); - nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kgnb, - &kRRCint); + nr_derive_key_rrc_enc(UE->ciphering_algorithm, UE->kgnb, &kRRCenc); + nr_derive_key_rrc_int(UE->integrity_algorithm, UE->kgnb, &kRRCint); if (!IS_SOFTMODEM_IQPLAYER) { SET_LOG_DUMP(DEBUG_SECURITY) ; } @@ -328,25 +147,20 @@ nr_rrc_pdcp_config_security( if ( LOG_DUMPFLAG( DEBUG_SECURITY ) ) { if (print_keys == 1 ) { print_keys =0; - LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, ue_context_pP->ue_context.kgnb, 32,"\nKgNB:" ); + LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, UE->kgnb, 32, "\nKgNB:"); LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 16,"\nKRRCenc:" ); LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 16,"\nKRRCint:" ); } } - pdcp_config_set_security( - ctxt_pP, - NULL, /* pdcp_pP not used anymore in NR */ - DCCH, - DCCH+2, - enable_ciphering ? - ue_context_pP->ue_context.ciphering_algorithm - | (ue_context_pP->ue_context.integrity_algorithm << 4) - : 0 - | (ue_context_pP->ue_context.integrity_algorithm << 4), - kRRCenc, - kRRCint, - kUPenc); + pdcp_config_set_security(ctxt_pP, + NULL, /* pdcp_pP not used anymore in NR */ + DCCH, + DCCH + 2, + enable_ciphering ? UE->ciphering_algorithm | (UE->integrity_algorithm << 4) : 0 | (UE->integrity_algorithm << 4), + kRRCenc, + kRRCint, + kUPenc); } //------------------------------------------------------------------------------ @@ -363,75 +177,51 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ( { // gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; MessageDef *message_p = NULL; - rrc_ue_ngap_ids_t *rrc_ue_ngap_ids_p = NULL; - hashtable_rc_t h_rc; + gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_NAS_FIRST_REQ); - memset(&message_p->ittiMsg.ngap_nas_first_req, 0, sizeof(ngap_nas_first_req_t)); - ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id(ctxt_pP->module_id); - NGAP_NAS_FIRST_REQ(message_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id; - rrc_ue_ngap_ids_p = malloc(sizeof(rrc_ue_ngap_ids_t)); - rrc_ue_ngap_ids_p->ue_initial_id = ue_context_pP->ue_context.ue_initial_id; - rrc_ue_ngap_ids_p->gNB_ue_ngap_id = UE_INITIAL_ID_INVALID; - rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rntiMaybeUEid; + ngap_nas_first_req_t *req = &NGAP_NAS_FIRST_REQ(message_p); + memset(req, 0, sizeof(*req)); - h_rc = hashtable_insert(RC.nrrrc[ctxt_pP->module_id]->initial_id2_ngap_ids, - (hash_key_t)ue_context_pP->ue_context.ue_initial_id, - rrc_ue_ngap_ids_p); - - if (h_rc != HASH_TABLE_OK) { - LOG_E(NGAP, "[gNB %d] Error while hashtable_insert in initial_id2_ngap_ids ue_initial_id %u\n", - ctxt_pP->module_id, - ue_context_pP->ue_context.ue_initial_id); - } + req->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; /* Assume that cause is coded in the same way in RRC and NGap, just check that the value is in NGap range */ - AssertFatal(ue_context_pP->ue_context.establishment_cause < NGAP_RRC_CAUSE_LAST, - "Establishment cause invalid (%jd/%d) for gNB %d!", - ue_context_pP->ue_context.establishment_cause, - NGAP_RRC_CAUSE_LAST, - ctxt_pP->module_id); - NGAP_NAS_FIRST_REQ(message_p).establishment_cause = ue_context_pP->ue_context.establishment_cause; - + AssertFatal(UE->establishment_cause < NGAP_RRC_CAUSE_LAST, "Establishment cause invalid (%jd/%d) for gNB %d!", UE->establishment_cause, NGAP_RRC_CAUSE_LAST, ctxt_pP->module_id); + req->establishment_cause = UE->establishment_cause; + /* Forward NAS message */ - NGAP_NAS_FIRST_REQ(message_p).nas_pdu.buffer = rrcSetupComplete->dedicatedNAS_Message.buf; - NGAP_NAS_FIRST_REQ(message_p).nas_pdu.length = rrcSetupComplete->dedicatedNAS_Message.size; + req->nas_pdu.buffer = rrcSetupComplete->dedicatedNAS_Message.buf; + req->nas_pdu.length = rrcSetupComplete->dedicatedNAS_Message.size; // extract_imsi(NGAP_NAS_FIRST_REQ (message_p).nas_pdu.buffer, // NGAP_NAS_FIRST_REQ (message_p).nas_pdu.length, // ue_context_pP); /* Fill UE identities with available information */ - NGAP_NAS_FIRST_REQ(message_p).ue_identity.presenceMask = NGAP_UE_IDENTITIES_NONE; + req->ue_identity.presenceMask = NGAP_UE_IDENTITIES_NONE; /* Fill s-TMSI */ - NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.amf_set_id = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id; - NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.amf_pointer = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer; - NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.m_tmsi = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi; + req->ue_identity.s_tmsi.amf_set_id = UE->Initialue_identity_5g_s_TMSI.amf_set_id; + req->ue_identity.s_tmsi.amf_pointer = UE->Initialue_identity_5g_s_TMSI.amf_pointer; + req->ue_identity.s_tmsi.m_tmsi = UE->Initialue_identity_5g_s_TMSI.fiveg_tmsi; /* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */ int selected_plmn_identity = rrcSetupComplete->selectedPLMN_Identity - 1; - NGAP_NAS_FIRST_REQ(message_p).selected_plmn_identity = selected_plmn_identity; + req->selected_plmn_identity = selected_plmn_identity; if (rrcSetupComplete->registeredAMF != NULL) { NR_RegisteredAMF_t *r_amf = rrcSetupComplete->registeredAMF; - NGAP_NAS_FIRST_REQ(message_p).ue_identity.presenceMask |= NGAP_UE_IDENTITIES_guami; + req->ue_identity.presenceMask |= NGAP_UE_IDENTITIES_guami; if (r_amf->plmn_Identity != NULL) { if ((r_amf->plmn_Identity->mcc != NULL) && (r_amf->plmn_Identity->mcc->list.count > 0)) { /* Use first indicated PLMN MCC if it is defined */ - NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc = *r_amf->plmn_Identity->mcc->list.array[selected_plmn_identity]; - LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", - ctxt_pP->module_id, - NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mcc, - ue_context_pP->ue_context.rnti); + req->ue_identity.guami.mcc = *r_amf->plmn_Identity->mcc->list.array[selected_plmn_identity]; + LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", ctxt_pP->module_id, req->ue_identity.guami.mcc, UE->rnti); } if (r_amf->plmn_Identity->mnc.list.count > 0) { /* Use first indicated PLMN MNC if it is defined */ - NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc = *r_amf->plmn_Identity->mnc.list.array[selected_plmn_identity]; - LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", - ctxt_pP->module_id, - NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mnc, - ue_context_pP->ue_context.rnti); + req->ue_identity.guami.mnc = *r_amf->plmn_Identity->mnc.list.array[selected_plmn_identity]; + LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", ctxt_pP->module_id, req->ue_identity.guami.mnc, UE->rnti); } } else { /* TODO */ @@ -439,192 +229,248 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ( /* amf_Identifier */ uint32_t amf_Id = BIT_STRING_to_uint32(&r_amf->amf_Identifier); - NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id = amf_Id >> 16; - NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id; - NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer; + req->ue_identity.guami.amf_region_id = amf_Id >> 16; + req->ue_identity.guami.amf_set_id = UE->Initialue_identity_5g_s_TMSI.amf_set_id; + req->ue_identity.guami.amf_pointer = UE->Initialue_identity_5g_s_TMSI.amf_pointer; - ue_context_pP->ue_context.ue_guami.mcc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc; - ue_context_pP->ue_context.ue_guami.mnc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc; - ue_context_pP->ue_context.ue_guami.mnc_len = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc_len; - ue_context_pP->ue_context.ue_guami.amf_region_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id; - ue_context_pP->ue_context.ue_guami.amf_set_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id; - ue_context_pP->ue_context.ue_guami.amf_pointer = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer; + // fixme: illogical place to set UE values, should be in the function that call this one + UE->ue_guami.mcc = req->ue_identity.guami.mcc; + UE->ue_guami.mnc = req->ue_identity.guami.mnc; + UE->ue_guami.mnc_len = req->ue_identity.guami.mnc_len; + UE->ue_guami.amf_region_id = req->ue_identity.guami.amf_region_id; + UE->ue_guami.amf_set_id = req->ue_identity.guami.amf_set_id; + UE->ue_guami.amf_pointer = req->ue_identity.guami.amf_pointer; - LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n", + LOG_I(NGAP, + "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n", ctxt_pP->module_id, - NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_set_id, - NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_region_id, - ue_context_pP->ue_context.rnti); + req->ue_identity.guami.amf_set_id, + req->ue_identity.guami.amf_region_id, + UE->rnti); } itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, message_p); } -//------------------------------------------------------------------------------ -int -rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( - MessageDef *msg_p, - const char *msg_name, - instance_t instance -) -//------------------------------------------------------------------------------ +static void fill_qos(NGAP_QosFlowSetupRequestList_t *qos, pdusession_t *session) { - uint16_t ue_initial_id; - uint32_t gNB_ue_ngap_id; - rrc_gNB_ue_context_t *ue_context_p = NULL; - protocol_ctxt_t ctxt={0}; - uint8_t pdu_sessions_done = 0; - gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp; - int ret = 0; - - ue_initial_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_initial_id; - gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).gNB_ue_ngap_id; - - ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id); - LOG_I(NR_RRC, "[gNB %ld] Received %s: ue_initial_id %d, gNB_ue_ngap_id %u \n", - instance, msg_name, ue_initial_id, gNB_ue_ngap_id); - - if (ue_context_p == NULL) { - /* Can not associate this message to an UE index, send a failure to NGAP and discard it! */ - MessageDef *msg_fail_p = NULL; - LOG_W(NR_RRC, "[gNB %ld] In NGAP_INITIAL_CONTEXT_SETUP_REQ: unknown UE from NGAP ids (%d, %u)\n", instance, ue_initial_id, 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 = gNB_ue_ngap_id; - // TODO add failure cause when defined! - itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); - return (-1); - } else { - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); - gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).gNB_ue_ngap_id; - ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id; - ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nas_pdu_flag; - - uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions; - if (nb_pdusessions_tosetup != 0) { - AssertFatal(rrc->node_type != ngran_gNB_CUCP, "PDU sessions in Initial context setup request not handled by E1 yet\n"); - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; - for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { - if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) - continue; - ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_NEW; - ue_context_p->ue_context.pduSession[i].param = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done]; - create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].pdusession_id; - create_tunnel_req.incoming_rb_id[pdu_sessions_done] = i+1; - create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].gtp_teid; - // To be developped: hardcoded first flow - create_tunnel_req.outgoing_qfi[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].qos[0].qfi; - create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.length; - memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer, - NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.buffer, - sizeof(uint8_t)*20); - LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n", - i, - create_tunnel_req.outgoing_teid[pdu_sessions_done], - create_tunnel_req.pdusession_id[pdu_sessions_done]); - pdu_sessions_done++; - - if(pdu_sessions_done >= nb_pdusessions_tosetup) { - break; - } - } - - ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions; - create_tunnel_req.ue_id = ue_context_p->ue_context.rnti; - create_tunnel_req.num_tunnels = pdu_sessions_done; - - ret = gtpv1u_create_ngu_tunnel( - instance, - &create_tunnel_req, - &create_tunnel_resp); - if (ret != 0) { - LOG_E(NR_RRC,"rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ue_release_timer_ng = 1; - ue_context_p->ue_context.ue_release_timer_thres_ng = 100; - ue_context_p->ue_context.ue_release_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - ue_context_p->ue_context.ul_failure_timer = 20000; - ue_context_p->ue_context.ul_failure_timer = 0; - return (0); - } - - nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt, &create_tunnel_resp, 0); - ue_context_p->ue_context.nb_of_pdusessions += NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions; - ue_context_p->ue_context.established_pdu_sessions_flag = 1; + DevAssert(qos->list.count > 0); + DevAssert(qos->list.count <= NGAP_maxnoofQosFlows); + for (int qosIdx = 0; qosIdx < qos->list.count; qosIdx++) { + NGAP_QosFlowSetupRequestItem_t *qosFlowItem_p = qos->list.array[qosIdx]; + // Set the QOS informations + session->qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; + NGAP_QosCharacteristics_t *qosChar = &qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics; + if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) { + if (qosChar->choice.nonDynamic5QI != NULL) { + session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI; } - - /* NAS PDU */ - if (NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag == 1) { - ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag; - ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length; - ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer; - } - - /* security */ - rrc_gNB_process_security(&ctxt, ue_context_p, &(NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_capabilities)); - process_gNB_security_key ( - &ctxt, - ue_context_p, - NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_key); - - /* configure only integrity, ciphering comes after receiving SecurityModeComplete */ - nr_rrc_pdcp_config_security(&ctxt, ue_context_p, 0); - - rrc_gNB_generate_SecurityModeCommand (&ctxt, ue_context_p); - - // in case, send the S1SP initial context response if it is not sent with the attach complete message - if (ue_context_p->ue_context.StatusRrc == NR_RRC_RECONFIGURED) { - LOG_I(NR_RRC, "Sending rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause); - rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(&ctxt,ue_context_p); } - return 0; + ngap_allocation_retention_priority_t *tmp = &session->qos[qosIdx].allocation_retention_priority; + NGAP_AllocationAndRetentionPriority_t *tmp2 = &qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority; + tmp->priority_level = tmp2->priorityLevelARP; + tmp->pre_emp_capability = tmp2->pre_emptionCapability; + tmp->pre_emp_vulnerability = tmp2->pre_emptionVulnerability; } + session->nb_qos = qos->list.count; +} + +static int decodePDUSessionResourceSetup(pdusession_t *session) +{ + NGAP_PDUSessionResourceSetupRequestTransfer_t *pdusessionTransfer; + for (int i=0; ipdusessionTransfer.length; i++) + printf("%02x:",session->pdusessionTransfer.buffer[i]); + printf("\n"); + asn_codec_ctx_t st = {.max_stack_size = 100 * 1000}; + asn_dec_rval_t dec_rval = + aper_decode(&st, &asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, (void **)&pdusessionTransfer, session->pdusessionTransfer.buffer, session->pdusessionTransfer.length, 0, 0); + + if (dec_rval.code != RC_OK) { + LOG_E(NR_RRC, "can not decode PDUSessionResourceSetupRequestTransfer\n"); + return -1; + } + + for (int i = 0; i < pdusessionTransfer->protocolIEs.list.count; i++) { + NGAP_PDUSessionResourceSetupRequestTransferIEs_t *pdusessionTransfer_ies = pdusessionTransfer->protocolIEs.list.array[i]; + switch (pdusessionTransfer_ies->id) { + /* optional PDUSessionAggregateMaximumBitRate */ + case NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate: + break; + + /* mandatory UL-NGU-UP-TNLInformation */ + case NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLInformation: { + NGAP_GTPTunnel_t *gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel; + + /* Set the transport layer address */ + memcpy(session->upf_addr.buffer, gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size); + + session->upf_addr.length = gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused; + + /* GTP tunnel endpoint ID */ + OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, session->gtp_teid); + } + + break; + + /* optional AdditionalUL-NGU-UP-TNLInformation */ + case NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation: + break; + + /* optional DataForwardingNotPossible */ + case NGAP_ProtocolIE_ID_id_DataForwardingNotPossible: + break; + + /* mandatory PDUSessionType */ + case NGAP_ProtocolIE_ID_id_PDUSessionType: + session->upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; + break; + + /* optional SecurityIndication */ + case NGAP_ProtocolIE_ID_id_SecurityIndication: + break; + + /* optional NetworkInstance */ + case NGAP_ProtocolIE_ID_id_NetworkInstance: + break; + + /* mandatory QosFlowSetupRequestList */ + case NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList: + fill_qos(&pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList, session); + break; + + /* optional CommonNetworkInstance */ + case NGAP_ProtocolIE_ID_id_CommonNetworkInstance: + break; + + default: + LOG_E(NR_RRC, "could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id); + return -1; + } + } + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer,pdusessionTransfer ); + + return 0; } //------------------------------------------------------------------------------ -void -rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP -) +int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t instance) //------------------------------------------------------------------------------ { - MessageDef *msg_p = NULL; - int pdusession; + protocol_ctxt_t ctxt = {0}; + ngap_initial_context_setup_req_t *req = &NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p); + + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + + 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); + return (-1); + } + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + UE->amf_ue_ngap_id = req->amf_ue_ngap_id; + uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions; + if (nb_pdusessions_tosetup) { + AssertFatal(false, "PDU sessions in Initial context setup request not handled by E1 yet\n"); + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0}; + for (int i = 0; i < nb_pdusessions_tosetup; i++) { + UE->nb_of_pdusessions++; + if(UE->pduSession[i].status >= PDU_SESSION_STATUS_DONE) + continue; + UE->pduSession[i].status = PDU_SESSION_STATUS_NEW; + UE->pduSession[i].param = req->pdusession_param[i]; + create_tunnel_req.num_tunnels++; + create_tunnel_req.pdusession_id[i] = req->pdusession_param[i].pdusession_id; + create_tunnel_req.outgoing_teid[i] = req->pdusession_param[i].gtp_teid; + // To be developped: hardcoded first flow + create_tunnel_req.outgoing_qfi[i] = req->pdusession_param[i].qos[0].qfi; + create_tunnel_req.dst_addr[i].length = req->pdusession_param[i].upf_addr.length; + memcpy(create_tunnel_req.dst_addr[i].buffer, req->pdusession_param[i].upf_addr.buffer, sizeof(create_tunnel_req.dst_addr[i].buffer)); + LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n", i, create_tunnel_req.outgoing_teid[i], create_tunnel_req.pdusession_id[i]); + } + create_tunnel_req.ue_id = UE->rnti; + gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp = {0}; + int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, &create_tunnel_resp); + if (ret != 0) { + LOG_E(NR_RRC, "rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n", UE->rnti); + UE->ue_release_timer_ng = 1; + UE->ue_release_timer_thres_ng = 100; + UE->ue_release_timer = 0; + UE->ue_reestablishment_timer = 0; + UE->ul_failure_timer = 20000; + UE->ul_failure_timer = 0; + return (0); + } + + nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt, &create_tunnel_resp, 0); + UE->established_pdu_sessions_flag = 1; + } + + /* NAS PDU */ + // this is malloced pointers, we pass it for later free() + UE->nas_pdu = req->nas_pdu; + + /* security */ + rrc_gNB_process_security(&ctxt, ue_context_p, &req->security_capabilities); + process_gNB_security_key(&ctxt, ue_context_p, req->security_key); + + /* configure only integrity, ciphering comes after receiving SecurityModeComplete */ + nr_rrc_pdcp_config_security(&ctxt, ue_context_p, 0); + + rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p); + + // in case, send the S1SP initial context response if it is not sent with the attach complete message + if (UE->StatusRrc == NR_RRC_RECONFIGURED) { + LOG_I(NR_RRC, "Sending rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", UE->reestablishment_cause); + rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(&ctxt, ue_context_p); + } + + return 0; +} + +//------------------------------------------------------------------------------ +void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP) +//------------------------------------------------------------------------------ +{ + MessageDef *msg_p = NULL; int pdu_sessions_done = 0; int pdu_sessions_failed = 0; - int qos_flow_index = 0; msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, NGAP_INITIAL_CONTEXT_SETUP_RESP); - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + ngap_initial_context_setup_resp_t *resp = &NGAP_INITIAL_CONTEXT_SETUP_RESP(msg_p); + gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; - for (pdusession = 0; pdusession < ue_context_pP->ue_context.nb_of_pdusessions; pdusession++) { - if (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_DONE) { + resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + + for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) { + rrc_pdu_session_param_t *session = &UE->pduSession[pdusession]; + if (session->status == PDU_SESSION_STATUS_DONE) { pdu_sessions_done++; - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id; - // TODO add other information from S1-U when it will be integrated - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession]; - memcpy(NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.buffer , ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, 20); - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.length = 4; - ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED; - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos; - for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos; qos_flow_index++) { - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi = - ue_context_pP->ue_context.pduSession[pdusession].param.qos[qos_flow_index].qfi; - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL; + 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].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; + resp->pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL; } } else { pdu_sessions_failed++; - ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_FAILED; - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id; + resp->pdusessions_failed[pdusession].pdusession_id = session->param.pdusession_id; // TODO add cause when it will be integrated - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].cause = NGAP_CAUSE_RADIO_NETWORK; - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; + resp->pdusessions_failed[pdusession].cause = NGAP_CAUSE_RADIO_NETWORK; + resp->pdusessions_failed[pdusession].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; } } - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions = pdu_sessions_done; - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions_failed = pdu_sessions_failed; + resp->nb_of_pdusessions = pdu_sessions_done; + resp->nb_of_pdusessions_failed = pdu_sessions_failed; itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); } @@ -700,144 +546,105 @@ static e_NR_IntegrityProtAlgorithm rrc_gNB_select_integrity( return ret; } -int -rrc_gNB_process_security( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - ngap_security_capabilities_t *security_capabilities_pP -) { +static int rrc_gNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP, ngap_security_capabilities_t *security_capabilities_pP) +{ bool changed = false; NR_CipheringAlgorithm_t cipheringAlgorithm; e_NR_IntegrityProtAlgorithm integrityProtAlgorithm; + gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; + /* Save security parameters */ - ue_context_pP->ue_context.security_capabilities = *security_capabilities_pP; + UE->security_capabilities = *security_capabilities_pP; // translation LOG_D(NR_RRC, "[gNB %d] NAS security_capabilities.encryption_algorithms %u AS ciphering_algorithm %lu NAS security_capabilities.integrity_algorithms %u AS integrity_algorithm %u\n", ctxt_pP->module_id, - ue_context_pP->ue_context.security_capabilities.nRencryption_algorithms, - (unsigned long)ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.security_capabilities.nRintegrity_algorithms, - ue_context_pP->ue_context.integrity_algorithm); + UE->security_capabilities.nRencryption_algorithms, + (unsigned long)UE->ciphering_algorithm, + UE->security_capabilities.nRintegrity_algorithms, + UE->integrity_algorithm); /* Select relevant algorithms */ - cipheringAlgorithm = rrc_gNB_select_ciphering(ctxt_pP, ue_context_pP->ue_context.security_capabilities.nRencryption_algorithms); + cipheringAlgorithm = rrc_gNB_select_ciphering(ctxt_pP, UE->security_capabilities.nRencryption_algorithms); - if (ue_context_pP->ue_context.ciphering_algorithm != cipheringAlgorithm) { - ue_context_pP->ue_context.ciphering_algorithm = cipheringAlgorithm; + if (UE->ciphering_algorithm != cipheringAlgorithm) { + UE->ciphering_algorithm = cipheringAlgorithm; changed = true; } - integrityProtAlgorithm = rrc_gNB_select_integrity(ctxt_pP, ue_context_pP->ue_context.security_capabilities.nRintegrity_algorithms); + integrityProtAlgorithm = rrc_gNB_select_integrity(ctxt_pP, UE->security_capabilities.nRintegrity_algorithms); - if (ue_context_pP->ue_context.integrity_algorithm != integrityProtAlgorithm) { - ue_context_pP->ue_context.integrity_algorithm = integrityProtAlgorithm; + if (UE->integrity_algorithm != integrityProtAlgorithm) { + UE->integrity_algorithm = integrityProtAlgorithm; changed = true; } - LOG_I (NR_RRC, "[gNB %d][UE %x] Selected security algorithms (%p): %lx, %x, %s\n", - ctxt_pP->module_id, - ue_context_pP->ue_context.rnti, - security_capabilities_pP, - (unsigned long)cipheringAlgorithm, - integrityProtAlgorithm, - changed ? "changed" : "same"); + LOG_I(NR_RRC, + "[gNB %d][UE %x] Selected security algorithms (%p): %lx, %x, %s\n", + ctxt_pP->module_id, + UE->rnti, + security_capabilities_pP, + (unsigned long)cipheringAlgorithm, + integrityProtAlgorithm, + changed ? "changed" : "same"); return changed; } //------------------------------------------------------------------------------ -int -rrc_gNB_process_NGAP_DOWNLINK_NAS( - MessageDef *msg_p, - const char *msg_name, - instance_t instance, - mui_t *rrc_gNB_mui -) +int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mui_t *rrc_gNB_mui) //------------------------------------------------------------------------------ { - uint16_t ue_initial_id; - uint32_t gNB_ue_ngap_id; - uint32_t length; - uint8_t *buffer; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - protocol_ctxt_t ctxt; - memset(&ctxt, 0, sizeof(protocol_ctxt_t)); - ue_initial_id = NGAP_DOWNLINK_NAS (msg_p).ue_initial_id; - gNB_ue_ngap_id = NGAP_DOWNLINK_NAS (msg_p).gNB_ue_ngap_id; - ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id); - LOG_I(NR_RRC, "[gNB %ld] Received %s: ue_initial_id %d, gNB_ue_ngap_id %u\n", - instance, - msg_name, - ue_initial_id, - gNB_ue_ngap_id); + uint32_t length; + uint8_t *buffer; + protocol_ctxt_t ctxt = {0}; + ngap_downlink_nas_t *req = &NGAP_DOWNLINK_NAS(msg_p); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id); - if (ue_context_p == NULL) { - /* Can not associate this message to an UE index, send a failure to NGAP and discard it! */ - MessageDef *msg_fail_p; - LOG_W(NR_RRC, "[gNB %ld] In NGAP_DOWNLINK_NAS: unknown UE from NGAP ids (%d, %u)\n", instance, ue_initial_id, gNB_ue_ngap_id); - msg_fail_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_NAS_NON_DELIVERY_IND); - NGAP_NAS_NON_DELIVERY_IND (msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; - NGAP_NAS_NON_DELIVERY_IND (msg_fail_p).nas_pdu.length = NGAP_DOWNLINK_NAS (msg_p).nas_pdu.length; - NGAP_NAS_NON_DELIVERY_IND (msg_fail_p).nas_pdu.buffer = NGAP_DOWNLINK_NAS (msg_p).nas_pdu.buffer; - // TODO add failure cause when defined! - itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); - return (-1); - } else { - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + 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; + LOG_W(NR_RRC, "[gNB %ld] In NGAP_DOWNLINK_NAS: 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_NAS_NON_DELIVERY_IND); + ngap_nas_non_delivery_ind_t *msg = &NGAP_NAS_NON_DELIVERY_IND(msg_fail_p); + msg->gNB_ue_ngap_id = req->gNB_ue_ngap_id; + msg->nas_pdu.length = req->nas_pdu.length; + msg->nas_pdu.buffer = req->nas_pdu.buffer; + // TODO add failure cause when defined! + itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); + return (-1); + } - /* Is it the first income from NGAP ? */ - if (ue_context_p->ue_context.gNB_ue_ngap_id == 0) { - ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_DOWNLINK_NAS (msg_p).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); - /* Create message for PDCP (DLInformationTransfer_t) */ - length = do_NR_DLInformationTransfer ( - instance, - &buffer, - rrc_gNB_get_next_transaction_identifier (instance), - NGAP_DOWNLINK_NAS (msg_p).nas_pdu.length, - NGAP_DOWNLINK_NAS (msg_p).nas_pdu.buffer); - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, buffer, length, "[MSG] RRC DL Information Transfer\n"); - /* - * switch UL or DL NAS message without RRC piggybacked to SRB2 if active. - */ - switch (RC.nrrrc[ctxt.module_id]->node_type) { - case ngran_gNB_CU: - case ngran_gNB_CUCP: - /* Transfer data to PDCP */ - nr_rrc_data_req ( - &ctxt, - ue_context_p->ue_context.Srb2.Active == 1 ? ue_context_p->ue_context.Srb2.Srb_info.Srb_id : ue_context_p->ue_context.Srb1.Srb_info.Srb_id, - (*rrc_gNB_mui)++, - SDU_CONFIRM_NO, - length, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); - break; + /* Create message for PDCP (DLInformationTransfer_t) */ + length = do_NR_DLInformationTransfer(instance, &buffer, rrc_gNB_get_next_transaction_identifier(instance), req->nas_pdu.length, req->nas_pdu.buffer); + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, buffer, length, "[MSG] RRC DL Information Transfer\n"); + /* + * switch UL or DL NAS message without RRC piggybacked to SRB2 if active. + */ + switch (RC.nrrrc[ctxt.module_id]->node_type) { + case ngran_gNB_CU: + case ngran_gNB_CUCP: + case ngran_gNB: { + long srb_id; + if (UE->Srb[2].Active) + srb_id = UE->Srb[2].Srb_info.Srb_id; + else + srb_id = UE->Srb[1].Srb_info.Srb_id; + AssertFatal(srb_id > 0 && srb_id < maxSRBs, ""); + /* Transfer data to PDCP */ + nr_rrc_data_req(&ctxt, srb_id, (*rrc_gNB_mui)++, SDU_CONFIRM_NO, length, buffer, PDCP_TRANSMISSION_MODE_CONTROL); + free(buffer); // nr_rrc_data_req do a second malloc and copy + } break; - case ngran_gNB_DU: - // nothing to do for DU - AssertFatal(1==0,"nothing to do for DU\n"); - break; + case ngran_gNB_DU: + // nothing to do for DU + break; - case ngran_gNB: - { - /* Transfer data to PDCP */ - nr_rrc_data_req ( - &ctxt, - ue_context_p->ue_context.Srb2.Active == 1 ? ue_context_p->ue_context.Srb2.Srb_info.Srb_id : ue_context_p->ue_context.Srb1.Srb_info.Srb_id, - (*rrc_gNB_mui)++, - SDU_CONFIRM_NO, - length, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); - } - break; - - default : - LOG_W(NR_RRC, "Unknown node type %d\n", RC.nrrrc[ctxt.module_id]->node_type); - } - return (0); - } + default: + LOG_W(NR_RRC, "Unknown node type %d\n", RC.nrrrc[ctxt.module_id]->node_type); + } + return (0); } //------------------------------------------------------------------------------ @@ -853,12 +660,13 @@ rrc_gNB_send_NGAP_UPLINK_NAS( uint8_t *pdu_buffer; MessageDef *msg_p; NR_ULInformationTransfer_t *ulInformationTransfer = ul_dcch_msg->message.choice.c1->choice.ulInformationTransfer; + gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; if (ulInformationTransfer->criticalExtensions.present == NR_ULInformationTransfer__criticalExtensions_PR_ulInformationTransfer) { pdu_length = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message->size; pdu_buffer = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message->buf; msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UPLINK_NAS); - NGAP_UPLINK_NAS (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->gNB_ue_ngap_id; NGAP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length; NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer; // extract_imsi(NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer, @@ -881,156 +689,118 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( MessageDef *msg_p; int pdu_sessions_done = 0; int pdu_sessions_failed = 0; - int pdusession; - int qos_flow_index; msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_RESP); - NGAP_PDUSESSION_SETUP_RESP(msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + ngap_pdusession_setup_resp_t *resp = &NGAP_PDUSESSION_SETUP_RESP(msg_p); + gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; + resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; - for (pdusession = 0; pdusession < ue_context_pP->ue_context.nb_of_pdusessions; pdusession++) { - // if (xid == ue_context_pP->ue_context.pdusession[pdusession].xid) { - if (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_DONE) { - pdusession_setup_t * tmp=&NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdu_sessions_done]; - tmp->pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id; - // tmp->pdusession_id = 1; - tmp->nb_of_qos_flow = ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos; - tmp->gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession]; - tmp->gNB_addr.pdu_session_type = PDUSessionType_ipv4; - tmp->gNB_addr.length = ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].length; - memcpy(tmp->gNB_addr.buffer, - ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, tmp->gNB_addr.length); - for (qos_flow_index = 0; qos_flow_index < tmp->nb_of_qos_flow; qos_flow_index++) { - tmp->associated_qos_flows[qos_flow_index].qfi = - ue_context_pP->ue_context.pduSession[pdusession].param.qos[qos_flow_index].qfi; - tmp->associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL; - } - - ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED; - LOG_I (NR_RRC,"gnb_gtp_addr (msg index %d, pdu_sessions index %d, status %d, xid %d): nb_of_pdusessions %d, pdusession_id %d, teid: %u \n ", - pdu_sessions_done, pdusession, ue_context_pP->ue_context.pduSession[pdusession].status, xid, - ue_context_pP->ue_context.nb_of_pdusessions, - NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].pdusession_id, - NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gtp_teid); - pdu_sessions_done++; - } else if ((ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_NEW) || - (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_ESTABLISHED)) { - LOG_D (NR_RRC,"PDU-SESSION is NEW or already ESTABLISHED\n"); - } else { /* to be improved */ - ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_FAILED; - NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id; - pdu_sessions_failed++; - // TODO add cause when it will be integrated + for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) { + rrc_pdu_session_param_t *session = &UE->pduSession[pdusession]; + if (session->status == PDU_SESSION_STATUS_DONE) { + 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); + 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; } - NGAP_PDUSESSION_SETUP_RESP(msg_p).nb_of_pdusessions = pdu_sessions_done; - NGAP_PDUSESSION_SETUP_RESP(msg_p).nb_of_pdusessions_failed = pdu_sessions_failed; + + session->status = PDU_SESSION_STATUS_ESTABLISHED; + LOG_I(NR_RRC, + "msg index %d, pdu_sessions index %d, status %d, xid %d): nb_of_pdusessions %d, pdusession_id %d, teid: %u \n ", + pdu_sessions_done, + pdusession, + session->status, + xid, + UE->nb_of_pdusessions, + tmp->pdusession_id, + tmp->gtp_teid); + pdu_sessions_done++; + } else if (session->status != PDU_SESSION_STATUS_ESTABLISHED) { + session->status = PDU_SESSION_STATUS_FAILED; + resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = session->param.pdusession_id; + pdu_sessions_failed++; + // TODO add cause when it will be integrated + } + resp->nb_of_pdusessions = pdu_sessions_done; + resp->nb_of_pdusessions_failed = pdu_sessions_failed; // } else { // LOG_D(NR_RRC,"xid does not corresponds (context pdu_sessions index %d, status %d, xid %d/%d) \n ", - // pdusession, ue_context_pP->ue_context.pdusession[pdusession].status, xid, ue_context_pP->ue_context.pdusession[pdusession].xid); + // pdusession, UE->pdusession[pdusession].status, xid, UE->pdusession[pdusession].xid); // } } - if ((pdu_sessions_done > 0) ) { - LOG_I(NR_RRC, - "NGAP_PDUSESSION_SETUP_RESP: sending the message: nb_of_pdusessions %d, total pdu_sessions %d, index %d\n", - ue_context_pP->ue_context.nb_of_pdusessions, - ue_context_pP->ue_context.nb_of_pdusessions, - pdusession); + if ((pdu_sessions_done > 0 || pdu_sessions_failed)) { + LOG_I(NR_RRC, "NGAP_PDUSESSION_SETUP_RESP: sending the message\n"); itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); } for(int i = 0; i < NB_RB_MAX; i++) { - ue_context_pP->ue_context.pduSession[i].xid = -1; + UE->pduSession[i].xid = -1; } return; } //------------------------------------------------------------------------------ -void -rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( - MessageDef *msg_p, - const char *msg_name, - instance_t instance -) +void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance) //------------------------------------------------------------------------------ { - gNB_RRC_INST *rrc; - uint16_t ue_initial_id; - uint32_t gNB_ue_ngap_id; + 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_initial_id = msg->ue_initial_id; - gNB_ue_ngap_id = msg->gNB_ue_ngap_id; - ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); + 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]; - LOG_I(NR_RRC, "[gNB %ld] Received %s: ue_initial_id %d, gNB_ue_ngap_id %u \n", - instance, msg_name, ue_initial_id, gNB_ue_ngap_id); + LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, msg->gNB_ue_ngap_id); if (ue_context_p == NULL) { MessageDef *msg_fail_p = NULL; - LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_SETUP_REQ: unknown UE from NGAP ids (%d, %u)\n", instance, ue_initial_id, gNB_ue_ngap_id); + LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_SETUP_REQ: unknown UE from NGAP ids (%u)\n", instance, msg->gNB_ue_ngap_id); msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_REQUEST_FAIL); - NGAP_PDUSESSION_SETUP_REQ(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; + NGAP_PDUSESSION_SETUP_FAIL(msg_fail_p).gNB_ue_ngap_id = msg->gNB_ue_ngap_id; // TODO add failure cause when defined! itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); return ; } - ue_context_p->ue_context.gNB_ue_ngap_id = msg->gNB_ue_ngap_id; - ue_context_p->ue_context.amf_ue_ngap_id = msg->amf_ue_ngap_id; + UE->gNB_ue_ngap_id = msg->gNB_ue_ngap_id; + UE->amf_ue_ngap_id = msg->amf_ue_ngap_id; + e1ap_bearer_setup_req_t bearer_req = {0}; - /* Configurations are referred from rrc_gNB_generate_dedicatedRRCReconfiguration() and - rrc_gNB_process_RRCReconfigurationComplete() + for (int i = 0; i < msg->nb_pdusessions_tosetup; i++) { + rrc_pdu_session_param_t *pduSession = find_pduSession(UE, msg->pdusession_setup_params[i].pdusession_id, true); + 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->nas_pdu = msg->pdusession_setup_params[i].nas_pdu; + session->pdusessionTransfer = msg->pdusession_setup_params[i].pdusessionTransfer; + decodePDUSessionResourceSetup(session); + bearer_req.gNB_cu_cp_ue_id = msg->gNB_ue_ngap_id; + bearer_req.rnti = UE->rnti; + bearer_req.cipheringAlgorithm = UE->ciphering_algorithm; + memcpy(bearer_req.encryptionKey, UE->kgnb, sizeof(UE->kgnb)); + bearer_req.integrityProtectionAlgorithm = UE->integrity_algorithm; + memcpy(bearer_req.integrityProtectionKey, UE->kgnb, sizeof(UE->kgnb)); + bearer_req.ueDlAggMaxBitRate = msg->ueAggMaxBitRateDownlink; + pdu_session_to_setup_t *pdu = bearer_req.pduSession + bearer_req.numPDUSessions; + bearer_req.numPDUSessions++; + pdu->sessionId = session->pdusession_id; + pdu->sst = msg->allowed_nssai[i].sST; + pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed; - At CU-CP we configure the E1 bearer context setup parameters (PDU sessions, DRBs and - QoS flows) same as in these functions. At CU-UP we create PDU Sessions and allocate DRBs. - */ - e1ap_bearer_setup_req_t bearer_req; - - bearer_req.gNB_cu_cp_ue_id = gNB_ue_ngap_id; - bearer_req.rnti = ue_context_p->ue_context.rnti; - bearer_req.cipheringAlgorithm = ue_context_p->ue_context.ciphering_algorithm; - memcpy(bearer_req.encryptionKey, ue_context_p->ue_context.kgnb, sizeof(ue_context_p->ue_context.kgnb)); - bearer_req.integrityProtectionAlgorithm = ue_context_p->ue_context.integrity_algorithm; - memcpy(bearer_req.integrityProtectionKey, ue_context_p->ue_context.kgnb, sizeof(ue_context_p->ue_context.kgnb)); - bearer_req.ueDlAggMaxBitRate = msg->ueAggMaxBitRateDownlink; - - bearer_req.numPDUSessions = msg->nb_pdusessions_tosetup; - int xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id); - - for (int i=0; i < bearer_req.numPDUSessions; i++) { - int idx = ue_context_p->ue_context.nb_of_pdusessions++; - pdu_session_to_setup_t *pdu = bearer_req.pduSession + i; + pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed; + pdu->teId = session->gtp_teid; + memcpy(&pdu->tlAddress, session->upf_addr.buffer, 4); // Fixme: dirty IPv4 target pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding - ue_context_p->ue_context.pduSession[idx].param = msg->pdusession_setup_params[i]; - ue_context_p->ue_context.pduSession[idx].xid = xid; - ue_context_p->ue_context.pduSession[idx].status = PDU_SESSION_STATUS_NEW; - - pdu->sessionId = msg->pdusession_setup_params[i].pdusession_id; - pdu->sessionType = msg->pdusession_setup_params[i].upf_addr.pdu_session_type; - pdu->sst = msg->allowed_nssai[i].sST; - if (rrc->security.do_drb_integrity) { - pdu->integrityProtectionIndication = E1AP_IntegrityProtectionIndication_required; - } else { - pdu->integrityProtectionIndication = E1AP_IntegrityProtectionIndication_not_needed; - } - - if (rrc->security.do_drb_ciphering) { - pdu->confidentialityProtectionIndication = E1AP_ConfidentialityProtectionIndication_required; - } else { - pdu->confidentialityProtectionIndication = E1AP_ConfidentialityProtectionIndication_not_needed; - } - pdu->teId = msg->pdusession_setup_params[i].gtp_teid; - memcpy(&pdu->tlAddress, - msg->pdusession_setup_params[i].upf_addr.buffer, - sizeof(uint8_t)*4); - - ue_context_p->ue_context.pduSession[idx].param = msg->pdusession_setup_params[i]; - ue_context_p->ue_context.gNB_ue_ngap_id = msg->gNB_ue_ngap_id; - ue_context_p->ue_context.amf_ue_ngap_id = msg->amf_ue_ngap_id; for (int j=0; j < pdu->numDRB2Setup; j++) { DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j; @@ -1056,183 +826,197 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( cellGroup->id = 0; // MCG } - drb->numQosFlow2Setup = msg->pdusession_setup_params[i].nb_qos; + drb->numQosFlow2Setup = session->nb_qos; for (int k=0; k < drb->numQosFlow2Setup; k++) { qos_flow_to_setup_t *qos = drb->qosFlows + k; - qos->id = msg->pdusession_setup_params[j].qos[k].qfi; - qos->fiveQI = msg->pdusession_setup_params[j].qos[k].fiveQI; - qos->fiveQI_type = msg->pdusession_setup_params[j].qos[k].fiveQI_type; + qos->id = session->qos[k].qfi; + qos->fiveQI = session->qos[k].fiveQI; + qos->fiveQI_type = session->qos[k].fiveQI_type; - qos->qoSPriorityLevel = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.priority_level; - qos->pre_emptionCapability = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_capability; - qos->pre_emptionVulnerability = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_vulnerability; + qos->qoSPriorityLevel = session->qos[k].allocation_retention_priority.priority_level; + qos->pre_emptionCapability = session->qos[k].allocation_retention_priority.pre_emp_capability; + qos->pre_emptionVulnerability = session->qos[k].allocation_retention_priority.pre_emp_vulnerability; } } } - rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance); return; } -//------------------------------------------------------------------------------ -int -rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ( - MessageDef *msg_p, - const char *msg_name, - instance_t instance -) -//------------------------------------------------------------------------------ +static void fill_qos2(NGAP_QosFlowAddOrModifyRequestList_t *qos, pdusession_t *session) { - uint16_t ue_initial_id; - uint32_t gNB_ue_ngap_id; - uint8_t nb_pdusessions_tomodify; - rrc_gNB_ue_context_t *ue_context_p = NULL; - uint8_t i; - uint8_t qos_flow_index; - protocol_ctxt_t ctxt; - - ue_initial_id = NGAP_PDUSESSION_MODIFY_REQ(msg_p).ue_initial_id; - gNB_ue_ngap_id = NGAP_PDUSESSION_MODIFY_REQ(msg_p).gNB_ue_ngap_id; - nb_pdusessions_tomodify = NGAP_PDUSESSION_MODIFY_REQ(msg_p).nb_pdusessions_tomodify; - - ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id); - if (ue_context_p == NULL) { - LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_MODIFY_REQ: unknown UE from NGAP ids (%d, %u)\n", instance, ue_initial_id, gNB_ue_ngap_id); - // TODO - return (-1); - } else { - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); - ctxt.eNB_index = 0; - - ue_context_p->ue_context.gNB_ue_ngap_id = gNB_ue_ngap_id; - { - int j; - bool is_treated[NGAP_MAX_PDUSESSION] = {false}; - uint8_t nb_of_failed_pdusessions = 0; - - for (i = 0; i < nb_pdusessions_tomodify; i++) { - if (is_treated[i] == true) { - continue; - } - - //Check if same PDU session ID to handle multiple pdu sessions - for (j = i+1; j < nb_pdusessions_tomodify; j++) { - if (is_treated[j] == false && - NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[j].pdusession_id == - NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].pdusession_id) { - // handle multiple pdu session id - LOG_D(NR_RRC, "handle multiple pdu session id \n"); - ue_context_p->ue_context.modify_pdusession[j].status = PDU_SESSION_STATUS_NEW; - ue_context_p->ue_context.modify_pdusession[j].param.pdusession_id = - NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[j].pdusession_id; - ue_context_p->ue_context.modify_pdusession[j].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_context_p->ue_context.modify_pdusession[j].cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances; - nb_of_failed_pdusessions++; - is_treated[i] = true; - is_treated[j] = true; - } - } - // handle multiple pdu session id case - if (is_treated[i] == true) { - LOG_D(NR_RRC, "handle multiple pdu session id \n"); - ue_context_p->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_NEW; - ue_context_p->ue_context.modify_pdusession[i].param.pdusession_id = - NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].pdusession_id; - ue_context_p->ue_context.modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_context_p->ue_context.modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances; - nb_of_failed_pdusessions++; - continue; - } - - // Check pdu session ID is established - for (j = 0; j < NR_NB_RB_MAX -3; j++) { - if (ue_context_p->ue_context.pduSession[j].param.pdusession_id == - NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].pdusession_id) { - if (ue_context_p->ue_context.pduSession[j].status == PDU_SESSION_STATUS_TORELEASE || - ue_context_p->ue_context.pduSession[j].status == PDU_SESSION_STATUS_DONE) { - break; - } - // Found established pdu session, prepare to send RRC message - ue_context_p->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_NEW; - ue_context_p->ue_context.modify_pdusession[i].param.pdusession_id = - NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].pdusession_id; - ue_context_p->ue_context.modify_pdusession[i].cause = NGAP_CAUSE_NOTHING; - if (NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].nas_pdu.buffer != NULL) { - ue_context_p->ue_context.modify_pdusession[i].param.nas_pdu.buffer = - NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].nas_pdu.buffer; - ue_context_p->ue_context.modify_pdusession[i].param.nas_pdu.length = - NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].nas_pdu.length; - } - // Save new pdu session parameters, qos, upf addr, teid - for (qos_flow_index = 0; qos_flow_index < NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].nb_qos; qos_flow_index++) { - ue_context_p->ue_context.modify_pdusession[i].param.qos[qos_flow_index] = - NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].qos[qos_flow_index]; - } - ue_context_p->ue_context.modify_pdusession[i].param.nb_qos = - NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].nb_qos; - - ue_context_p->ue_context.modify_pdusession[i].param.upf_addr = - ue_context_p->ue_context.pduSession[j].param.upf_addr; - ue_context_p->ue_context.modify_pdusession[i].param.gtp_teid = - ue_context_p->ue_context.pduSession[j].param.gtp_teid; - - is_treated[i] = true; - break; - } - } - - // handle Unknown pdu session ID - if (is_treated[i] == false) { - LOG_D(NR_RRC, "handle Unknown pdu session ID \n"); - ue_context_p->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_NEW; - ue_context_p->ue_context.modify_pdusession[i].param.pdusession_id = - NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].pdusession_id; - ue_context_p->ue_context.modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_context_p->ue_context.modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; - nb_of_failed_pdusessions++; - is_treated[i] = true; - } + // we need to duplicate the function fill_qos because all data types are slightly different + DevAssert(qos->list.count > 0); + DevAssert(qos->list.count <= NGAP_maxnoofQosFlows); + for (int qosIdx = 0; qosIdx < qos->list.count; qosIdx++) { + NGAP_QosFlowAddOrModifyRequestItem_t *qosFlowItem_p = qos->list.array[qosIdx]; + // Set the QOS informations + session->qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; + NGAP_QosCharacteristics_t *qosChar = &qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics; + if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) { + if (qosChar->choice.nonDynamic5QI != NULL) { + session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI; } - - ue_context_p->ue_context.nb_of_modify_pdusessions = nb_pdusessions_tomodify; - ue_context_p->ue_context.nb_of_failed_pdusessions = nb_of_failed_pdusessions; + } else if (qosChar->present == NGAP_QosCharacteristics_PR_dynamic5QI) { + // TODO } - if (ue_context_p->ue_context.nb_of_failed_pdusessions < ue_context_p->ue_context.nb_of_modify_pdusessions) { - 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"); - uint8_t nb_of_pdu_sessions_failed = 0; - MessageDef *msg_fail_p = NULL; - 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); - } + ngap_allocation_retention_priority_t *tmp = &session->qos[qosIdx].allocation_retention_priority; + NGAP_AllocationAndRetentionPriority_t *tmp2 = &qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority; + tmp->priority_level = tmp2->priorityLevelARP; + tmp->pre_emp_capability = tmp2->pre_emptionCapability; + tmp->pre_emp_vulnerability = tmp2->pre_emptionVulnerability; + } + session->nb_qos = qos->list.count; +} - NGAP_PDUSESSION_MODIFY_RESP(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; - NGAP_PDUSESSION_MODIFY_RESP(msg_fail_p).nb_of_pdusessions = 0; +static void decodePDUSessionResourceModify(pdusession_t *param, const ngap_pdu_t pdu) +{ + NGAP_PDUSessionResourceModifyRequestTransfer_t *pdusessionTransfer; + asn_dec_rval_t dec_rval = aper_decode(NULL, &asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, (void **)&pdusessionTransfer, pdu.buffer, pdu.length, 0, 0); - for (nb_of_pdu_sessions_failed = 0; nb_of_pdu_sessions_failed < ue_context_p->ue_context.nb_of_failed_pdusessions; nb_of_pdu_sessions_failed++) { - NGAP_PDUSESSION_MODIFY_RESP(msg_fail_p).pdusessions_failed[nb_of_pdu_sessions_failed].pdusession_id = - ue_context_p->ue_context.modify_pdusession[nb_of_pdu_sessions_failed].param.pdusession_id; - NGAP_PDUSESSION_MODIFY_RESP(msg_fail_p).pdusessions_failed[nb_of_pdu_sessions_failed].cause = - ue_context_p->ue_context.modify_pdusession[nb_of_pdu_sessions_failed].cause; - NGAP_PDUSESSION_MODIFY_RESP(msg_fail_p).pdusessions_failed[nb_of_pdu_sessions_failed].cause_value = - ue_context_p->ue_context.modify_pdusession[nb_of_pdu_sessions_failed].cause_value; - } + if (dec_rval.code != RC_OK) { + LOG_E(NR_RRC, "could not decode PDUSessionResourceModifyRequestTransfer\n"); + return; + } - NGAP_PDUSESSION_MODIFY_RESP(msg_fail_p).nb_of_pdusessions_failed = - ue_context_p->ue_context.nb_of_failed_pdusessions; - itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); - ue_context_p->ue_context.nb_of_modify_pdusessions = 0; - ue_context_p->ue_context.nb_of_failed_pdusessions = 0; - memset(ue_context_p->ue_context.modify_pdusession, 0, sizeof(ue_context_p->ue_context.modify_pdusession)); - return (0); + for (int j = 0; j < pdusessionTransfer->protocolIEs.list.count; j++) { + NGAP_PDUSessionResourceModifyRequestTransferIEs_t *pdusessionTransfer_ies = pdusessionTransfer->protocolIEs.list.array[j]; + switch (pdusessionTransfer_ies->id) { + /* optional PDUSessionAggregateMaximumBitRate */ + case NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate: + // TODO + LOG_E(NR_RRC, "Cant' handle NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate\n"); + break; + + /* optional UL-NGU-UP-TNLModifyList */ + case NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLModifyList: + // TODO + LOG_E(NR_RRC, "Cant' handle NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLModifyList\n"); + break; + + /* optional NetworkInstance */ + case NGAP_ProtocolIE_ID_id_NetworkInstance: + // TODO + LOG_E(NR_RRC, "Cant' handle NGAP_ProtocolIE_ID_id_NetworkInstance\n"); + break; + + /* optional QosFlowAddOrModifyRequestList */ + case NGAP_ProtocolIE_ID_id_QosFlowAddOrModifyRequestList: + fill_qos2(&pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList, param); + break; + + /* optional QosFlowToReleaseList */ + case NGAP_ProtocolIE_ID_id_QosFlowToReleaseList: + // TODO + LOG_E(NR_RRC, "Can't handle NGAP_ProtocolIE_ID_id_QosFlowToReleaseList\n"); + break; + + /* optional AdditionalUL-NGU-UP-TNLInformation */ + case NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation: + // TODO + LOG_E(NR_RRC, "Cant' handle NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation\n"); + break; + + /* optional CommonNetworkInstance */ + case NGAP_ProtocolIE_ID_id_CommonNetworkInstance: + // TODO + LOG_E(NR_RRC, "Cant' handle NGAP_ProtocolIE_ID_id_CommonNetworkInstance\n"); + break; + + default: + LOG_E(NR_RRC, "could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id); + return; } } + ASN_STRUCT_FREE(asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer,pdusessionTransfer ); +} + +//------------------------------------------------------------------------------ +int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t instance) +//------------------------------------------------------------------------------ +{ + rrc_gNB_ue_context_t *ue_context_p = NULL; + + protocol_ctxt_t ctxt; + ngap_pdusession_modify_req_t *req = &NGAP_PDUSESSION_MODIFY_REQ(msg_p); + + ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id); + if (ue_context_p == NULL) { + LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_MODIFY_REQ: unknown UE from NGAP ids (%u)\n", instance, req->gNB_ue_ngap_id); + // TO implement return setup failed + return (-1); + } + 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; + + 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) + 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++; + } 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; + } + // 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; + } + } + + 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) { + 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); + if (msg_fail_p == NULL) { + LOG_E(NR_RRC, "itti_alloc_new_message failed, msg_fail_p is NULL \n"); + return (-1); + } + ngap_pdusession_modify_resp_t *msg = &NGAP_PDUSESSION_MODIFY_RESP(msg_fail_p); + 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; + } + + 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; } @@ -1245,88 +1029,78 @@ rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP( ) //------------------------------------------------------------------------------ { - MessageDef *msg_p = NULL; - int i, j; - uint8_t qos_flow_index; + MessageDef *msg_p = NULL; uint8_t pdu_sessions_failed = 0; uint8_t pdu_sessions_done = 0; - + gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; + msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP); if (msg_p == NULL) { LOG_E(NR_RRC, "itti_alloc_new_message failed, msg_p is NULL \n"); return (-1); } - + ngap_pdusession_modify_resp_t *resp = &NGAP_PDUSESSION_MODIFY_RESP(msg_p); LOG_I(NR_RRC, "send message NGAP_PDUSESSION_MODIFY_RESP \n"); - NGAP_PDUSESSION_MODIFY_RESP(msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; - for (i = 0; i < ue_context_pP->ue_context.nb_of_modify_pdusessions; i++) { - if (xid == ue_context_pP->ue_context.modify_pdusession[i].xid) { - if (ue_context_pP->ue_context.modify_pdusession[i].status == PDU_SESSION_STATUS_DONE) { - for (j = 0; j < ue_context_pP->ue_context.nb_of_pdusessions; j++) { - if (ue_context_pP->ue_context.modify_pdusession[i].param.pdusession_id == - ue_context_pP->ue_context.pduSession[j].param.pdusession_id) { - LOG_I(NR_RRC, "update pdu session %d \n", ue_context_pP->ue_context.pduSession[j].param.pdusession_id); - // Update ue_context_pP->ue_context.pduSession - ue_context_pP->ue_context.pduSession[j].status = PDU_SESSION_STATUS_ESTABLISHED; - ue_context_pP->ue_context.pduSession[j].cause = NGAP_CAUSE_NOTHING; - for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.modify_pdusession[i].param.nb_qos; qos_flow_index++) { - ue_context_pP->ue_context.pduSession[j].param.qos[qos_flow_index] = - ue_context_pP->ue_context.modify_pdusession[i].param.qos[qos_flow_index]; - } - break; - } + 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); + 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 (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]; } - - if (j < ue_context_pP->ue_context.nb_of_pdusessions) { - NGAP_PDUSESSION_MODIFY_RESP(msg_p).pdusessions[pdu_sessions_done].pdusession_id = - ue_context_pP->ue_context.modify_pdusession[i].param.pdusession_id; - for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.modify_pdusession[i].param.nb_qos; qos_flow_index++) { - NGAP_PDUSESSION_MODIFY_RESP(msg_p).pdusessions[pdu_sessions_done].qos[qos_flow_index].qfi = - ue_context_pP->ue_context.modify_pdusession[i].param.qos[qos_flow_index].qfi; - } - NGAP_PDUSESSION_MODIFY_RESP(msg_p).pdusessions[pdu_sessions_done].nb_of_qos_flow = - ue_context_pP->ue_context.modify_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 ", - pdu_sessions_done, i, ue_context_pP->ue_context.modify_pdusession[i].status, xid, - ue_context_pP->ue_context.nb_of_modify_pdusessions, - NGAP_PDUSESSION_MODIFY_RESP(msg_p).pdusessions[pdu_sessions_done].pdusession_id); - pdu_sessions_done++; - } else { - NGAP_PDUSESSION_MODIFY_RESP(msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = - ue_context_pP->ue_context.modify_pdusession[i].param.pdusession_id; - NGAP_PDUSESSION_MODIFY_RESP(msg_p).pdusessions_failed[pdu_sessions_failed].cause = NGAP_CAUSE_RADIO_NETWORK; - NGAP_PDUSESSION_MODIFY_RESP(msg_p).pdusessions_failed[pdu_sessions_failed].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; - pdu_sessions_failed++; + 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; } - } else if ((ue_context_pP->ue_context.modify_pdusession[i].status == PDU_SESSION_STATUS_NEW) || - (ue_context_pP->ue_context.modify_pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED)) { - LOG_D (NR_RRC, "PDU SESSION is NEW or already ESTABLISHED\n"); - } else if (ue_context_pP->ue_context.modify_pdusession[i].status == PDU_SESSION_STATUS_FAILED) { - NGAP_PDUSESSION_MODIFY_RESP(msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = - ue_context_pP->ue_context.modify_pdusession[i].param.pdusession_id; - NGAP_PDUSESSION_MODIFY_RESP(msg_p).pdusessions_failed[pdu_sessions_failed].cause = - ue_context_pP->ue_context.modify_pdusession[i].cause; - NGAP_PDUSESSION_MODIFY_RESP(msg_p).pdusessions_failed[pdu_sessions_failed].cause_value = - ue_context_pP->ue_context.modify_pdusession[i].cause_value; + 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; + 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 ", + pdu_sessions_done, + i, + UE->modify_pdusession[i].status, + xid, + UE->nb_of_modify_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; + 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 { - LOG_D(NR_RRC,"xid does not correspond (context pdu session index %d, status %d, xid %d/%d) \n ", - i, ue_context_pP->ue_context.modify_pdusession[i].status, xid, ue_context_pP->ue_context.modify_pdusession[i].xid); + } else if ((UE->modify_pdusession[i].status == PDU_SESSION_STATUS_NEW) || (UE->modify_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; + 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); } - NGAP_PDUSESSION_MODIFY_RESP(msg_p).nb_of_pdusessions = pdu_sessions_done; - NGAP_PDUSESSION_MODIFY_RESP(msg_p).nb_of_pdusessions_failed = pdu_sessions_failed; + 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, index %d\n", - ue_context_pP->ue_context.nb_of_modify_pdusessions, - ue_context_pP->ue_context.nb_of_pdusessions, - i); + 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); itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); } else { itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); @@ -1336,40 +1110,32 @@ rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP( } //------------------------------------------------------------------------------ -void -rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ( - const module_id_t gnb_mod_idP, - const rrc_gNB_ue_context_t *const ue_context_pP, - const ngap_Cause_t causeP, - const long cause_valueP) +void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, const rrc_gNB_ue_context_t *const ue_context_pP, const ngap_Cause_t causeP, const long cause_valueP) //------------------------------------------------------------------------------ { if (ue_context_pP == NULL) { LOG_E(RRC, "[gNB] In NGAP_UE_CONTEXT_RELEASE_REQ: invalid UE\n"); } else { - MessageDef *msg_context_release_req_p = NULL; - msg_context_release_req_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_REQ); - NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; - NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause = causeP; - NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause_value = cause_valueP; - NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).nb_of_pdusessions = ue_context_pP->ue_context.nb_of_pdusessions; - for (int pdusession = 0; pdusession < ue_context_pP->ue_context.nb_of_pdusessions; pdusession++) { - NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id; + const gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_REQ); + ngap_ue_release_req_t *req = &NGAP_UE_CONTEXT_RELEASE_REQ(msg); + memset(req, 0, sizeof(*req)); + req->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + req->cause = causeP; + req->cause_value = cause_valueP; + for (int i = 0; i < UE->nb_of_pdusessions; i++) { + req->pdusessions[i].pdusession_id = UE->pduSession[i].param.pdusession_id; + req->nb_of_pdusessions++; } - itti_send_msg_to_task(TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_mod_idP), msg_context_release_req_p); + itti_send_msg_to_task(TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_mod_idP), msg); } } /*------------------------------------------------------------------------------*/ -int -rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ ( - MessageDef *msg_p, - const char *msg_name, - instance_t instance) +int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t instance) { uint32_t gNB_ue_ngap_id; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_REQ(msg_p).gNB_ue_ngap_id; - ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, UE_INITIAL_ID_INVALID, gNB_ue_ngap_id); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], gNB_ue_ngap_id); if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to ngAP and discard it! */ @@ -1385,12 +1151,10 @@ rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ ( } else { /* TODO release context. */ /* Send the response */ - { - MessageDef *msg_resp_p; - msg_resp_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP); - NGAP_UE_CONTEXT_RELEASE_RESP(msg_resp_p).gNB_ue_ngap_id = gNB_ue_ngap_id; - itti_send_msg_to_task(TASK_NGAP, instance, msg_resp_p); - } + MessageDef *msg_resp_p; + msg_resp_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP); + NGAP_UE_CONTEXT_RELEASE_RESP(msg_resp_p).gNB_ue_ngap_id = gNB_ue_ngap_id; + itti_send_msg_to_task(TASK_NGAP, instance, msg_resp_p); return (0); } } @@ -1400,18 +1164,13 @@ rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ ( * Process the NG command NGAP_UE_CONTEXT_RELEASE_COMMAND, sent by AMF. * The gNB should remove all pdu session, NG context, and other context of the UE. */ -int -rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND( - MessageDef *msg_p, - const char *msg_name, - instance_t instance) { +int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance) +{ //----------------------------------------------------------------------------- uint32_t gNB_ue_ngap_id = 0; protocol_ctxt_t ctxt; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - struct rrc_ue_ngap_ids_s *rrc_ue_ngap_ids = NULL; gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id; - ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, UE_INITIAL_ID_INVALID, gNB_ue_ngap_id); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], gNB_ue_ngap_id); if (ue_context_p == NULL) { /* Can not associate this message to an UE index */ @@ -1422,21 +1181,16 @@ rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND( msg_complete_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE); NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).gNB_ue_ngap_id = gNB_ue_ngap_id; itti_send_msg_to_task(TASK_NGAP, instance, msg_complete_p); - rrc_ue_ngap_ids = rrc_gNB_NGAP_get_ue_ids(RC.nrrrc[instance], UE_INITIAL_ID_INVALID, gNB_ue_ngap_id); - - if (rrc_ue_ngap_ids != NULL) { - rrc_gNB_NGAP_remove_ue_ids(RC.nrrrc[instance], rrc_ue_ngap_ids); - } - return -1; - } else { - ue_context_p->ue_context.ue_release_timer_ng = 0; - ue_context_p->ue_context.ue_release_timer_thres_rrc = 1000; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); - ctxt.eNB_index = 0; - rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p); - return 0; } + + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + UE->ue_release_timer_ng = 0; + UE->ue_release_timer_thres_rrc = 1000; + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + ctxt.eNB_index = 0; + rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p); + return 0; } void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE( @@ -1447,52 +1201,6 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE( itti_send_msg_to_task(TASK_NGAP, instance, msg); } -//------------------------------------------------------------------------------ -/* -* Remove UE ids (ue_initial_id and ng_id) from hashtables. -*/ -void -rrc_gNB_NGAP_remove_ue_ids( - gNB_RRC_INST *const rrc_instance_pP, - struct rrc_ue_ngap_ids_s *const ue_ids_pP -) -//------------------------------------------------------------------------------ -{ - hashtable_rc_t h_rc; - - if (rrc_instance_pP == NULL) { - LOG_E(NR_RRC, "Bad NR RRC instance\n"); - return; - } - - if (ue_ids_pP == NULL) { - LOG_E(NR_RRC, "Trying to free a NULL NGAP UE IDs\n"); - return; - } - - const uint16_t ue_initial_id = ue_ids_pP->ue_initial_id; - const uint32_t gNB_ue_ngap_id = ue_ids_pP->gNB_ue_ngap_id; - - if (gNB_ue_ngap_id > 0) { - h_rc = hashtable_remove(rrc_instance_pP->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_id); - - if (h_rc != HASH_TABLE_OK) { - LOG_W(NR_RRC, "NGAP Did not find entry in hashtable ngap_id2_ngap_ids for gNB_ue_ngap_id %u\n", gNB_ue_ngap_id); - } else { - LOG_W(NR_RRC, "NGAP removed entry in hashtable ngap_id2_ngap_ids for gNB_ue_ngap_id %u\n", gNB_ue_ngap_id); - } - } - - if (ue_initial_id != UE_INITIAL_ID_INVALID) { - h_rc = hashtable_remove(rrc_instance_pP->initial_id2_ngap_ids, (hash_key_t)ue_initial_id); - - if (h_rc != HASH_TABLE_OK) { - LOG_W(NR_RRC, "NGAP Did not find entry in hashtable initial_id2_ngap_ids for ue_initial_id %u\n", ue_initial_id); - } else { - LOG_W(NR_RRC, "NGAP removed entry in hashtable initial_id2_ngap_ids for ue_initial_id %u\n", ue_initial_id); - } - } -} void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND( const protocol_ctxt_t *const ctxt_pP, @@ -1503,40 +1211,38 @@ rrc_gNB_send_NGAP_UE_CAPABILITIES_IND( { 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 */ - unsigned char buf[4096]; - unsigned char *buf2; - NR_UERadioAccessCapabilityInformation_t rac; - - if (ueCapabilityRATContainerList->list.count == 0) { - LOG_W(RRC, "[gNB %d][UE %x] bad UE capabilities\n", ctxt_pP->module_id, ue_context_pP->ue_context.rnti); - } - - asn_enc_rval_t ret = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, NULL, ueCapabilityRATContainerList, buf, 4096); - - if (ret.encoded == -1) abort(); - - memset(&rac, 0, sizeof(NR_UERadioAccessCapabilityInformation_t)); - rac.criticalExtensions.present = NR_UERadioAccessCapabilityInformation__criticalExtensions_PR_c1; - rac.criticalExtensions.choice.c1 = calloc(1,sizeof(*rac.criticalExtensions.choice.c1)); - rac.criticalExtensions.choice.c1->present = NR_UERadioAccessCapabilityInformation__criticalExtensions__c1_PR_ueRadioAccessCapabilityInformation; - rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation = calloc(1,sizeof(NR_UERadioAccessCapabilityInformation_IEs_t)); - rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation->ue_RadioAccessCapabilityInfo.buf = buf; - rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation->ue_RadioAccessCapabilityInfo.size = (ret.encoded+7)/8; - rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation->nonCriticalExtension = NULL; - /* 8192 is arbitrary, should be big enough */ - buf2 = malloc16(8192); - - if (buf2 == NULL) abort(); - - ret = uper_encode_to_buffer(&asn_DEF_NR_UERadioAccessCapabilityInformation, NULL, &rac, buf2, 8192); - - if (ret.encoded == -1) abort(); + 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); + } + + int ret = uper_encode_to_new_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, NULL, ueCapabilityRATContainerList, &buf); + AssertFatal(ret > 0, "fail to encode ue capabilities\n"); + + rac.criticalExtensions.present = NR_UERadioAccessCapabilityInformation__criticalExtensions_PR_c1; + asn1cCalloc(rac.criticalExtensions.choice.c1, c1); + c1->present = NR_UERadioAccessCapabilityInformation__criticalExtensions__c1_PR_ueRadioAccessCapabilityInformation; + asn1cCalloc(c1->choice.ueRadioAccessCapabilityInformation, info); + info->ue_RadioAccessCapabilityInfo.buf = buf; + info->ue_RadioAccessCapabilityInfo.size = ret; + info->nonCriticalExtension = NULL; + /* 8192 is arbitrary, should be big enough */ + void *buf2 = NULL; + int encoded = uper_encode_to_new_buffer(&asn_DEF_NR_UERadioAccessCapabilityInformation, NULL, &rac, &buf2); + + AssertFatal(encoded > 0, "fail to encode ue capabilities\n"); + ; + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UERadioAccessCapabilityInformation, &rac); MessageDef *msg_p; msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UE_CAPABILITIES_IND); - NGAP_UE_CAPABILITIES_IND (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; - NGAP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.length = (ret.encoded+7)/8; - NGAP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.buffer = buf2; + ngap_ue_cap_info_ind_t *ind = &NGAP_UE_CAPABILITIES_IND(msg_p); + memset(ind, 0, sizeof(*ind)); + ind->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + ind->ue_radio_cap.length = encoded; + ind->ue_radio_cap.buffer = buf2; itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); LOG_I(NR_RRC,"Send message to ngap: NGAP_UE_CAPABILITIES_IND\n"); } @@ -1552,154 +1258,118 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( { int pdu_sessions_released = 0; MessageDef *msg_p; + gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_RELEASE_RESPONSE); - NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + ngap_pdusession_release_resp_t *resp = &NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p); + memset(resp, 0, sizeof(*resp)); + resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; for (int i = 0; i < NB_RB_MAX; i++) { - if (xid == ue_context_pP->ue_context.pduSession[i].xid) { - NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusession_release[pdu_sessions_released].pdusession_id = - ue_context_pP->ue_context.pduSession[i].param.pdusession_id; + 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_context_pP->ue_context.pduSession[i], 0, sizeof(pdu_session_param_t)); + memset(&UE->pduSession[i], 0, sizeof(*UE->pduSession)); } } - NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).nb_of_pdusessions_released = pdu_sessions_released; - NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).nb_of_pdusessions_failed = ue_context_pP->ue_context.nb_release_of_pdusessions; - memcpy(&(NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusessions_failed[0]), &ue_context_pP->ue_context.pdusessions_release_failed[0], - sizeof(pdusession_failed_t)*ue_context_pP->ue_context.nb_release_of_pdusessions); - ue_context_pP->ue_context.nb_of_pdusessions -= pdu_sessions_released; - LOG_I(NR_RRC, - "NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_ID %u release_pdu_sessions %d setup_pdu_sessions %d \n", - NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p).gNB_ue_ngap_id, - pdu_sessions_released, - ue_context_pP->ue_context.nb_of_pdusessions); + 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; + 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_context_pP->ue_context.pduSession[i].xid = -1; + UE->pduSession[i].xid = -1; } //clear release pdusessions - ue_context_pP->ue_context.nb_release_of_pdusessions = 0; - memset(&ue_context_pP->ue_context.pdusessions_release_failed[0], 0, sizeof(pdusession_failed_t)*NGAP_MAX_PDUSESSION); + UE->nb_release_of_pdusessions = 0; + memset(UE->pdusessions_release_failed, 0, sizeof(UE->pdusessions_release_failed)); } //------------------------------------------------------------------------------ -int -rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND( - MessageDef *msg_p, - const char *msg_name, - instance_t instance -) +int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance) //------------------------------------------------------------------------------ { - uint32_t gNB_ue_ngap_id; - rrc_gNB_ue_context_t *ue_context_p = NULL; - protocol_ctxt_t ctxt; - pdusession_release_t pdusession_release_params[NGAP_MAX_PDUSESSION]; - uint8_t nb_pdusessions_torelease; + uint32_t gNB_ue_ngap_id; + protocol_ctxt_t ctxt; uint8_t xid; - int i, pdusession; - uint8_t b_existed,is_existed; uint8_t pdusession_release_drb = 0; - - memcpy(&pdusession_release_params[0], &(NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).pdusession_release_params[0]), - sizeof(pdusession_release_t)*NGAP_MAX_PDUSESSION); - gNB_ue_ngap_id = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id; - nb_pdusessions_torelease = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).nb_pdusessions_torelease; - if (nb_pdusessions_torelease > NGAP_MAX_PDUSESSION) { + 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) { + LOG_E(NR_RRC, "incorrect number of pdu session do release %d\n", cmd->nb_pdusessions_torelease); return -1; } - ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, UE_INITIAL_ID_INVALID, gNB_ue_ngap_id); - LOG_I(NR_RRC, "[gNB %ld] Received %s: gNB_ue_ngap_id %u \n", instance, msg_name, gNB_ue_ngap_id); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], gNB_ue_ngap_id); - if (ue_context_p != NULL) { - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.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", - NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id&0x000000FFFFFFFFFF, gNB_ue_ngap_id, nb_pdusessions_torelease); + if (!ue_context_p) { + LOG_E(NR_RRC, "[gNB %ld] not found ue context gNB_ue_ngap_id %u \n", instance, gNB_ue_ngap_id); + return -1; + } - for (pdusession = 0; pdusession < nb_pdusessions_torelease; pdusession++) { - b_existed = 0; - is_existed = 0; + 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); - for (i = pdusession-1; i >= 0; i--) { - if (pdusession_release_params[pdusession].pdusession_id == pdusession_release_params[i].pdusession_id) { - is_existed = 1; - break; - } - } - - if(is_existed == 1) { - // pdusession_id is existed - continue; - } - - for (i = 0; i < NR_NB_RB_MAX; i++) { - if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pduSession[i].param.pdusession_id) { - b_existed = 1; - break; - } - } - - if(b_existed == 0) { - // no pdusession_id - LOG_I(NR_RRC, "no pdusession_id \n"); - ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].pdusession_id = pdusession_release_params[pdusession].pdusession_id; - ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 30; - ue_context_p->ue_context.nb_release_of_pdusessions++; - } else { - if(ue_context_p->ue_context.pduSession[i].status == PDU_SESSION_STATUS_FAILED) { - ue_context_p->ue_context.pduSession[i].xid = xid; - continue; - } else if(ue_context_p->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED) { - LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pduSession[i].param.pdusession_id); - ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_TORELEASE; - ue_context_p->ue_context.pduSession[i].xid = xid; - pdusession_release_drb++; - } else { - // pdusession_id status NG - ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].pdusession_id = pdusession_release_params[pdusession].pdusession_id; - ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK; - ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 0; - ue_context_p->ue_context.nb_release_of_pdusessions++; - } - } + 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++; + continue; } - - if(pdusession_release_drb > 0) { - //TODO RRCReconfiguration To UE - LOG_I(NR_RRC, "Send RRCReconfiguration To UE \n"); - rrc_gNB_generate_dedicatedRRCReconfiguration_release(&ctxt, ue_context_p, xid, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.length, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.buffer); - } else { - //gtp tunnel delete - LOG_I(NR_RRC, "gtp tunnel delete \n"); - gtpv1u_gnb_delete_tunnel_req_t req={0}; - req.ue_id = ue_context_p->ue_context.rnti; - - for(i = 0; i < NB_RB_MAX; i++) { - if(xid == ue_context_p->ue_context.pduSession[i].xid) { - req.pdusession_id[req.num_pdusession++] = ue_context_p->ue_context.gnb_gtp_psi[i]; - ue_context_p->ue_context.gnb_gtp_teid[i] = 0; - memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i])); - ue_context_p->ue_context.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); - LOG_I(NR_RRC, "Send PDU Session Release Response \n"); + if (pduSession->status == PDU_SESSION_STATUS_FAILED) { + pduSession->xid = xid; + continue; } + if (pduSession->status == PDU_SESSION_STATUS_ESTABLISHED) { + 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) { + // 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 { - LOG_E(NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %u Error ue_context_p NULL \n", - NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id&0x000000FFFFFFFFFF, NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id); - return -1; - } + // gtp tunnel delete + LOG_I(NR_RRC, "gtp tunnel delete \n"); + 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); + LOG_I(NR_RRC, "Send PDU Session Release Response \n"); + } return 0; } @@ -1713,8 +1383,8 @@ void nr_rrc_rx_tx(void) { } /*------------------------------------------------------------------------------*/ -int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance) { - +int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance) +{ for (uint16_t tai_size = 0; tai_size < NGAP_PAGING_IND(msg_p).tai_size; tai_size++) { LOG_I(NR_RRC,"[gNB %ld] In NGAP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc, NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, NGAP_PAGING_IND(msg_p).tac[tai_size]); @@ -1745,4 +1415,3 @@ int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance return 0; } - diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h index 6c8a861f03..a0c42dcaaf 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.h +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -40,18 +40,6 @@ #include "NR_UL-DCCH-Message.h" #include "NGAP_CauseRadioNetwork.h" -typedef struct rrc_ue_ngap_ids_s { - /* Tree related data */ - RB_ENTRY(rrc_ue_ngap_ids_s) entries; - - // keys - uint16_t ue_initial_id; - uint32_t gNB_ue_ngap_id; - - // value - rnti_t ue_rnti; -} rrc_ue_ngap_ids_t; - void rrc_gNB_send_NGAP_NAS_FIRST_REQ( const protocol_ctxt_t *const ctxt_pP, @@ -59,12 +47,7 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ( NR_RRCSetupComplete_IEs_t *rrcSetupComplete ); -int -rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( - MessageDef *msg_p, - const char *msg_name, - instance_t instance -); +int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t instance); void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP( @@ -72,20 +55,7 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP( rrc_gNB_ue_context_t *const ue_context_pP ); -int -rrc_gNB_process_security( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - ngap_security_capabilities_t *security_capabilities_pP -); - -int -rrc_gNB_process_NGAP_DOWNLINK_NAS( - MessageDef *msg_p, - const char *msg_name, - instance_t instance, - mui_t *rrc_gNB_mui -); +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( @@ -101,19 +71,9 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( uint8_t xid ); -void -rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( - MessageDef *msg_p, - const char *msg_name, - instance_t instance -); +void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance); -int -rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ( - MessageDef *msg_p, - const char *msg_name, - instance_t instance -); +int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t instance); int rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP( @@ -128,38 +88,13 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( rrc_gNB_ue_context_t *ue_context_pP ); +void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, const rrc_gNB_ue_context_t *const ue_context_pP, const ngap_Cause_t causeP, const long cause_valueP); -void -rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ( - const module_id_t gnb_mod_idP, - const rrc_gNB_ue_context_t *const ue_context_pP, - const ngap_Cause_t causeP, - const long cause_valueP -); +int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t instance); -int -rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ ( - MessageDef *msg_p, - const char *msg_name, - instance_t instance -); +int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance); -int -rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND( - MessageDef *msg_p, - const char *msg_name, - instance_t instance -); - -void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE( - instance_t instance, - uint32_t gNB_ue_ngap_id); - -void -rrc_gNB_NGAP_remove_ue_ids( - gNB_RRC_INST *const rrc_instance_pP, - struct rrc_ue_ngap_ids_s *const ue_ids_pP -); +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( @@ -168,12 +103,7 @@ rrc_gNB_send_NGAP_UE_CAPABILITIES_IND( NR_UL_DCCH_Message_t *const ul_dcch_msg ); -int -rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND( - MessageDef *msg_p, - const char *msg_name, - instance_t instance -); +int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance); void rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( @@ -189,17 +119,6 @@ nr_rrc_pdcp_config_security( const uint8_t send_security_mode_command ); -struct rrc_gNB_ue_context_s * -rrc_gNB_get_ue_context_from_ngap_ids( - const instance_t instanceP, - const uint16_t ue_initial_idP, - const uint32_t gNB_ue_ngap_idP -); - -int -rrc_gNB_process_PAGING_IND( - MessageDef *msg_p, - const char *msg_name, - instance_t instance); +int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance); #endif diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 87b4de23b2..137ed695f5 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -38,15 +38,14 @@ //------------------------------------------------------------------------------ -int rrc_gNB_compare_ue_rnti_id( - struct rrc_gNB_ue_context_s *c1_pP, struct rrc_gNB_ue_context_s *c2_pP) +int rrc_gNB_compare_ue_rnti_id(rrc_gNB_ue_context_t *c1_pP, rrc_gNB_ue_context_t *c2_pP) //------------------------------------------------------------------------------ { - if (c1_pP->ue_id_rnti > c2_pP->ue_id_rnti) { + if (c1_pP->ue_context.gNB_ue_ngap_id > c2_pP->ue_context.gNB_ue_ngap_id) { return 1; } - if (c1_pP->ue_id_rnti < c2_pP->ue_id_rnti) { + if (c1_pP->ue_context.gNB_ue_ngap_id < c2_pP->ue_context.gNB_ue_ngap_id) { return -1; } @@ -57,25 +56,17 @@ int rrc_gNB_compare_ue_rnti_id( RB_GENERATE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue_rnti_id); - - //------------------------------------------------------------------------------ -struct rrc_gNB_ue_context_s * -rrc_gNB_allocate_new_UE_context( - gNB_RRC_INST *rrc_instance_pP -) +rrc_gNB_ue_context_t *rrc_gNB_allocate_new_ue_context(gNB_RRC_INST *rrc_instance_pP) //------------------------------------------------------------------------------ { - struct rrc_gNB_ue_context_s *new_p; - new_p = (struct rrc_gNB_ue_context_s * )malloc(sizeof(struct rrc_gNB_ue_context_s)); + rrc_gNB_ue_context_t *new_p = calloc(1, sizeof(*new_p)); if (new_p == NULL) { - LOG_E(RRC, "Cannot allocate new ue context\n"); + LOG_E(NR_RRC, "Cannot allocate new ue context\n"); return NULL; } - - memset(new_p, 0, sizeof(struct rrc_gNB_ue_context_s)); - new_p->local_uid = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator); + 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; @@ -83,94 +74,66 @@ rrc_gNB_allocate_new_UE_context( new_p->ue_context.modify_e_rab[i].xid = -1; } - LOG_D(NR_RRC,"Returning new UE context at %p\n",new_p); + 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); } //------------------------------------------------------------------------------ -struct rrc_gNB_ue_context_s * -rrc_gNB_get_ue_context( - gNB_RRC_INST *rrc_instance_pP, - rnti_t rntiP) +rrc_gNB_ue_context_t *rrc_gNB_get_ue_context(gNB_RRC_INST *rrc_instance_pP, ue_id_t ue) //------------------------------------------------------------------------------ { rrc_gNB_ue_context_t temp; - memset(&temp, 0, sizeof(struct rrc_gNB_ue_context_s)); /* gNB ue rrc id = 24 bits wide */ - temp.ue_id_rnti = rntiP; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - ue_context_p = RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp); - - if ( ue_context_p != NULL) { - return ue_context_p; - } else { - RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) { - if (ue_context_p->ue_context.rnti == rntiP) { - return ue_context_p; - } - } - return NULL; - } + temp.ue_context.gNB_ue_ngap_id = ue; + return RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp); } -void rrc_gNB_free_mem_UE_context( - const protocol_ctxt_t *const ctxt_pP, - struct rrc_gNB_ue_context_s *const ue_context_pP -) +rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST *rrc_instance_pP, rnti_t rntiP) +{ + rrc_gNB_ue_context_t *ue_context_p; + RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) + { + if (ue_context_p->ue_context.rnti == rntiP) + return ue_context_p; + } + LOG_W(NR_RRC, "search by rnti not found %04x\n", rntiP); + return NULL; +} + +void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t *const ue_context_pP) //----------------------------------------------------------------------------- { - - LOG_T(RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_context_pP); - - //ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]); - //ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]); - - // empty the internal fields of the UE context here + free(ue_context_pP); + LOG_T(NR_RRC, " Clearing UE context 0x%p (free internal structs)\n", ue_context_pP); } //------------------------------------------------------------------------------ -void rrc_gNB_remove_ue_context( - const protocol_ctxt_t *const ctxt_pP, - gNB_RRC_INST *rrc_instance_pP, - struct rrc_gNB_ue_context_s *ue_context_pP) +void rrc_gNB_remove_ue_context(gNB_RRC_INST *rrc_instance_pP, rrc_gNB_ue_context_t *ue_context_pP) //------------------------------------------------------------------------------ { if (rrc_instance_pP == NULL) { - LOG_E(RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Bad RRC instance\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_E(NR_RRC, " Bad RRC instance\n"); return; } if (ue_context_pP == NULL) { - LOG_E(RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Trying to free a NULL UE context\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_E(NR_RRC, "Trying to free a NULL UE context\n"); return; } RB_REMOVE(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); - rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_pP); - uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->local_uid); - free(ue_context_pP); - rrc_instance_pP->Nb_ue --; - LOG_I(RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" Removed UE context\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.gNB_ue_ngap_id); + rrc_gNB_free_mem_ue_context(ue_context_pP); + LOG_I(NR_RRC, "Removed UE context\n"); } //----------------------------------------------------------------------------- // return the ue context if there is already an UE with ue_identityP, NULL otherwise -struct rrc_gNB_ue_context_s * -rrc_gNB_ue_context_random_exist( - gNB_RRC_INST *rrc_instance_pP, - const uint64_t ue_identityP -) +rrc_gNB_ue_context_t *rrc_gNB_ue_context_random_exist(gNB_RRC_INST *rrc_instance_pP, const uint64_t ue_identityP) //----------------------------------------------------------------------------- { - struct rrc_gNB_ue_context_s *ue_context_p = NULL; + rrc_gNB_ue_context_t *ue_context_p = NULL; RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head) { if (ue_context_p->ue_context.random_ue_identity == ue_identityP) return ue_context_p; @@ -180,63 +143,48 @@ rrc_gNB_ue_context_random_exist( //----------------------------------------------------------------------------- // return the ue context if there is already an UE with the same S-TMSI, NULL otherwise -struct rrc_gNB_ue_context_s * -rrc_gNB_ue_context_5g_s_tmsi_exist( - gNB_RRC_INST *rrc_instance_pP, - const uint64_t s_TMSI -) +rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_instance_pP, const uint64_t s_TMSI) //----------------------------------------------------------------------------- { - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head) { - LOG_I(NR_RRC,"Checking for UE 5G S-TMSI %ld: RNTI %04x\n", - s_TMSI, ue_context_p->ue_context.rnti); - - if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 == s_TMSI) { - return ue_context_p; - } - } + rrc_gNB_ue_context_t *ue_context_p = NULL; + RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head) + { + LOG_I(NR_RRC, "Checking for UE 5G S-TMSI %ld: RNTI %04x\n", s_TMSI, ue_context_p->ue_context.rnti); + if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 == s_TMSI) + return ue_context_p; + } return NULL; } +void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, uint32_t gNB_ue_ngap_id) +{ + // rnti will need to be a fast access key, with indexing, today it is sequential search + // This function will update the index when it will be made + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, gNB_ue_ngap_id); + if (ue_context_p) + ue_context_p->ue_context.rnti = rnti; + else + LOG_E(NR_RRC, "update rnti on a wrong UE id\n"); +} //----------------------------------------------------------------------------- -// return a new ue context structure if ue_identityP, ctxt_pP->rnti not found in collection -struct rrc_gNB_ue_context_s * -rrc_gNB_get_next_free_ue_context( - const protocol_ctxt_t *const ctxt_pP, - gNB_RRC_INST *rrc_instance_pP, - const uint64_t ue_identityP -) +// return a new ue context structure if ue_identityP, rnti not found in collection +rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, const uint64_t ue_identityP) //----------------------------------------------------------------------------- { - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, ctxt_pP->rntiMaybeUEid); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc_instance_pP, rnti); - if (ue_context_p == NULL) { - ue_context_p = rrc_gNB_allocate_new_UE_context(rrc_instance_pP); - - if (ue_context_p == NULL) { - LOG_E(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" Cannot create new UE context, no memory\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - return NULL; - } - - ue_context_p->ue_id_rnti = ctxt_pP->rntiMaybeUEid; // here ue_id_rnti is just a key, may be something else - ue_context_p->ue_context.rnti = ctxt_pP->rntiMaybeUEid; // yes duplicate, 1 may be removed - ue_context_p->ue_context.random_ue_identity = ue_identityP; - RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" Created new UE context uid %u\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_context_p->local_uid); + if (ue_context_p) { + LOG_E(NR_RRC, "Cannot create new UE context, already exist rnti: %04x\n", rnti); return ue_context_p; - } else { - LOG_E(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" Cannot create new UE context, already exist\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - return NULL; } - return(ue_context_p); + ue_context_p = rrc_gNB_allocate_new_ue_context(rrc_instance_pP); + if (ue_context_p == NULL) + return NULL; + + ue_context_p->ue_context.rnti = rnti; + ue_context_p->ue_context.random_ue_identity = ue_identityP; + RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p); + LOG_W(NR_RRC, " Created new UE context rnti: %04x, random ue id %lx, RRC ue id %u\n", rnti, ue_identityP, ue_context_p->ue_context.gNB_ue_ngap_id); + return ue_context_p; } diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index 4009f2617f..9c1ec2c164 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -34,52 +34,23 @@ #include "COMMON/platform_types.h" #include "nr_rrc_defs.h" -int rrc_gNB_compare_ue_rnti_id( - struct rrc_gNB_ue_context_s* c1_pP, - struct rrc_gNB_ue_context_s* c2_pP -); +int rrc_gNB_compare_ue_rnti_id(rrc_gNB_ue_context_t* c1_pP, rrc_gNB_ue_context_t* c2_pP); RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue_rnti_id); -struct rrc_gNB_ue_context_s* -rrc_gNB_allocate_new_UE_context( - gNB_RRC_INST* rrc_instance_pP -); +rrc_gNB_ue_context_t* rrc_gNB_allocate_new_ue_context(gNB_RRC_INST* rrc_instance_pP); -struct rrc_gNB_ue_context_s* -rrc_gNB_get_ue_context( - gNB_RRC_INST* rrc_instance_pP, - rnti_t rntiP -); +rrc_gNB_ue_context_t* rrc_gNB_get_ue_context(gNB_RRC_INST* rrc_instance_pP, ue_id_t ue); +rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST* rrc_instance_pP, rnti_t rntiP); -void rrc_gNB_free_mem_UE_context( - const protocol_ctxt_t *const ctxt_pP, - struct rrc_gNB_ue_context_s *const ue_context_pP -); +void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t* const ue_context_pP); -void rrc_gNB_remove_ue_context( - const protocol_ctxt_t* const ctxt_pP, - gNB_RRC_INST* rrc_instance_pP, - struct rrc_gNB_ue_context_s* ue_context_pP -); +void rrc_gNB_remove_ue_context(gNB_RRC_INST* rrc_instance_pP, rrc_gNB_ue_context_t* ue_context_pP); -struct rrc_gNB_ue_context_s * -rrc_gNB_ue_context_random_exist( - gNB_RRC_INST *rrc_instance_pP, - const uint64_t ue_identityP -); +rrc_gNB_ue_context_t* rrc_gNB_ue_context_random_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP); -struct rrc_gNB_ue_context_s * -rrc_gNB_ue_context_5g_s_tmsi_exist( - gNB_RRC_INST *rrc_instance_pP, - const uint64_t s_TMSI -); - -struct rrc_gNB_ue_context_s * -rrc_gNB_get_next_free_ue_context( - const protocol_ctxt_t *const ctxt_pP, - gNB_RRC_INST *rrc_instance_pP, - const uint64_t ue_identityP -); +rrc_gNB_ue_context_t* rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t s_TMSI); +void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, uint32_t gNB_ue_ngap_id); +rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP); #endif diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 039fffa555..89c5b44858 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -45,9 +45,8 @@ #include #include "pdcp.h" -void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t *cg_config_info) { - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - +void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t *cg_config_info) +{ OCTET_STRING_t *ueCapabilityRAT_Container_nr=NULL; OCTET_STRING_t *ueCapabilityRAT_Container_MRDC=NULL; asn_dec_rval_t dec_rval; @@ -62,36 +61,27 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL } // decode and store capabilities - ue_context_p = rrc_gNB_allocate_new_UE_context(rrc); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (ueCapabilityRAT_Container_nr != NULL) { - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_NR_Capability, - (void **)&ue_context_p->ue_context.UE_Capability_nr, - ueCapabilityRAT_Container_nr->buf, - ueCapabilityRAT_Container_nr->size, 0, 0); + dec_rval = uper_decode(NULL, &asn_DEF_NR_UE_NR_Capability, (void **)&UE->UE_Capability_nr, ueCapabilityRAT_Container_nr->buf, ueCapabilityRAT_Container_nr->size, 0, 0); if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E(RRC, "Failed to decode UE NR capabilities (%zu bytes) container size %lu\n", dec_rval.consumed,ueCapabilityRAT_Container_nr->size); - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, - ue_context_p->ue_context.UE_Capability_nr); - ue_context_p->ue_context.UE_Capability_nr = 0; + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); + UE->UE_Capability_nr = 0; AssertFatal(1==0,"exiting\n"); } } if (ueCapabilityRAT_Container_MRDC != NULL) { - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_MRDC_Capability, - (void **)&ue_context_p->ue_context.UE_Capability_MRDC, - ueCapabilityRAT_Container_MRDC->buf, - ueCapabilityRAT_Container_MRDC->size, 0, 0); + dec_rval = uper_decode(NULL, &asn_DEF_NR_UE_MRDC_Capability, (void **)&UE->UE_Capability_MRDC, ueCapabilityRAT_Container_MRDC->buf, ueCapabilityRAT_Container_MRDC->size, 0, 0); if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E(RRC, "Failed to decode UE MRDC capabilities (%zu bytes)\n", dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, - ue_context_p->ue_context.UE_Capability_MRDC); - ue_context_p->ue_context.UE_Capability_MRDC = 0; + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); + UE->UE_Capability_MRDC = 0; AssertFatal(1==0,"exiting\n"); } } @@ -99,16 +89,16 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL // dump ue_capabilities if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_nr != NULL ) { - xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr); + xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr); } if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_MRDC != NULL ) { - xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC); + xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC); } LOG_A(NR_RRC, "Successfully decoded UE NR capabilities (NR and MRDC)\n"); - ue_context_p->ue_context.spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig)); - ue_context_p->ue_context.spCellConfig->spCellConfigDedicated = rrc->carrier.servingcellconfig; + UE->spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig)); + UE->spCellConfig->spCellConfigDedicated = rrc->carrier.servingcellconfig; LOG_I(NR_RRC,"Adding new NSA user (%p)\n",ue_context_p); rrc_add_nsa_user(rrc,ue_context_p, m); } @@ -117,7 +107,8 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue_rnti_id); -void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m) { +void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m) +{ // generate nr-Config-r15 containers for LTE RRC : inside message for X2 EN-DC (CG-Config Message from 38.331) rrc_gNB_carrier_data_t *carrier=&rrc->carrier; const gNB_RrcConfigurationReq *configuration = &rrc->configuration; @@ -129,6 +120,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ unsigned char *kUPenc = NULL; unsigned char *kUPint = NULL; int i; + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; // In case of phy-test and do-ra mode, read UE capabilities directly from file if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) { @@ -150,25 +142,20 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ } else LOG_E(NR_RRC,"Could not open UE Capabilities input file. Not handling OAI UE Capabilities.\n"); - ue_context_p->ue_context.UE_Capability_nr = UE_Capability_nr; + UE->UE_Capability_nr = UE_Capability_nr; } // NR RRCReconfiguration - AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n"); - ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t)); - ue_context_p->ue_context.secondaryCellGroup = calloc(1,sizeof(NR_CellGroupConfig_t)); - memset((void *)ue_context_p->ue_context.reconfig,0,sizeof(NR_RRCReconfiguration_t)); - ue_context_p->ue_context.reconfig->rrc_TransactionIdentifier=0; - ue_context_p->ue_context.reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration; + UE->reconfig = calloc(1, sizeof(NR_RRCReconfiguration_t)); + UE->secondaryCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t)); + memset((void *)UE->reconfig, 0, sizeof(NR_RRCReconfiguration_t)); + UE->reconfig->rrc_TransactionIdentifier = 0; + UE->reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration; NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t)); - ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies; - ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t)); + UE->reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies; + UE->rb_config = calloc(1, sizeof(NR_RRCReconfiguration_t)); if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){ - fill_default_rbconfig(ue_context_p->ue_context.rb_config, - 10 /* EPS bearer ID */, - 1 /* drb ID */, - NR_CipheringAlgorithm_nea0, - NR_SecurityConfig__keyToUse_master); + fill_default_rbconfig(UE->rb_config, 10 /* EPS bearer ID */, 1 /* drb ID */, NR_CipheringAlgorithm_nea0, NR_SecurityConfig__keyToUse_master); } else { /* TODO: handle more than one bearer */ if (m == NULL) { @@ -181,9 +168,9 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ } /* store security key and security capabilities */ - memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32); - ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms; - ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms; + memcpy(UE->kgnb, m->kgnb, 32); + UE->security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms; + UE->security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms; /* Select ciphering algorithm based on gNB configuration file and * UE's supported algorithms. @@ -191,7 +178,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ * The ordering of the list comes from the configuration file. */ /* preset nea0 as fallback */ - ue_context_p->ue_context.ciphering_algorithm = 0; + UE->ciphering_algorithm = 0; for (i = 0; i < rrc->security.ciphering_algorithms_count; i++) { int nea_mask[4] = { 0, @@ -203,13 +190,13 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ /* nea0 already preselected */ break; } - if (ue_context_p->ue_context.security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) { - ue_context_p->ue_context.ciphering_algorithm = rrc->security.ciphering_algorithms[i]; + if (UE->security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) { + UE->ciphering_algorithm = rrc->security.ciphering_algorithms[i]; break; } } - LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)ue_context_p->ue_context.ciphering_algorithm); + LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)UE->ciphering_algorithm); /* integrity: no integrity protection for DRB in ENDC mode * as written in 38.331: "If UE is connected to E-UTRA/EPC, this field @@ -218,49 +205,46 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ * So nothing for DRB. Plus a test with a COTS UE revealed that it * did not apply integrity on the DRB. */ - ue_context_p->ue_context.integrity_algorithm = 0; + UE->integrity_algorithm = 0; - LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm); + LOG_I(RRC, "selecting integrity algorithm %d\n", UE->integrity_algorithm); /* derive UP security key */ - nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, - ue_context_p->ue_context.kgnb, - &kUPenc); - nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm, - ue_context_p->ue_context.kgnb, - &kUPint); + nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc); + nr_derive_key_up_int(UE->integrity_algorithm, UE->kgnb, &kUPint); e_NR_CipheringAlgorithm cipher_algo; - switch (ue_context_p->ue_context.ciphering_algorithm) { - case 0: cipher_algo = NR_CipheringAlgorithm_nea0; break; - case 1: cipher_algo = NR_CipheringAlgorithm_nea1; break; - case 2: cipher_algo = NR_CipheringAlgorithm_nea2; break; - case 3: cipher_algo = NR_CipheringAlgorithm_nea3; break; - default: LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); + switch (UE->ciphering_algorithm) { + case 0: + cipher_algo = NR_CipheringAlgorithm_nea0; + break; + case 1: + cipher_algo = NR_CipheringAlgorithm_nea1; + break; + case 2: + cipher_algo = NR_CipheringAlgorithm_nea2; + break; + case 3: + cipher_algo = NR_CipheringAlgorithm_nea3; + break; + default: + LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); } - fill_default_rbconfig(ue_context_p->ue_context.rb_config, - m->e_rabs_tobeadded[0].e_rab_id, - m->e_rabs_tobeadded[0].drb_ID, - cipher_algo, - NR_SecurityConfig__keyToUse_secondary); + fill_default_rbconfig(UE->rb_config, m->e_rabs_tobeadded[0].e_rab_id, m->e_rabs_tobeadded[0].drb_ID, cipher_algo, NR_SecurityConfig__keyToUse_secondary); } - NR_ServingCellConfig_t *scc = ue_context_p->ue_context.spCellConfig ? - ue_context_p->ue_context.spCellConfig->spCellConfigDedicated : NULL; - fill_default_reconfig(carrier->servingcellconfigcommon, - scc, - reconfig_ies, - ue_context_p->ue_context.secondaryCellGroup, - ue_context_p->ue_context.UE_Capability_nr, - configuration, - ue_context_p->local_uid); - - ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; + NR_ServingCellConfig_t *scc = UE->spCellConfig ? UE->spCellConfig->spCellConfigDedicated : NULL; + fill_default_reconfig(carrier->servingcellconfigcommon, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, configuration, ue_context_p->ue_context.gNB_ue_ngap_id); + // the UE context is not yet inserted in the RRC UE manager + // rrc_gNB_update_ue_context_rnti(UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, rrc, + // UE->gNB_ue_ngap_id); + UE->rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); memset((void *)CG_Config,0,sizeof(*CG_Config)); - //int CG_Config_size = generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config); - generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config); + // int CG_Config_size = generate_CG_Config(rrc,CG_Config,UE->reconfig,UE->rb_config); + generate_CG_Config(rrc, CG_Config, UE->reconfig, UE->rb_config); if(m!=NULL) { uint8_t inde_list[m->nb_e_rabs_tobeadded]; @@ -268,15 +252,15 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ if (m->nb_e_rabs_tobeadded>0) { for (int i=0; inb_e_rabs_tobeadded; i++) { - // Add the new E-RABs at the corresponding rrc ue context of the gNB - ue_context_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id; - ue_context_p->ue_context.e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid; - memcpy(&ue_context_p->ue_context.e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t)); - ue_context_p->ue_context.nb_of_e_rabs++; + // Add the new E-RABs at the corresponding rrc ue context of the gNB + UE->e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id; + UE->e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid; + memcpy(&UE->e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t)); + UE->nb_of_e_rabs++; //Fill the required E-RAB specific information for the creation of the S1-U tunnel between the gNB and the SGW - create_tunnel_req.eps_bearer_id[i] = ue_context_p->ue_context.e_rab[i].param.e_rab_id; - create_tunnel_req.sgw_S1u_teid[i] = ue_context_p->ue_context.e_rab[i].param.gtp_teid; - memcpy(&create_tunnel_req.sgw_addr[i], &ue_context_p->ue_context.e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t)); + create_tunnel_req.eps_bearer_id[i] = UE->e_rab[i].param.e_rab_id; + create_tunnel_req.sgw_S1u_teid[i] = UE->e_rab[i].param.gtp_teid; + memcpy(&create_tunnel_req.sgw_addr[i], &UE->e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t)); inde_list[i] = i; LOG_I(RRC,"S1-U tunnel: index %d target sgw ip %d.%d.%d.%d length %d gtp teid %u\n", i, @@ -288,10 +272,10 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ create_tunnel_req.sgw_S1u_teid[i]); } - create_tunnel_req.rnti = ue_context_p->ue_id_rnti; + create_tunnel_req.rnti = ue_context_p->ue_context.rnti; create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded; RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[rrc->module_id]->rrc_ue_head, ue_context_p); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id); memset(&create_tunnel_resp, 0, sizeof(create_tunnel_resp)); if (!IS_SOFTMODEM_NOS1) { LOG_D(RRC, "Calling gtpv1u_create_s1u_tunnel()\n"); @@ -307,8 +291,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = m->nb_e_rabs_tobeadded; X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).target_assoc_id = m->target_assoc_id; - for(int i=0; iue_context.nb_of_e_rabs; i++) { - X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id; + for (int i = 0; i < UE->nb_of_e_rabs; i++) { + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = UE->e_rab[i].param.e_rab_id; X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid = create_tunnel_resp.enb_S1u_teid[i]; memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr, &create_tunnel_resp.enb_addr, sizeof(transport_layer_addr_t)); //The length field in the X2AP targetting structure is expected in bits but the create_tunnel_resp returns the address length in bytes @@ -334,7 +318,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ LOG_W(RRC, "No E-RAB to be added received from SgNB Addition Request message \n"); X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).MeNB_ue_x2_id = m->ue_x2_id; - X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; //X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size // Send to X2 entity to transport to MeNB asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config, @@ -346,18 +330,17 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding } - rrc->Nb_ue++; // configure MAC and RLC bool ret = false; if (get_softmodem_params()->phy_test) { // phytest mode: we don't set up RA, etc - ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id], ue_context_p->ue_id_rnti, ue_context_p->ue_context.secondaryCellGroup); + ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id] , ue_context_p->ue_context.rnti, ue_context_p->ue_context.secondaryCellGroup); } else { - ret = nr_mac_prepare_ra_nsa_ue(RC.nrmac[rrc->module_id], ue_context_p->ue_id_rnti, ue_context_p->ue_context.secondaryCellGroup); + ret = nr_mac_prepare_ra_nsa_ue(RC.nrmac[rrc->module_id], ue_context_p->ue_context.rnti, ue_context_p->ue_context.secondaryCellGroup); } AssertFatal(ret, "cannot add NSA UE in MAC, aborting\n"); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0, rrc->module_id); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id); if (get_softmodem_params()->do_ra) ctxt.enb_flag = 0; LOG_W(RRC, "Calling RRC PDCP/RLC ASN1 request functions for protocol context %p with module_id %d, rnti %lx, frame %d, subframe %d eNB_index %d \n", @@ -368,20 +351,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ctxt.subframe, ctxt.eNB_index); - nr_pdcp_add_drbs(ctxt.enb_flag, - ctxt.rntiMaybeUEid, - 0, - ue_context_p->ue_context.rb_config->drb_ToAddModList, - (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, - kUPenc, - kUPint, - ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); + nr_pdcp_add_drbs( + ctxt.enb_flag, ctxt.rntiMaybeUEid, 0, UE->rb_config->drb_ToAddModList, (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, kUPenc, kUPint, UE->secondaryCellGroup->rlc_BearerToAddModList); - nr_rrc_rlc_config_asn1_req(&ctxt, - get_softmodem_params()->sa ? ue_context_p->ue_context.rb_config->srb_ToAddModList : NULL, - ue_context_p->ue_context.rb_config->drb_ToAddModList, - ue_context_p->ue_context.rb_config->drb_ToReleaseList, - ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); + nr_rrc_rlc_config_asn1_req( + &ctxt, get_softmodem_params()->sa ? UE->rb_config->srb_ToAddModList : NULL, UE->rb_config->drb_ToAddModList, UE->rb_config->drb_ToReleaseList, UE->secondaryCellGroup->rlc_BearerToAddModList); LOG_D(RRC, "%s:%d: done RRC PDCP/RLC ASN1 request for UE rnti %lx\n", __FUNCTION__, __LINE__, ctxt.rntiMaybeUEid); } @@ -394,7 +368,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { LOG_D(RRC, "calling rrc_remove_nsa_user rnti %d\n", rnti); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rnti, 0, 0, rrc->module_id); - ue_context = rrc_gNB_get_ue_context(rrc, rnti); + ue_context = rrc_gNB_get_ue_context_by_rnti(rrc, rnti); if (ue_context == NULL) { LOG_W(RRC, "rrc_remove_nsa_user: rnti %d not found\n", rnti); return; @@ -419,5 +393,5 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { } gtpv1u_delete_s1u_tunnel(rrc->module_id, &tmp); /* remove context */ - rrc_gNB_remove_ue_context(&ctxt, rrc, ue_context); + rrc_gNB_remove_ue_context(rrc, ue_context); } diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index 37b5d0dd8b..1848601de8 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -22,19 +22,30 @@ #include "rrc_gNB_radio_bearers.h" #include "oai_asn1.h" -NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering) +rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create) { - NR_DRB_ToAddMod_t *DRB_config = NULL; - NR_SDAP_Config_t *SDAP_config = NULL; + int j; + for (j = 0; j < ue->nb_of_pdusessions; j++) + if (id == ue->pduSession[j].param.pdusession_id) + break; + if (j == ue->nb_of_pdusessions && create) + ue->nb_of_pdusessions++; + else + return NULL; + AssertFatal(ue->nb_of_pdusessions < NGAP_MAX_PDU_SESSION, ""); + return ue->pduSession + j; +} - DRB_config = CALLOC(1, sizeof(*DRB_config)); +NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering) +{ + NR_DRB_ToAddMod_t *DRB_config = CALLOC(1, sizeof(*DRB_config)); DRB_config->drb_Identity = drb_id; - DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation)); - DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; - + asn1cCalloc(DRB_config->cnAssociation, association); + association->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; + /* SDAP Configuration */ - SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); - SDAP_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd)); + NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); + asn1cCalloc(SDAP_config->mappedQoS_FlowsToAdd, sdapFlows); SDAP_config->pdu_Session = pduSession->param.pdusession_id; @@ -50,53 +61,36 @@ NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, pdu_session_par for (int qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) { - NR_QFI_t *qfi = calloc(1, sizeof(NR_QFI_t)); + asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi); *qfi = pduSession->param.qos[qos_flow_index].qfi; - asn1cSeqAdd(&SDAP_config->mappedQoS_FlowsToAdd->list, qfi); - if(pduSession->param.qos[qos_flow_index].fiveQI > 5) pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE_NONGBR; else pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE; } - - SDAP_config->mappedQoS_FlowsToRelease = NULL; - DRB_config->cnAssociation->choice.sdap_Config = SDAP_config; - + + association->choice.sdap_Config = SDAP_config; + /* PDCP Configuration */ - DRB_config->reestablishPDCP = NULL; - DRB_config->recoverPDCP = NULL; - DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config)); - DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb)); + asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig); + asn1cCalloc(pdcpConfig->drb, drb); - DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer)); - *DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_infinity; - DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL)); - *DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; - DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL)); - *DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; + asn1cCallocOne(drb->discardTimer, NR_PDCP_Config__drb__discardTimer_infinity); - DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; - DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0; - - DRB_config->pdcp_Config->drb->integrityProtection = NULL; - DRB_config->pdcp_Config->drb->statusReportRequired = NULL; - DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL; - DRB_config->pdcp_Config->moreThanOneRLC = NULL; - - DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering)); - *DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms100; - DRB_config->pdcp_Config->ext1 = NULL; + asn1cCallocOne(drb->pdcp_SN_SizeUL, NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits); + asn1cCallocOne(drb->pdcp_SN_SizeDL, NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits); + + drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; + drb->headerCompression.choice.notUsed = 0; + + asn1cCallocOne(pdcpConfig->t_Reordering, NR_PDCP_Config__t_Reordering_ms100); if (do_drb_integrity) { - DRB_config->pdcp_Config->drb->integrityProtection = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->integrityProtection)); - *DRB_config->pdcp_Config->drb->integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled; + asn1cCallocOne(drb->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled); } - if (!do_drb_ciphering) { - DRB_config->pdcp_Config->ext1 = calloc(1, sizeof(*DRB_config->pdcp_Config->ext1)); - DRB_config->pdcp_Config->ext1->cipheringDisabled = calloc(1, sizeof(*DRB_config->pdcp_Config->ext1->cipheringDisabled)); - *DRB_config->pdcp_Config->ext1->cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true; + asn1cCalloc(pdcpConfig->ext1, ext1); + asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true); } ue->DRB_active[drb_id-1] = DRB_ACTIVE; @@ -104,7 +98,7 @@ NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, pdu_session_par return DRB_config; } -uint8_t next_available_drb(gNB_RRC_UE_t *ue, pdu_session_param_t *pdusession, bool is_gbr) +uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr) { uint8_t drb_id; diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.h b/openair2/RRC/NR/rrc_gNB_radio_bearers.h index 6cd6443d4f..62065c1d87 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.h +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.h @@ -35,10 +35,10 @@ #define GBR_FLOW (1) #define NONGBR_FLOW (0) -NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue, uint8_t drb_id, pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering); - -uint8_t next_available_drb(gNB_RRC_UE_t *ue, pdu_session_param_t *pdusession, bool is_gbr); - +NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering); +uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr); bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id); +rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create); + #endif diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c index e9a22eb578..280663e2b0 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c @@ -435,14 +435,9 @@ nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb, bool has_sdap_rx, bool has_sdap if(is_defaultDRB) { sdap_entity->default_drb = drb_identity; LOG_I(SDAP, "Default DRB for the created SDAP entity: %ld \n", sdap_entity->default_drb); - - if(mappedQFIs2AddCount) { - LOG_D(SDAP, "RRC updating mapping rules\n"); - for (int i = 0; i < mappedQFIs2AddCount; i++) - { - sdap_entity->qfi2drb_map_update(sdap_entity, mapped_qfi_2_add[i], sdap_entity->default_drb, has_sdap_rx, has_sdap_tx); - } - } + LOG_D(SDAP, "RRC updating mapping rules: %d\n", mappedQFIs2AddCount); + for (int i = 0; i < mappedQFIs2AddCount; i++) + sdap_entity->qfi2drb_map_update(sdap_entity, mapped_qfi_2_add[i], sdap_entity->default_drb, has_sdap_rx, has_sdap_tx); } sdap_entity->next_entity = sdap_info.sdap_entity_llist; diff --git a/openair2/X2AP/x2ap_eNB_itti_messaging.c b/openair2/X2AP/x2ap_eNB_itti_messaging.c index 26e26ba411..66be3520e2 100644 --- a/openair2/X2AP/x2ap_eNB_itti_messaging.c +++ b/openair2/X2AP/x2ap_eNB_itti_messaging.c @@ -43,7 +43,7 @@ void x2ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin sctp_data_req->assoc_id = assoc_id; sctp_data_req->buffer = buffer; sctp_data_req->buffer_length = buffer_length; - sctp_data_req->stream = stream; + sctp_data_req->stream = stream; itti_send_msg_to_task(TASK_SCTP, instance, message_p); } diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 9ab93355b4..9d3eb6db76 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -859,6 +859,7 @@ void *nas_nrue_task(void *args_p) instance = msg_p->ittiMsgHeader.originInstance; Mod_id = instance ; uicc_t *uicc=checkUicc(Mod_id); + LOG_I(NAS, "[UE %d] Received %s\n", Mod_id, ITTI_MSG_NAME(msg_p)); if (instance == INSTANCE_DEFAULT) { printf("%s:%d: FATAL: instance is INSTANCE_DEFAULT, should not happen.\n", @@ -867,84 +868,83 @@ void *nas_nrue_task(void *args_p) } switch (ITTI_MSG_ID(msg_p)) { - case INITIALIZE_MESSAGE: - LOG_I(NAS, "[UE %d] Received %s\n", Mod_id, ITTI_MSG_NAME (msg_p)); + case INITIALIZE_MESSAGE: - break; + break; - case TERMINATE_MESSAGE: - itti_exit_task (); - break; + case TERMINATE_MESSAGE: + itti_exit_task(); + break; - case MESSAGE_TEST: - LOG_I(NAS, "[UE %d] Received %s\n", Mod_id, ITTI_MSG_NAME (msg_p)); - break; + case MESSAGE_TEST: + break; - case NAS_CELL_SELECTION_CNF: - LOG_I(NAS, "[UE %d] Received %s: errCode %u, cellID %u, tac %u\n", Mod_id, ITTI_MSG_NAME (msg_p), - NAS_CELL_SELECTION_CNF (msg_p).errCode, NAS_CELL_SELECTION_CNF (msg_p).cellID, NAS_CELL_SELECTION_CNF (msg_p).tac); - // as_stmsi_t s_tmsi={0, 0}; - // as_nas_info_t nas_info; - // plmn_t plmnID={0, 0, 0, 0}; - // generateRegistrationRequest(&nas_info); - // nr_nas_itti_nas_establish_req(0, AS_TYPE_ORIGINATING_SIGNAL, s_tmsi, plmnID, nas_info.data, nas_info.length, 0); - break; + case NAS_CELL_SELECTION_CNF: + LOG_I(NAS, + "[UE %d] Received %s: errCode %u, cellID %u, tac %u\n", + Mod_id, + ITTI_MSG_NAME(msg_p), + NAS_CELL_SELECTION_CNF(msg_p).errCode, + NAS_CELL_SELECTION_CNF(msg_p).cellID, + NAS_CELL_SELECTION_CNF(msg_p).tac); + // as_stmsi_t s_tmsi={0, 0}; + // as_nas_info_t nas_info; + // plmn_t plmnID={0, 0, 0, 0}; + // generateRegistrationRequest(&nas_info); + // nr_nas_itti_nas_establish_req(0, AS_TYPE_ORIGINATING_SIGNAL, s_tmsi, plmnID, nas_info.data, nas_info.length, 0); + break; - case NAS_CELL_SELECTION_IND: - LOG_I(NAS, "[UE %d] Received %s: cellID %u, tac %u\n", Mod_id, ITTI_MSG_NAME (msg_p), - NAS_CELL_SELECTION_IND (msg_p).cellID, NAS_CELL_SELECTION_IND (msg_p).tac); + case NAS_CELL_SELECTION_IND: + LOG_I(NAS, "[UE %d] Received %s: cellID %u, tac %u\n", Mod_id, ITTI_MSG_NAME(msg_p), NAS_CELL_SELECTION_IND(msg_p).cellID, NAS_CELL_SELECTION_IND(msg_p).tac); - /* TODO not processed by NAS currently */ - break; + /* TODO not processed by NAS currently */ + break; - case NAS_PAGING_IND: - LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id, ITTI_MSG_NAME (msg_p), - NAS_PAGING_IND (msg_p).cause); + case NAS_PAGING_IND: + LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id, ITTI_MSG_NAME(msg_p), NAS_PAGING_IND(msg_p).cause); - /* TODO not processed by NAS currently */ - break; + /* TODO not processed by NAS currently */ + break; - case NAS_CONN_ESTABLI_CNF: - { - LOG_I(NAS, "[UE %d] Received %s: errCode %u, length %u\n", Mod_id, ITTI_MSG_NAME (msg_p), - NAS_CONN_ESTABLI_CNF (msg_p).errCode, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length); + case NAS_CONN_ESTABLI_CNF: { + LOG_I(NAS, "[UE %d] Received %s: errCode %u, length %u\n", Mod_id, ITTI_MSG_NAME(msg_p), NAS_CONN_ESTABLI_CNF(msg_p).errCode, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); - pdu_buffer = NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.data; - msg_type = get_msg_type(pdu_buffer, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length); + pdu_buffer = NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data; + msg_type = get_msg_type(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); - if(msg_type == REGISTRATION_ACCEPT){ - LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n"); + if (msg_type == REGISTRATION_ACCEPT) { + LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n"); - as_nas_info_t initialNasMsg; - memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); - generateRegistrationComplete(Mod_id,&initialNasMsg, NULL); - if(initialNasMsg.length > 0){ - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ); - NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id; - NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data; - NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length; - itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p); - LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); + as_nas_info_t initialNasMsg; + memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); + generateRegistrationComplete(Mod_id, &initialNasMsg, NULL); + if (initialNasMsg.length > 0) { + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ); + NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length; + itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p); + LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); + } + + as_nas_info_t pduEstablishMsg; + memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t)); + generatePduSessionEstablishRequest(Mod_id, uicc, &pduEstablishMsg); + if (pduEstablishMsg.length > 0) { + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ); + NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length; + itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p); + LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); + } + } else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) { + capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); } - as_nas_info_t pduEstablishMsg; - memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t)); - generatePduSessionEstablishRequest(Mod_id, uicc, &pduEstablishMsg); - if(pduEstablishMsg.length > 0){ - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ); - NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id; - NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data; - NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length; - itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p); - LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); - } - } else if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){ - capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length); - } - - break; + break; } case NAS_CONN_RELEASE_IND: diff --git a/openair3/NGAP/ngap_common.h b/openair3/NGAP/ngap_common.h index 9879ce7313..8de2542766 100644 --- a/openair3/NGAP/ngap_common.h +++ b/openair3/NGAP/ngap_common.h @@ -113,27 +113,27 @@ extern int asn1_xer_print; # define NGAP_DEBUG(x, args...) do { fprintf(stdout, "[NGAP][D]"x, ##args); } while(0) #endif +#define NGAP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \ + do { \ + IE_TYPE **ptr; \ + ie = NULL; \ + for (ptr = container->protocolIEs.list.array; ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; ptr++) { \ + if ((*ptr)->id == IE_ID) { \ + ie = *ptr; \ + break; \ + } \ + } \ + if (ie == NULL) { \ + if (mandatory) { \ + AssertFatal(NGAP, "NGAP_FIND_PROTOCOLIE_BY_ID ie is NULL (searching for ie: %ld)\n", IE_ID); \ + } else { \ + NGAP_INFO("NGAP_FIND_PROTOCOLIE_BY_ID ie is NULL (searching for ie: %ld)\n", IE_ID); \ + } \ + } \ + } while (0); \ + if (mandatory && !ie) \ + return -1 -#define NGAP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \ - do {\ - IE_TYPE **ptr; \ - ie = NULL; \ - for (ptr = container->protocolIEs.list.array; \ - ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \ - ptr++) { \ - if((*ptr)->id == IE_ID) { \ - ie = *ptr; \ - break; \ - } \ - } \ - if (ie == NULL ) { \ - if (mandatory) {\ - NGAP_ERROR("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL (searching for ie: %ld)\n",__FILE__,__LINE__, IE_ID);\ - abort();\ - }\ - else NGAP_INFO("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL (searching for ie: %ld)\n",__FILE__,__LINE__, IE_ID);\ - } \ - } while(0) /** \brief Function callback prototype. **/ typedef int (*ngap_message_decoded_callback)( diff --git a/openair3/NGAP/ngap_gNB.c b/openair3/NGAP/ngap_gNB.c index b4a3aa2f14..f877e9d4ba 100644 --- a/openair3/NGAP/ngap_gNB.c +++ b/openair3/NGAP/ngap_gNB.c @@ -162,7 +162,6 @@ void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_gnb_req_t * } else { new_instance = calloc(1, sizeof(ngap_gNB_instance_t)); DevAssert(new_instance != NULL); - RB_INIT(&new_instance->ngap_ue_head); RB_INIT(&new_instance->ngap_amf_head); /* Copy usefull parameters */ new_instance->instance = instance; @@ -276,127 +275,88 @@ void *ngap_gNB_process_itti_msg(void *notUsed) { MessageDef *received_msg = NULL; int result; itti_receive_msg(TASK_NGAP, &received_msg); + if (received_msg) { + instance_t instance = ITTI_MSG_DESTINATION_INSTANCE(received_msg); + LOG_D(RRC, "Received message %s\n", ITTI_MSG_NAME(received_msg)); + switch (ITTI_MSG_ID(received_msg)) { + case TERMINATE_MESSAGE: + NGAP_WARN(" *** Exiting NGAP thread\n"); + itti_exit_task(); + break; - switch (ITTI_MSG_ID(received_msg)) { - case TERMINATE_MESSAGE: - NGAP_WARN(" *** Exiting NGAP thread\n"); - itti_exit_task(); - break; + case NGAP_REGISTER_GNB_REQ: + /* Register a new gNB. + * in Virtual mode gNBs will be distinguished using the mod_id/ + * Each gNB has to send an NGAP_REGISTER_GNB message with its + * own parameters. + */ + ngap_gNB_handle_register_gNB(instance, &NGAP_REGISTER_GNB_REQ(received_msg)); + break; - case NGAP_REGISTER_GNB_REQ: { - /* Register a new gNB. - * in Virtual mode gNBs will be distinguished using the mod_id/ - * Each gNB has to send an NGAP_REGISTER_GNB message with its - * own parameters. - */ - ngap_gNB_handle_register_gNB(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_REGISTER_GNB_REQ(received_msg)); + case SCTP_NEW_ASSOCIATION_RESP: + ngap_gNB_handle_sctp_association_resp(instance, &received_msg->ittiMsg.sctp_new_association_resp); + break; + + case SCTP_DATA_IND: + ngap_gNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind); + break; + + case NGAP_NAS_FIRST_REQ: + ngap_gNB_handle_nas_first_req(instance, &NGAP_NAS_FIRST_REQ(received_msg)); + break; + + case NGAP_UPLINK_NAS: + ngap_gNB_nas_uplink(instance, &NGAP_UPLINK_NAS(received_msg)); + break; + + case NGAP_UE_CAPABILITIES_IND: + ngap_gNB_ue_capabilities(instance, &NGAP_UE_CAPABILITIES_IND(received_msg)); + break; + + case NGAP_INITIAL_CONTEXT_SETUP_RESP: + ngap_gNB_initial_ctxt_resp(instance, &NGAP_INITIAL_CONTEXT_SETUP_RESP(received_msg)); + break; + + case NGAP_PDUSESSION_SETUP_RESP: + ngap_gNB_pdusession_setup_resp(instance, &NGAP_PDUSESSION_SETUP_RESP(received_msg)); + break; + + case NGAP_PDUSESSION_MODIFY_RESP: + ngap_gNB_pdusession_modify_resp(instance, &NGAP_PDUSESSION_MODIFY_RESP(received_msg)); + break; + + case NGAP_NAS_NON_DELIVERY_IND: + ngap_gNB_nas_non_delivery_ind(instance, &NGAP_NAS_NON_DELIVERY_IND(received_msg)); + break; + + case NGAP_PATH_SWITCH_REQ: + ngap_gNB_path_switch_req(instance, &NGAP_PATH_SWITCH_REQ(received_msg)); + break; + + case NGAP_PDUSESSION_MODIFICATION_IND: + ngap_gNB_generate_PDUSESSION_Modification_Indication(instance, &NGAP_PDUSESSION_MODIFICATION_IND(received_msg)); + break; + + case NGAP_UE_CONTEXT_RELEASE_COMPLETE: + ngap_ue_context_release_complete(instance, &NGAP_UE_CONTEXT_RELEASE_COMPLETE(received_msg)); + break; + + case NGAP_UE_CONTEXT_RELEASE_REQ: + ngap_ue_context_release_req(instance, &NGAP_UE_CONTEXT_RELEASE_REQ(received_msg)); + break; + + case NGAP_PDUSESSION_RELEASE_RESPONSE: + ngap_gNB_pdusession_release_resp(instance, &NGAP_PDUSESSION_RELEASE_RESPONSE(received_msg)); + break; + + default: + NGAP_ERROR("Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; } - break; - case SCTP_NEW_ASSOCIATION_RESP: { - ngap_gNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &received_msg->ittiMsg.sctp_new_association_resp); - } - break; - - case SCTP_DATA_IND: { - ngap_gNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind); - } - break; - - case NGAP_NAS_FIRST_REQ: { - ngap_gNB_handle_nas_first_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_NAS_FIRST_REQ(received_msg)); - } - break; - - case NGAP_UPLINK_NAS: { - ngap_gNB_nas_uplink(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_UPLINK_NAS(received_msg)); - } - break; - - case NGAP_UE_CAPABILITIES_IND: { - ngap_gNB_ue_capabilities(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_UE_CAPABILITIES_IND(received_msg)); - } - break; - - case NGAP_INITIAL_CONTEXT_SETUP_RESP: { - ngap_gNB_initial_ctxt_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_INITIAL_CONTEXT_SETUP_RESP(received_msg)); - } - break; - - case NGAP_PDUSESSION_SETUP_RESP: { - ngap_gNB_pdusession_setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_PDUSESSION_SETUP_RESP(received_msg)); - } - break; - - case NGAP_PDUSESSION_MODIFY_RESP: { - ngap_gNB_pdusession_modify_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_PDUSESSION_MODIFY_RESP(received_msg)); - } - break; - - case NGAP_NAS_NON_DELIVERY_IND: { - ngap_gNB_nas_non_delivery_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_NAS_NON_DELIVERY_IND(received_msg)); - } - break; - - case NGAP_PATH_SWITCH_REQ: { - ngap_gNB_path_switch_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_PATH_SWITCH_REQ(received_msg)); - } - break; - - case NGAP_PDUSESSION_MODIFICATION_IND: { - ngap_gNB_generate_PDUSESSION_Modification_Indication(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_PDUSESSION_MODIFICATION_IND(received_msg)); - } - break; - - case NGAP_UE_CONTEXT_RELEASE_COMPLETE: { - ngap_ue_context_release_complete(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_UE_CONTEXT_RELEASE_COMPLETE(received_msg)); - } - break; - - case NGAP_UE_CONTEXT_RELEASE_REQ: { - ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; // test - struct ngap_gNB_ue_context_s *ue_context_p = NULL; // test - ngap_ue_context_release_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_UE_CONTEXT_RELEASE_REQ(received_msg)); - ngap_gNB_instance_p = ngap_gNB_get_instance(ITTI_MSG_DESTINATION_INSTANCE(received_msg)); // test - DevAssert(ngap_gNB_instance_p != NULL); // test - - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - NGAP_UE_CONTEXT_RELEASE_REQ(received_msg).gNB_ue_ngap_id)) == NULL) { // test - /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ - NGAP_ERROR("Failed to find ue context associated with gNB ue ngap id: %u\n", - NGAP_UE_CONTEXT_RELEASE_REQ(received_msg).gNB_ue_ngap_id); // test - } // test - } - break; - - case NGAP_PDUSESSION_RELEASE_RESPONSE: { - ngap_gNB_pdusession_release_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &NGAP_PDUSESSION_RELEASE_RESPONSE(received_msg)); - } - break; - - default: - NGAP_ERROR("Received unhandled message: %d:%s\n", - ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); - break; + result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } - - result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - received_msg = NULL; return NULL; } diff --git a/openair3/NGAP/ngap_gNB_context_management_procedures.c b/openair3/NGAP/ngap_gNB_context_management_procedures.c index 6c1a8584a6..8d3c20d218 100644 --- a/openair3/NGAP/ngap_gNB_context_management_procedures.c +++ b/openair3/NGAP/ngap_gNB_context_management_procedures.c @@ -58,9 +58,7 @@ int ngap_ue_context_release_complete(instance_t instance, ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; struct ngap_gNB_ue_context_s *ue_context_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_UEContextReleaseComplete_t *out; - NGAP_UEContextReleaseComplete_IEs_t *ie; + NGAP_NGAP_PDU_t pdu = {0}; uint8_t *buffer; uint32_t length; @@ -70,44 +68,37 @@ int ngap_ue_context_release_complete(instance_t instance, DevAssert(ue_release_complete_p != NULL); DevAssert(ngap_gNB_instance_p != NULL); - /*RB_FOREACH(ue_context_p, ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head) { - NGAP_WARN("in ngap_ue_map: UE context gNB_ue_ngap_id %u amf_ue_ngap_id %u state %u\n", - ue_context_p->gNB_ue_ngap_id, ue_context_p->amf_ue_ngap_id, - ue_context_p->ue_state); - }*/ - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - ue_release_complete_p->gNB_ue_ngap_id)) == NULL) { + if ((ue_context_p = ngap_get_ue_context(ue_release_complete_p->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: %u\n", - ue_release_complete_p->gNB_ue_ngap_id); + NGAP_ERROR("Failed to find ue context associated with gNB ue ngap id: %u\n", ue_release_complete_p->gNB_ue_ngap_id); return -1; } /* Prepare the NGAP message to encode */ - memset(&pdu, 0, sizeof(pdu)); pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome = CALLOC(1, sizeof(struct NGAP_SuccessfulOutcome)); - pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_UEContextRelease; - pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; - pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_UEContextReleaseComplete; - out = &pdu.choice.successfulOutcome->value.choice.UEContextReleaseComplete; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NGAP_ProcedureCode_id_UEContextRelease; + head->criticality = NGAP_Criticality_reject; + head->value.present = NGAP_SuccessfulOutcome__value_PR_UEContextReleaseComplete; + NGAP_UEContextReleaseComplete_t *out = &head->value.choice.UEContextReleaseComplete; /* mandatory */ - ie = (NGAP_UEContextReleaseComplete_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseComplete_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_AMF_UE_NGAP_ID; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseComplete_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + } /* mandatory */ - ie = (NGAP_UEContextReleaseComplete_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseComplete_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = ue_release_complete_p->gNB_ue_ngap_id; - asn1cSeqAdd(&out->protocolIEs.list, ie); - + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseComplete_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_release_complete_p->gNB_ue_ngap_id; + } if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { /* Encode procedure has failed... */ @@ -123,35 +114,18 @@ int ngap_ue_context_release_complete(instance_t instance, //LG ngap_gNB_itti_send_sctp_close_association(ngap_gNB_instance_p->instance, // ue_context_p->amf_ref->assoc_id); // release UE context - struct ngap_gNB_ue_context_s *ue_context2_p = NULL; - - if ((ue_context2_p = RB_REMOVE(ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head, ue_context_p)) - != NULL) { - NGAP_WARN("Removed UE context gNB_ue_ngap_id %u\n", - ue_context2_p->gNB_ue_ngap_id); - ngap_gNB_free_ue_context(ue_context2_p); - } else { - NGAP_WARN("Removing UE context gNB_ue_ngap_id %u: did not find context\n", - ue_context_p->gNB_ue_ngap_id); - } - /*RB_FOREACH(ue_context_p, ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head) { - NGAP_WARN("in ngap_ue_map: UE context gNB_ue_ngap_id %u amf_ue_ngap_id %u state %u\n", - ue_context_p->gNB_ue_ngap_id, ue_context_p->amf_ue_ngap_id, - ue_context_p->ue_state); - }*/ - + ngap_gNB_ue_context_t *tmp = ngap_detach_ue_context(ue_release_complete_p->gNB_ue_ngap_id); + if (tmp) + free(tmp); return 0; } - int ngap_ue_context_release_req(instance_t instance, ngap_ue_release_req_t *ue_release_req_p) { ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; struct ngap_gNB_ue_context_s *ue_context_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_UEContextReleaseRequest_t *out; - NGAP_UEContextReleaseRequest_IEs_t *ie; + NGAP_NGAP_PDU_t pdu = {0}; uint8_t *buffer = NULL; uint32_t length; /* Retrieve the NGAP gNB instance associated with Mod_id */ @@ -160,8 +134,7 @@ int ngap_ue_context_release_req(instance_t instance, DevAssert(ue_release_req_p != NULL); DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - ue_release_req_p->gNB_ue_ngap_id)) == NULL) { + if ((ue_context_p = ngap_get_ue_context(ue_release_req_p->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: %u\n", ue_release_req_p->gNB_ue_ngap_id); @@ -169,33 +142,34 @@ int ngap_ue_context_release_req(instance_t instance, } /* Prepare the NGAP message to encode */ - memset(&pdu, 0, sizeof(pdu)); pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage = CALLOC(1, sizeof(struct NGAP_InitiatingMessage)); - pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UEContextReleaseRequest; - pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; - pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UEContextReleaseRequest; - out = &pdu.choice.initiatingMessage->value.choice.UEContextReleaseRequest; + asn1cCalloc(pdu.choice.initiatingMessage, head); + head->procedureCode = NGAP_ProcedureCode_id_UEContextReleaseRequest; + head->criticality = NGAP_Criticality_ignore; + head->value.present = NGAP_InitiatingMessage__value_PR_UEContextReleaseRequest; + NGAP_UEContextReleaseRequest_t *out = &head->value.choice.UEContextReleaseRequest; /* mandatory */ - ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_AMF_UE_NGAP_ID; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseRequest_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + } /* mandatory */ - ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = ue_release_req_p->gNB_ue_ngap_id; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseRequest_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_release_req_p->gNB_ue_ngap_id; + } /* optional */ if (ue_release_req_p->nb_of_pdusessions > 0) { - ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t)); + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseRequest_IEs_t, ie); ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceListCxtRelReq; ie->criticality = NGAP_Criticality_reject; ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_PDUSessionResourceListCxtRelReq; @@ -205,51 +179,19 @@ int ngap_ue_context_release_req(instance_t instance, item->pDUSessionID = ue_release_req_p->pdusessions[i].pdusession_id; asn1cSeqAdd(&ie->value.choice.PDUSessionResourceListCxtRelReq.list, item); } - asn1cSeqAdd(&out->protocolIEs.list, ie); } /* mandatory */ - ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_Cause; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_Cause; - - switch (ue_release_req_p->cause) { - case NGAP_Cause_PR_radioNetwork: - ie->value.choice.Cause.present = NGAP_Cause_PR_radioNetwork; - ie->value.choice.Cause.choice.radioNetwork = ue_release_req_p->cause_value; - break; - - case NGAP_Cause_PR_transport: - ie->value.choice.Cause.present = NGAP_Cause_PR_transport; - ie->value.choice.Cause.choice.transport = ue_release_req_p->cause_value; - break; - - case NGAP_Cause_PR_nas: - ie->value.choice.Cause.present = NGAP_Cause_PR_nas; - ie->value.choice.Cause.choice.nas = ue_release_req_p->cause_value; - break; - - case NGAP_Cause_PR_protocol: - ie->value.choice.Cause.present = NGAP_Cause_PR_protocol; - ie->value.choice.Cause.choice.protocol = ue_release_req_p->cause_value; - break; - - case NGAP_Cause_PR_misc: - ie->value.choice.Cause.present = NGAP_Cause_PR_misc; - ie->value.choice.Cause.choice.misc = ue_release_req_p->cause_value; - break; - - case NGAP_Cause_PR_NOTHING: - default: - ie->value.choice.Cause.present = NGAP_Cause_PR_NOTHING; - break; + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseRequest_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_Cause; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_Cause; + DevAssert(ue_release_req_p->cause <= NGAP_Cause_PR_choice_ExtensionS); + ie->value.choice.Cause.present = ue_release_req_p->cause; + ie->value.choice.Cause.choice.misc = ue_release_req_p->cause_value; } - asn1cSeqAdd(&out->protocolIEs.list, ie); - - - if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { /* Encode procedure has failed... */ NGAP_ERROR("Failed to encode UE context release complete\n"); diff --git a/openair3/NGAP/ngap_gNB_decoder.c b/openair3/NGAP/ngap_gNB_decoder.c index b551471a84..c752ace05d 100644 --- a/openair3/NGAP/ngap_gNB_decoder.c +++ b/openair3/NGAP/ngap_gNB_decoder.c @@ -156,13 +156,8 @@ int ngap_gNB_decode_pdu(NGAP_NGAP_PDU_t *pdu, const uint8_t *const buffer, asn_dec_rval_t dec_ret; DevAssert(pdu != NULL); DevAssert(buffer != NULL); - dec_ret = aper_decode(NULL, - &asn_DEF_NGAP_NGAP_PDU, - (void **)&pdu, - buffer, - length, - 0, - 0); + asn_codec_ctx_t st = {.max_stack_size = 100 * 1000}; // if we enable asn1c debug the stack size become large + dec_ret = aper_decode(&st, &asn_DEF_NGAP_NGAP_PDU, (void **)&pdu, buffer, length, 0, 0); if (dec_ret.code != RC_OK) { NGAP_ERROR("Failed to decode pdu\n"); diff --git a/openair3/NGAP/ngap_gNB_defs.h b/openair3/NGAP/ngap_gNB_defs.h index f2bdd646ae..5591ecb061 100644 --- a/openair3/NGAP/ngap_gNB_defs.h +++ b/openair3/NGAP/ngap_gNB_defs.h @@ -236,11 +236,6 @@ typedef struct ngap_gNB_instance_s { /* Tree of NGAP AMF associations ordered by association ID */ RB_HEAD(ngap_amf_map, ngap_gNB_amf_data_s) ngap_amf_head; - /* TODO: add a map ordered by relative AMF capacity */ - - /* Tree of UE ordered by gNB_ue_ngap_id's */ - RB_HEAD(ngap_ue_map, ngap_gNB_ue_context_s) ngap_ue_head; - /* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */ instance_t instance; diff --git a/openair3/NGAP/ngap_gNB_encoder.c b/openair3/NGAP/ngap_gNB_encoder.c index c69de32467..e85ae4c8eb 100644 --- a/openair3/NGAP/ngap_gNB_encoder.c +++ b/openair3/NGAP/ngap_gNB_encoder.c @@ -38,23 +38,84 @@ #include "ngap_common.h" #include "ngap_gNB_encoder.h" -static inline int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu, - uint8_t **buffer, - uint32_t *len); +static inline int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); -static inline int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu, - uint8_t **buffer, uint32_t *len); + const NGAP_ProcedureCode_t tmp[] = {NGAP_ProcedureCode_id_NGSetup, + NGAP_ProcedureCode_id_UplinkNASTransport, + NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication, + NGAP_ProcedureCode_id_InitialUEMessage, + NGAP_ProcedureCode_id_NASNonDeliveryIndication, + NGAP_ProcedureCode_id_UEContextReleaseRequest, + NGAP_ProcedureCode_id_PathSwitchRequest, + NGAP_ProcedureCode_id_PDUSessionResourceModifyIndication}; + int i; + for (i = 0; i < sizeofArray(tmp); i++) + if (pdu->choice.initiatingMessage->procedureCode == tmp[i]) + break; + if (i == sizeofArray(tmp)) { + NGAP_DEBUG("Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } -static inline int ngap_gNB_encode_unsuccessfull_outcome(NGAP_NGAP_PDU_t *pdu, - uint8_t **buffer, uint32_t *len); + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NGAP msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} -int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) { +static inline int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); + const NGAP_ProcedureCode_t tmp[] = {NGAP_ProcedureCode_id_InitialContextSetup, + NGAP_ProcedureCode_id_UEContextRelease, + NGAP_ProcedureCode_id_PDUSessionResourceSetup, + NGAP_ProcedureCode_id_PDUSessionResourceModify, + NGAP_ProcedureCode_id_PDUSessionResourceRelease}; + int i; + for (i = 0; i < sizeofArray(tmp); i++) + if (pdu->choice.successfulOutcome->procedureCode == tmp[i]) + break; + if (i == sizeofArray(tmp)) { + NGAP_WARN("Unknown procedure ID (%ld) for successfull outcome message\n", pdu->choice.successfulOutcome->procedureCode); + return -1; + } + + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NGAP msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +static inline int ngap_gNB_encode_unsuccessfull_outcome(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); + + if (pdu->choice.unsuccessfulOutcome->procedureCode != NGAP_ProcedureCode_id_InitialContextSetup) { + NGAP_DEBUG("Unknown procedure ID (%d) for unsuccessfull outcome message\n", (int)pdu->choice.unsuccessfulOutcome->procedureCode); + return -1; + } + + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NGAP msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ int ret = -1; DevAssert(pdu != NULL); DevAssert(buffer != NULL); DevAssert(len != NULL); - - switch(pdu->present) { + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu); + } + switch (pdu->present) { case NGAP_NGAP_PDU_PR_initiatingMessage: ret = ngap_gNB_encode_initiating(pdu, buffer, len); break; @@ -68,156 +129,9 @@ int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) { break; default: - NGAP_DEBUG("Unknown message outcome (%d) or not implemented", - (int)pdu->present); + NGAP_DEBUG("Unknown message outcome (%d) or not implemented", (int)pdu->present); return -1; } - - //ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, pdu); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, pdu); return ret; } - -static inline -int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu, - uint8_t **buffer, uint32_t *len) { - asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; - DevAssert(pdu != NULL); - - switch(pdu->choice.initiatingMessage->procedureCode) { - case NGAP_ProcedureCode_id_NGSetup: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - break; - - case NGAP_ProcedureCode_id_UplinkNASTransport: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - break; - - case NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - break; - - case NGAP_ProcedureCode_id_InitialUEMessage: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - break; - - case NGAP_ProcedureCode_id_NASNonDeliveryIndication: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - break; - - case NGAP_ProcedureCode_id_UEContextReleaseRequest: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - break; - - case NGAP_ProcedureCode_id_PathSwitchRequest: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - break; - - case NGAP_ProcedureCode_id_PDUSessionResourceModifyIndication: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - break; - - default: - NGAP_DEBUG("Unknown procedure ID (%d) for initiating message\n", - (int)pdu->choice.initiatingMessage->procedureCode); - return -1; - } - - if (asn1_xer_print) { - xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu); - } - - memset(&res, 0, sizeof(res)); - res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu); - *buffer = res.buffer; - *len = res.result.encoded; - return 0; -} - -static inline -int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu, - uint8_t **buffer, uint32_t *len) { - asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; - DevAssert(pdu != NULL); - - switch(pdu->choice.successfulOutcome->procedureCode) { - case NGAP_ProcedureCode_id_InitialContextSetup: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - break; - - case NGAP_ProcedureCode_id_UEContextRelease: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - break; - - case NGAP_ProcedureCode_id_PDUSessionResourceSetup: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - NGAP_INFO("PDUSESSIONSetup successful message\n"); - break; - - case NGAP_ProcedureCode_id_PDUSessionResourceModify: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - NGAP_INFO("PDUSESSIONModify successful message\n"); - break; - - case NGAP_ProcedureCode_id_PDUSessionResourceRelease: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - NGAP_INFO("PDUSESSION Release successful message\n"); - break; - - default: - NGAP_WARN("Unknown procedure ID (%d) for successfull outcome message\n", - (int)pdu->choice.successfulOutcome->procedureCode); - return -1; - } - - if (asn1_xer_print) { - xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu); - } - - memset(&res, 0, sizeof(res)); - res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu); - *buffer = res.buffer; - *len = res.result.encoded; - return 0; -} - -static inline -int ngap_gNB_encode_unsuccessfull_outcome(NGAP_NGAP_PDU_t *pdu, - uint8_t **buffer, uint32_t *len) { - asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; - DevAssert(pdu != NULL); - - switch(pdu->choice.unsuccessfulOutcome->procedureCode) { - case NGAP_ProcedureCode_id_InitialContextSetup: - res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); - free(res.buffer); - break; - - default: - NGAP_DEBUG("Unknown procedure ID (%d) for unsuccessfull outcome message\n", - (int)pdu->choice.unsuccessfulOutcome->procedureCode); - return -1; - } - - if (asn1_xer_print) { - xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu); - } - - memset(&res, 0, sizeof(res)); - res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu); - *buffer = res.buffer; - *len = res.result.encoded; - return 0; -} diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index 487dd40ca1..f3fd9e84e7 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -48,119 +48,15 @@ #include "conversions.h" #include "NGAP_NonDynamic5QIDescriptor.h" -static int ngap_gNB_handle_ng_setup_response(uint32_t ssoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu); -static -int ngap_gNB_handle_ng_setup_failure(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); +static void allocCopy(ngap_pdu_t *out, OCTET_STRING_t in) +{ + if (in.size) { + out->buffer = malloc(in.size); + memcpy(out->buffer, in.buf, in.size); + } + out->length = in.size; +} -static -int ngap_gNB_handle_error_indication(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); - -static -int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); - -static -int ngap_gNB_handle_ue_context_release_command(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); - -static -int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); - -static -int ngap_gNB_handle_paging(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); - -static -int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); - -static -int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); - -static -int ngap_gNB_handle_ng_path_switch_request_ack(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); - -static -int ngap_gNB_handle_ng_path_switch_request_failure(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); - -static -int ngap_gNB_handle_ng_ENDC_pdusession_modification_confirm(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu); - -/* Handlers matrix. Only gNB related procedure present here */ -ngap_message_decoded_callback ngap_messages_callback[][3] = { - { 0, 0, 0 }, /* AMFConfigurationUpdate */ - { 0, 0, 0 }, /* AMFStatusIndication */ - { 0, 0, 0 }, /* CellTrafficTrace */ - { ngap_gNB_handle_deactivate_trace, 0, 0 }, /* DeactivateTrace */ - { ngap_gNB_handle_nas_downlink, 0, 0 }, /* DownlinkNASTransport */ - { 0, 0, 0 }, /* DownlinkNonUEAssociatedNRPPaTransport */ - { 0, 0, 0 }, /* DownlinkRANConfigurationTransfer */ - { 0, 0, 0 }, /* DownlinkRANStatusTransfer */ - { 0, 0, 0 }, /* DownlinkUEAssociatedNRPPaTransport */ - { ngap_gNB_handle_error_indication, 0, 0 }, /* ErrorIndication */ - { 0, 0, 0 }, /* HandoverCancel */ - { 0, 0, 0 }, /* HandoverNotification */ - { 0, 0, 0 }, /* HandoverPreparation */ - { 0, 0, 0 }, /* HandoverResourceAllocation */ - { ngap_gNB_handle_initial_context_request, 0, 0 }, /* InitialContextSetup */ - { 0, 0, 0 }, /* InitialUEMessage */ - { 0, 0, 0 }, /* LocationReportingControl */ - { 0, 0, 0 }, /* LocationReportingFailureIndication */ - { 0, 0, 0 }, /* LocationReport */ - { 0, 0, 0 }, /* NASNonDeliveryIndication */ - { 0, 0, 0 }, /* NGReset */ - { 0, ngap_gNB_handle_ng_setup_response, ngap_gNB_handle_ng_setup_failure }, /* NGSetup */ - { 0, 0, 0 }, /* OverloadStart */ - { 0, 0, 0 }, /* OverloadStop */ - { ngap_gNB_handle_paging, 0, 0 }, /* Paging */ - { 0, ngap_gNB_handle_ng_path_switch_request_ack, ngap_gNB_handle_ng_path_switch_request_failure }, /* PathSwitchRequest */ - { ngap_gNB_handle_pdusession_modify_request, 0, 0 }, /* PDUSessionResourceModify */ - { 0, ngap_gNB_handle_ng_ENDC_pdusession_modification_confirm, 0 }, /* PDUSessionResourceModifyIndication */ - { ngap_gNB_handle_pdusession_release_command, 0, 0 }, /* PDUSessionResourceRelease */ - { ngap_gNB_handle_pdusession_setup_request, 0, 0 }, /* PDUSessionResourceSetup */ - { 0, 0, 0 }, /* PDUSessionResourceNotify */ - { 0, 0, 0 }, /* PrivateMessage */ - { 0, 0, 0 }, /* PWSCancel */ - { 0, 0, 0 }, /* PWSFailureIndication */ - { 0, 0, 0 }, /* PWSRestartIndication */ - { 0, 0, 0 }, /* RANConfigurationUpdate */ - { 0, 0, 0 }, /* RerouteNASRequest */ - { 0, 0, 0 }, /* RRCInactiveTransitionReport */ - { 0, 0, 0 }, /* TraceFailureIndication */ - { ngap_gNB_handle_trace_start, 0, 0 }, /* TraceStart */ - { 0, 0, 0 }, /* UEContextModification */ - { ngap_gNB_handle_ue_context_release_command, 0, 0 }, /* UEContextRelease */ - { 0, 0, 0 }, /* UEContextReleaseRequest */ - { 0, 0, 0 }, /* UERadioCapabilityCheck */ - { 0, 0, 0 }, /* UERadioCapabilityInfoIndication */ - { 0, 0, 0 }, /* UETNLABindingRelease */ - { 0, 0, 0 }, /* UplinkNASTransport */ - { 0, 0, 0 }, /* UplinkNonUEAssociatedNRPPaTransport */ - { 0, 0, 0 }, /* UplinkRANConfigurationTransfer */ - { 0, 0, 0 }, /* UplinkRANStatusTransfer */ - { 0, 0, 0 }, /* UplinkUEAssociatedNRPPaTransport */ - { 0, 0, 0 }, /* WriteReplaceWarning */ - { 0, 0, 0 }, /* SecondaryRATDataUsageReport */ - -}; char *ngap_direction2String(int ngap_dir) { static char *ngap_direction_String[] = { "", /* Nothing */ @@ -209,46 +105,6 @@ void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shut } } -int ngap_gNB_handle_message(uint32_t assoc_id, int32_t stream, - const uint8_t *const data, const uint32_t data_length) { - NGAP_NGAP_PDU_t pdu; - int ret; - DevAssert(data != NULL); - memset(&pdu, 0, sizeof(pdu)); - - if (ngap_gNB_decode_pdu(&pdu, data, data_length) < 0) { - NGAP_ERROR("Failed to decode PDU\n"); - return -1; - } - - /* Checking procedure Code and direction of message */ - if (pdu.choice.initiatingMessage->procedureCode >= sizeof(ngap_messages_callback) / (3 * sizeof( - ngap_message_decoded_callback)) - || (pdu.present > NGAP_NGAP_PDU_PR_unsuccessfulOutcome)) { - NGAP_ERROR("[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", - assoc_id, pdu.choice.initiatingMessage->procedureCode, pdu.present); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); - return -1; - } - - /* No handler present. - * This can mean not implemented or no procedure for gNB (wrong direction). - */ - if (ngap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) { - NGAP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", - assoc_id, pdu.choice.initiatingMessage->procedureCode, - ngap_direction2String(pdu.present - 1)); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); - return -1; - } - - /* Calling the right handler */ - ret = (*ngap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1]) - (assoc_id, stream, &pdu); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); - return ret; -} - static int ngap_gNB_handle_ng_setup_failure(uint32_t assoc_id, uint32_t stream, @@ -378,10 +234,8 @@ int ngap_gNB_handle_ng_setup_response(uint32_t assoc_id, NGAP_ProtocolIE_ID_id_AMFName, true); if (ie) { - amf_desc_p->amf_name = calloc(ie->value.choice.AMFName.size + 1, sizeof(char)); - memcpy(amf_desc_p->amf_name, ie->value.choice.AMFName.buf, - ie->value.choice.AMFName.size); - /* Convert the amf name to a printable string */ + amf_desc_p->amf_name = malloc(ie->value.choice.AMFName.size + 1); + memcpy(amf_desc_p->amf_name, ie->value.choice.AMFName.buf, ie->value.choice.AMFName.size); amf_desc_p->amf_name[ie->value.choice.AMFName.size] = '\0'; } @@ -824,18 +678,12 @@ int ngap_gNB_handle_error_indication(uint32_t assoc_id, return 0; } - -static -int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu) { - +static int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu) +{ int i; - ngap_gNB_amf_data_t *amf_desc_p = NULL; - ngap_gNB_ue_context_t *ue_desc_p = NULL; + ngap_gNB_amf_data_t *amf_desc_p = NULL; NGAP_InitialContextSetupRequest_t *container; NGAP_InitialContextSetupRequestIEs_t *ie; - NGAP_RAN_UE_NGAP_ID_t ran_ue_ngap_id; uint64_t amf_ue_ngap_id; DevAssert(pdu != NULL); container = &pdu->choice.initiatingMessage->value.choice.InitialContextSetupRequest; @@ -850,27 +698,20 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true); - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); - } else { - return -1; - } + asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); /* id-RAN-UE-NGAP-ID */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - ran_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; - - if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance, - ran_ue_ngap_id)) == NULL) { - NGAP_ERROR("[SCTP %d] Received initial context setup request for non " - "existing UE context 0x%06lx\n", assoc_id, - ran_ue_ngap_id); - return -1; - } - } else { + const NGAP_RAN_UE_NGAP_ID_t ran_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; + ngap_gNB_ue_context_t *ue_desc_p = ngap_get_ue_context(ran_ue_ngap_id); + if (!ue_desc_p) { + NGAP_ERROR( + "[SCTP %d] Received initial context setup request for non " + "existing UE context 0x%06lx\n", + assoc_id, + ran_ue_ngap_id); return -1; } @@ -886,8 +727,7 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_INITIAL_CONTEXT_SETUP_REQ); ngap_initial_context_setup_req_t * msg=&NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p); - msg->ue_initial_id = ue_desc_p->ue_initial_id; - ue_desc_p->ue_initial_id = 0; + memset(msg, 0, sizeof(*msg)); msg->gNB_ue_ngap_id = ue_desc_p->gNB_ue_ngap_id; msg->amf_ue_ngap_id = ue_desc_p->amf_ue_ngap_id; /* id-UEAggregateMaximumBitRate */ @@ -908,154 +748,26 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_GUAMI, true); - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ TBCD_TO_MCC_MNC(&ie->value.choice.GUAMI.pLMNIdentity, msg->guami.mcc, msg->guami.mnc, msg->guami.mnc_len); OCTET_STRING_TO_INT8(&ie->value.choice.GUAMI.aMFRegionID, msg->guami.amf_region_id); OCTET_STRING_TO_INT16(&ie->value.choice.GUAMI.aMFSetID, msg->guami.amf_set_id); OCTET_STRING_TO_INT8(&ie->value.choice.GUAMI.aMFPointer, msg->guami.amf_pointer); - } else {/* ie != NULL */ - return -1; - } - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, - NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq, false); + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq, false); + if (ie != NULL) { + msg->nb_of_pdusessions = ie->value.choice.PDUSessionResourceSetupListCxtReq.list.count; - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - msg->nb_of_pdusessions = - ie->value.choice.PDUSessionResourceSetupListCxtReq.list.count; + for (i = 0; i < ie->value.choice.PDUSessionResourceSetupListCxtReq.list.count; i++) { + NGAP_PDUSessionResourceSetupItemCxtReq_t *item_p = ie->value.choice.PDUSessionResourceSetupListCxtReq.list.array[i]; + msg->pdusession_param[i].pdusession_id = item_p->pDUSessionID; - for (i = 0; i < ie->value.choice.PDUSessionResourceSetupListCxtReq.list.count; i++) { - NGAP_PDUSessionResourceSetupItemCxtReq_t *item_p; - asn_dec_rval_t dec_rval; - NGAP_PDUSessionResourceSetupRequestTransfer_t *pdusessionTransfer_p = NULL; - NGAP_PDUSessionResourceSetupRequestTransferIEs_t *pdusessionTransfer_ies = NULL; - - item_p = (NGAP_PDUSessionResourceSetupItemCxtReq_t *)ie->value.choice.PDUSessionResourceSetupListCxtReq.list.array[i]; - msg->pdusession_param[i].pdusession_id = item_p->pDUSessionID; - - if (item_p->nAS_PDU != NULL) { - /* Only copy NAS pdu if present */ - msg->pdusession_param[i].nas_pdu.length = item_p->nAS_PDU->size; - msg->pdusession_param[i].nas_pdu.buffer = - malloc(sizeof(uint8_t) * item_p->nAS_PDU->size); - memcpy(msg->pdusession_param[i].nas_pdu.buffer, - item_p->nAS_PDU->buf, item_p->nAS_PDU->size); - NGAP_DEBUG("Received NAS message with the PDUSESSION setup procedure\n"); - } else { - msg->pdusession_param[i].nas_pdu.length = 0; - msg->pdusession_param[i].nas_pdu.buffer = NULL; + allocCopy(&msg->pdusession_param[i].nas_pdu, *item_p->nAS_PDU); + allocCopy(&msg->pdusession_param[i].pdusessionTransfer, item_p->pDUSessionResourceSetupRequestTransfer); } + } - - dec_rval = aper_decode(NULL, - &asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, - (void **)&pdusessionTransfer_p, - item_p->pDUSessionResourceSetupRequestTransfer.buf, - item_p->pDUSessionResourceSetupRequestTransfer.size, 0, 0); - - if(dec_rval.code != RC_OK) { - NGAP_ERROR("could not decode PDUSessionResourceSetupRequestTransfer\n"); - return -1; - } - - for(int j=0; j< pdusessionTransfer_p->protocolIEs.list.count; j++) { - pdusessionTransfer_ies = pdusessionTransfer_p->protocolIEs.list.array[j]; - switch(pdusessionTransfer_ies->id) { - /* optional PDUSessionAggregateMaximumBitRate */ - case NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate: - break; - - /* mandatory UL-NGU-UP-TNLInformation */ - case NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLInformation: - { - NGAP_GTPTunnel_t *gTPTunnel_p; - gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel; - - /* Set the transport layer address */ - memcpy(msg->pdusession_param[i].upf_addr.buffer, - gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size); - - msg->pdusession_param[i].upf_addr.length = - gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused; - - /* GTP tunnel endpoint ID */ - OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, msg->pdusession_param[i].gtp_teid); - } - - break; - - /* optional AdditionalUL-NGU-UP-TNLInformation */ - case NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation: - break; - - /* optional DataForwardingNotPossible */ - case NGAP_ProtocolIE_ID_id_DataForwardingNotPossible: - break; - - /* mandatory PDUSessionType */ - case NGAP_ProtocolIE_ID_id_PDUSessionType: - msg->pdusession_param[i].upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; - break; - - /* optional SecurityIndication */ - case NGAP_ProtocolIE_ID_id_SecurityIndication: - break; - - /* optional NetworkInstance */ - case NGAP_ProtocolIE_ID_id_NetworkInstance: - break; - - /* mandatory QosFlowSetupRequestList */ - case NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList: - { - NGAP_QosFlowSetupRequestItem_t *qosFlowItem_p; - - NGAP_DEBUG("QosFlowSetupRequestList.list.count %d\n", pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count); - DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count > 0); - DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count <= NGAP_maxnoofQosFlows); - - msg->pdusession_param[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; - - for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; qosIdx++) { - qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.array[qosIdx]; - - /* Set the QOS informations */ - msg->pdusession_param[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; - if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){ - if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){ - msg->pdusession_param[i].qos[qosIdx].fiveQI = - (uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI; - } - } - - msg->pdusession_param[i].qos[qosIdx].allocation_retention_priority.priority_level = - qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP; - msg->pdusession_param[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = - qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionCapability; - msg->pdusession_param[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = - qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionVulnerability; - } - } - - break; - - /* optional CommonNetworkInstance */ - case NGAP_ProtocolIE_ID_id_CommonNetworkInstance: - break; - - default: - NGAP_ERROR("Not found protocolIEs id %ld\n", pdusessionTransfer_ies->id); - return -1; - } - } - - } /* for i... */ - } else {/* ie != NULL */ - NGAP_ERROR("Not found NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq\n"); - } - /* id-AllowedNSSAI */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_AllowedNSSAI, true); @@ -1067,25 +779,8 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, //DevAssert(ie->value.choice.AllowedNSSAI.list.count > 0); //DevAssert(ie->value.choice.AllowedNSSAI.list.count <= NGAP_maxnoofAllowedS_NSSAIs); - if (ie == NULL) { - NGAP_WARN("AllowedNSSAI not present, forging 2 NSSAI\n"); + AssertFatal(ie, "AllowedNSSAI not present, forging 2 NSSAI\n"); - msg->nb_allowed_nssais = 2; - - msg->allowed_nssai[0].sST = 01; - - msg->allowed_nssai[0].sD_flag = 1; - msg->allowed_nssai[0].sD[0] = 01; - msg->allowed_nssai[0].sD[1] = 02; - msg->allowed_nssai[0].sD[2] = 03; - - msg->allowed_nssai[1].sST = 01; - - msg->allowed_nssai[1].sD_flag = 1; - msg->allowed_nssai[1].sD[0] = 00;//11; - msg->allowed_nssai[1].sD[1] = 00;//22; - msg->allowed_nssai[1].sD[2] = 01;//33; - } else { NGAP_INFO("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count); msg->nb_allowed_nssais = ie->value.choice.AllowedNSSAI.list.count; @@ -1096,88 +791,56 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, if(allow_nssai_item_p->s_NSSAI.sD != NULL) { msg->allowed_nssai[i].sD_flag = 1; - msg->allowed_nssai[i].sD[0] = allow_nssai_item_p->s_NSSAI.sD->buf[0]; - msg->allowed_nssai[i].sD[1] = allow_nssai_item_p->s_NSSAI.sD->buf[1]; - msg->allowed_nssai[i].sD[2] = allow_nssai_item_p->s_NSSAI.sD->buf[2]; + memcpy(msg->allowed_nssai[i].sD, allow_nssai_item_p->s_NSSAI.sD, sizeof(msg->allowed_nssai[i].sD)); } } - } - //} else {/* ie != NULL */ - // return -1; - //} /* id-UESecurityCapabilities */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_UESecurityCapabilities, true); - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ msg->security_capabilities.nRencryption_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.nRencryptionAlgorithms); msg->security_capabilities.nRintegrity_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.nRintegrityProtectionAlgorithms); msg->security_capabilities.eUTRAencryption_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.eUTRAencryptionAlgorithms); - msg->security_capabilities.eUTRAintegrity_algorithms = - BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.eUTRAintegrityProtectionAlgorithms); - } else {/* ie != NULL */ - return -1; - } + msg->security_capabilities.eUTRAintegrity_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.eUTRAintegrityProtectionAlgorithms); - /* id-SecurityKey : Copy the security key */ - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, - NGAP_ProtocolIE_ID_id_SecurityKey, true); + /* id-SecurityKey : Copy the security key */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_SecurityKey, true); + memcpy(&msg->security_key, ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - memcpy(&msg->security_key, - ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); - - } else {/* ie != NULL */ - return -1; - } + /* id-MobilityRestrictionList */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_MobilityRestrictionList, false); - /* id-MobilityRestrictionList */ - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, - NGAP_ProtocolIE_ID_id_MobilityRestrictionList, false); - - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - NGAP_MobilityRestrictionList_t *mobility_rest_list_p = NULL; - mobility_rest_list_p = &ie->value.choice.MobilityRestrictionList; + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + NGAP_MobilityRestrictionList_t *mobility_rest_list_p = NULL; + mobility_rest_list_p = &ie->value.choice.MobilityRestrictionList; - msg->mobility_restriction_flag = 1; - TBCD_TO_MCC_MNC(&mobility_rest_list_p->servingPLMN, - msg->mobility_restriction.serving_plmn.mcc, - msg->mobility_restriction.serving_plmn.mnc, - msg->mobility_restriction.serving_plmn.mnc_digit_length); + msg->mobility_restriction_flag = 1; + TBCD_TO_MCC_MNC( + &mobility_rest_list_p->servingPLMN, msg->mobility_restriction.serving_plmn.mcc, msg->mobility_restriction.serving_plmn.mnc, msg->mobility_restriction.serving_plmn.mnc_digit_length); } /* id-NAS-PDU */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_NAS_PDU, false); - - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - if(ie->value.choice.NAS_PDU.size > 0) { - msg->nas_pdu_flag = 1; - msg->nas_pdu.length = ie->value.choice.NAS_PDU.size; - msg->nas_pdu.buffer = malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size); - memcpy(msg->nas_pdu.buffer, - ie->value.choice.NAS_PDU.buf, ie->value.choice.NAS_PDU.size); - } - } + + if (ie) + allocCopy(&msg->nas_pdu, ie->value.choice.NAS_PDU); itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); return 0; } - static int ngap_gNB_handle_ue_context_release_command(uint32_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu) { - - ngap_gNB_amf_data_t *amf_desc_p = NULL; - ngap_gNB_ue_context_t *ue_desc_p = NULL; + ngap_gNB_amf_data_t *amf_desc_p = NULL; MessageDef *message_p = NULL; uint64_t amf_ue_ngap_id; NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; @@ -1195,47 +858,43 @@ int ngap_gNB_handle_ue_context_release_command(uint32_t assoc_id, NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_UEContextReleaseCommand_IEs_t, ie, container, NGAP_ProtocolIE_ID_id_UE_NGAP_IDs, true); - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - switch (ie->value.choice.UE_NGAP_IDs.present) { - case NGAP_UE_NGAP_IDs_PR_uE_NGAP_ID_pair: - gnb_ue_ngap_id = ie->value.choice.UE_NGAP_IDs.choice.uE_NGAP_ID_pair->rAN_UE_NGAP_ID; - asn_INTEGER2ulong(&(ie->value.choice.UE_NGAP_IDs.choice.uE_NGAP_ID_pair->aMF_UE_NGAP_ID), &amf_ue_ngap_id); + switch (ie->value.choice.UE_NGAP_IDs.present) { + case NGAP_UE_NGAP_IDs_PR_uE_NGAP_ID_pair: + gnb_ue_ngap_id = ie->value.choice.UE_NGAP_IDs.choice.uE_NGAP_ID_pair->rAN_UE_NGAP_ID; + asn_INTEGER2ulong(&(ie->value.choice.UE_NGAP_IDs.choice.uE_NGAP_ID_pair->aMF_UE_NGAP_ID), &amf_ue_ngap_id); + ngap_gNB_ue_context_t *ue_desc_p = ngap_get_ue_context(gnb_ue_ngap_id); + if (!ue_desc_p) { + NGAP_ERROR( + "[SCTP %d] Received UE context release command for non " + "existing UE context 0x%06lx\n", + assoc_id, + gnb_ue_ngap_id); + return -1; + } else { + message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_UE_CONTEXT_RELEASE_COMMAND); - if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance, - gnb_ue_ngap_id)) == NULL) { - NGAP_ERROR("[SCTP %d] Received UE context release command for non " - "existing UE context 0x%06lx\n", - assoc_id, - gnb_ue_ngap_id); - return -1; - } else { - message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_UE_CONTEXT_RELEASE_COMMAND); - - if (ue_desc_p->amf_ue_ngap_id == 0) { // case of Detach Request and switch off from RRC_IDLE mode - ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id; - } - - NGAP_UE_CONTEXT_RELEASE_COMMAND(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id; - itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); - return 0; + if (ue_desc_p->amf_ue_ngap_id == 0) { // case of Detach Request and switch off from RRC_IDLE mode + ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id; } - break; + NGAP_UE_CONTEXT_RELEASE_COMMAND(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id; + itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); + return 0; + } + + break; //#warning "TODO mapping amf_ue_ngap_id gnb_ue_ngap_id?" - case NGAP_UE_NGAP_IDs_PR_aMF_UE_NGAP_ID: - asn_INTEGER2ulong(&(ie->value.choice.UE_NGAP_IDs.choice.aMF_UE_NGAP_ID), &amf_ue_ngap_id); - NGAP_ERROR("TO DO mapping amf_ue_ngap_id gnb_ue_ngap_id"); - (void)amf_ue_ngap_id; /* TODO: remove - it's to remove gcc warning about unused var */ + case NGAP_UE_NGAP_IDs_PR_aMF_UE_NGAP_ID: + asn_INTEGER2ulong(&(ie->value.choice.UE_NGAP_IDs.choice.aMF_UE_NGAP_ID), &amf_ue_ngap_id); + NGAP_ERROR("TO DO mapping amf_ue_ngap_id gnb_ue_ngap_id"); + (void)amf_ue_ngap_id; /* TODO: remove - it's to remove gcc warning about unused var */ - case NGAP_UE_NGAP_IDs_PR_NOTHING: - default: - NGAP_ERROR("NGAP_UE_CONTEXT_RELEASE_COMMAND not processed, missing info elements"); - return -1; - } - } else { - return -1; + case NGAP_UE_NGAP_IDs_PR_NOTHING: + default: + NGAP_ERROR("NGAP_UE_CONTEXT_RELEASE_COMMAND not processed, missing info elements"); + return -1; } NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_UEContextReleaseCommand_IEs_t, ie, container, @@ -1253,7 +912,7 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, uint64_t amf_ue_ngap_id; NGAP_RAN_UE_NGAP_ID_t ran_ue_ngap_id; ngap_gNB_amf_data_t *amf_desc_p = NULL; - ngap_gNB_ue_context_t *ue_desc_p = NULL; + NGAP_PDUSessionResourceSetupRequest_t *container; NGAP_PDUSessionResourceSetupRequestIEs_t *ie; DevAssert(pdu != NULL); @@ -1266,40 +925,21 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, } /* id-AMF-UE-NGAP-ID */ - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, - NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true); - - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); - } else { - return -1; - } + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true); + asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); /* id-gNB-UE-NGAP-ID */ - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, - NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); + ran_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - ran_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; - } else { - return -1; - } - - if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance, - ran_ue_ngap_id)) == NULL) { + ngap_gNB_ue_context_t *ue_desc_p = ngap_get_ue_context(ran_ue_ngap_id); + if (!ue_desc_p) { NGAP_ERROR("[SCTP %d] Received pdu session resource setup request for non " "existing UE context 0x%06lx\n", assoc_id, ran_ue_ngap_id); return -1; } - /* Initial context request = UE-related procedure -> stream != 0 */ - // if (stream == 0) { - // NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n", - // assoc_id, stream); - // return -1; - // } - ue_desc_p->rx_stream = stream; if ( ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { @@ -1309,8 +949,7 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, MessageDef * message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_SETUP_REQ); ngap_pdusession_setup_req_t * msg=&NGAP_PDUSESSION_SETUP_REQ(message_p); - msg->ue_initial_id = ue_desc_p->ue_initial_id; - ue_desc_p->ue_initial_id = 0; + memset(msg, 0, sizeof(*msg)); msg->gNB_ue_ngap_id = ue_desc_p->gNB_ue_ngap_id; msg->amf_ue_ngap_id = ue_desc_p->amf_ue_ngap_id; @@ -1325,147 +964,26 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSUReq, true); - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - msg->nb_pdusessions_tosetup = - ie->value.choice.PDUSessionResourceSetupListSUReq.list.count; + msg->nb_pdusessions_tosetup = ie->value.choice.PDUSessionResourceSetupListSUReq.list.count; - for (int i = 0; i < ie->value.choice.PDUSessionResourceSetupListSUReq.list.count; i++) { - NGAP_PDUSessionResourceSetupItemSUReq_t *item_p; - asn_dec_rval_t dec_rval; - NGAP_PDUSessionResourceSetupRequestTransfer_t *pdusessionTransfer_p = NULL; - NGAP_PDUSessionResourceSetupRequestTransferIEs_t *pdusessionTransfer_ies = NULL; + for (int i = 0; i < ie->value.choice.PDUSessionResourceSetupListSUReq.list.count; i++) { + NGAP_PDUSessionResourceSetupItemSUReq_t *item_p = ie->value.choice.PDUSessionResourceSetupListSUReq.list.array[i]; + msg->pdusession_setup_params[i].pdusession_id = item_p->pDUSessionID; - // PDU session ID - item_p = (NGAP_PDUSessionResourceSetupItemSUReq_t *)ie->value.choice.PDUSessionResourceSetupListSUReq.list.array[i]; - msg->pdusession_setup_params[i].pdusession_id = item_p->pDUSessionID; + // S-NSSAI + OCTET_STRING_TO_INT8(&item_p->s_NSSAI.sST, msg->allowed_nssai[i].sST); + if (item_p->s_NSSAI.sD != NULL) { + msg->allowed_nssai[i].sD_flag = 1; + msg->allowed_nssai[i].sD[0] = item_p->s_NSSAI.sD->buf[0]; + msg->allowed_nssai[i].sD[1] = item_p->s_NSSAI.sD->buf[1]; + msg->allowed_nssai[i].sD[2] = item_p->s_NSSAI.sD->buf[2]; + } - // S-NSSAI - OCTET_STRING_TO_INT8(&item_p->s_NSSAI.sST, msg->allowed_nssai[i].sST); - if(item_p->s_NSSAI.sD != NULL) { - msg->allowed_nssai[i].sD_flag = 1; - msg->allowed_nssai[i].sD[0] = item_p->s_NSSAI.sD->buf[0]; - msg->allowed_nssai[i].sD[1] = item_p->s_NSSAI.sD->buf[1]; - msg->allowed_nssai[i].sD[2] = item_p->s_NSSAI.sD->buf[2]; - } - - // check for the NAS PDU - if (item_p->pDUSessionNAS_PDU->size > 0 ) { - msg->pdusession_setup_params[i].nas_pdu.length = item_p->pDUSessionNAS_PDU->size; - msg->pdusession_setup_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionNAS_PDU->size); - memcpy(msg->pdusession_setup_params[i].nas_pdu.buffer, - item_p->pDUSessionNAS_PDU->buf, item_p->pDUSessionNAS_PDU->size); - // NGAP_INFO("received a NAS PDU with size %d (%02x.%02x)\n",msg->pdusession_setup_params[i].nas_pdu.length, item_p->nAS_PDU.buf[0], item_p->nAS_PDU.buf[1]); - } else { - msg->pdusession_setup_params[i].nas_pdu.length = 0; - msg->pdusession_setup_params[i].nas_pdu.buffer = NULL; - NGAP_WARN("NAS PDU is not provided, generate a PDUSESSION_SETUP Failure (TBD) back to AMF \n"); - } - - dec_rval = aper_decode(NULL, - &asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, - (void **)&pdusessionTransfer_p, - item_p->pDUSessionResourceSetupRequestTransfer.buf, - item_p->pDUSessionResourceSetupRequestTransfer.size, 0, 0); - - if(dec_rval.code != RC_OK) { - NGAP_ERROR("could not decode PDUSessionResourceSetupRequestTransfer\n"); - return -1; - } - - for(int j=0; j< pdusessionTransfer_p->protocolIEs.list.count; j++) { - pdusessionTransfer_ies = pdusessionTransfer_p->protocolIEs.list.array[j]; - - switch(pdusessionTransfer_ies->id) { - /* optional PDUSessionAggregateMaximumBitRate */ - case NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate: - break; - - /* mandatory UL-NGU-UP-TNLInformation */ - case NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLInformation: - { - NGAP_GTPTunnel_t *gTPTunnel_p; - gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel; - /* The transport layer address for the IP packets */ - OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, msg->pdusession_setup_params[i].gtp_teid); - msg->pdusession_setup_params[i].upf_addr.length = - gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused; - memcpy(msg->pdusession_setup_params[i].upf_addr.buffer , - gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size); - } - break; - - /* optional AdditionalUL-NGU-UP-TNLInformation */ - case NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation: - break; - - /* optional DataForwardingNotPossible */ - case NGAP_ProtocolIE_ID_id_DataForwardingNotPossible: - break; - - /* mandatory PDUSessionType */ - case NGAP_ProtocolIE_ID_id_PDUSessionType: - msg->pdusession_setup_params[i].upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; - break; - - /* optional SecurityIndication */ - case NGAP_ProtocolIE_ID_id_SecurityIndication: - break; - - /* optional NetworkInstance */ - case NGAP_ProtocolIE_ID_id_NetworkInstance: - break; - - /* mandatory QosFlowSetupRequestList */ - case NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList: - { - NGAP_QosFlowSetupRequestItem_t *qosFlowItem_p; - - NGAP_DEBUG("servedGUAMIs.list.count %d\n", pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count); - DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count > 0); - DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count <= NGAP_maxnoofQosFlows); - - msg->pdusession_setup_params[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; - - for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; qosIdx++){ - qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.array[qosIdx]; - - /* Set the QOS informations */ - msg->pdusession_setup_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; - if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){ - msg->pdusession_setup_params[i].qos[qosIdx].fiveQI_type = non_dynamic; - if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){ - msg->pdusession_setup_params[i].qos[qosIdx].fiveQI = - (uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI; - } - } else if (qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_dynamic5QI) - { - msg->pdusession_setup_params[i].qos[qosIdx].fiveQI_type = dynamic; - } - msg->pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.priority_level = - qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP; - msg->pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = - qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionCapability; - msg->pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = - qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionVulnerability; - } - } - break; - - /* optional CommonNetworkInstance */ - case NGAP_ProtocolIE_ID_id_CommonNetworkInstance: - break; - - default: - NGAP_ERROR("could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id); - return -1; - } - }/* for j... */ - } /* for i... */ - itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); - }else {/* ie == NULL */ - NGAP_ERROR("could not found NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSUReq\n"); - return -1; + allocCopy(&msg->pdusession_setup_params[i].nas_pdu, *item_p->pDUSessionNAS_PDU); + allocCopy(&msg->pdusession_setup_params[i].pdusessionTransfer, item_p->pDUSessionResourceSetupRequestTransfer); } + itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); + return 0; } @@ -1507,64 +1025,47 @@ int ngap_gNB_handle_paging(uint32_t assoc_id, MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PAGING_IND); ngap_paging_ind_t * msg=&NGAP_PAGING_IND(message_p); - - /* convert NGAP_PagingIEs_t to ngap_paging_ind_t */ - /* id-UEIdentityIndexValue : convert UE Identity Index value */ - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container, - NGAP_ProtocolIE_ID_id_UEPagingIdentity, true); + memset(msg, 0, sizeof(*msg)); - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - OCTET_STRING_TO_INT16(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->aMFSetID, msg->ue_paging_identity.s_tmsi.amf_set_id); - OCTET_STRING_TO_INT8(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->aMFPointer, msg->ue_paging_identity.s_tmsi.amf_pointer); - OCTET_STRING_TO_INT32(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->fiveG_TMSI, msg->ue_paging_identity.s_tmsi.m_tmsi); + /* convert NGAP_PagingIEs_t to ngap_paging_ind_t */ + /* id-UEIdentityIndexValue : convert UE Identity Index value */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container, NGAP_ProtocolIE_ID_id_UEPagingIdentity, true); - NGAP_DEBUG("[SCTP %d] Received Paging Identity amf_set_id %d, amf_pointer %d, m_tmsi %d\n", - assoc_id, - msg->ue_paging_identity.s_tmsi.amf_set_id, - msg->ue_paging_identity.s_tmsi.amf_pointer, - msg->ue_paging_identity.s_tmsi.m_tmsi); - } else { - return -1; - } + struct NGAP_FiveG_S_TMSI *fiveG_S_TMSI = ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI; + OCTET_STRING_TO_INT16(&fiveG_S_TMSI->aMFSetID, msg->ue_paging_identity.s_tmsi.amf_set_id); + OCTET_STRING_TO_INT8(&fiveG_S_TMSI->aMFPointer, msg->ue_paging_identity.s_tmsi.amf_pointer); + OCTET_STRING_TO_INT32(&fiveG_S_TMSI->fiveG_TMSI, msg->ue_paging_identity.s_tmsi.m_tmsi); + NGAP_DEBUG("[SCTP %d] Received Paging Identity amf_set_id %d, amf_pointer %d, m_tmsi %d\n", + assoc_id, + msg->ue_paging_identity.s_tmsi.amf_set_id, + msg->ue_paging_identity.s_tmsi.amf_pointer, + msg->ue_paging_identity.s_tmsi.m_tmsi); - msg->paging_drx = NGAP_PAGING_DRX_256; - /* id-pagingDRX */ - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container, - NGAP_ProtocolIE_ID_id_PagingDRX, false); + msg->paging_drx = NGAP_PAGING_DRX_256; + /* id-pagingDRX */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container, NGAP_ProtocolIE_ID_id_PagingDRX, false); - /* optional */ - if (ie) { - msg->paging_drx = ie->value.choice.PagingDRX; - } else { - msg->paging_drx = NGAP_PAGING_DRX_256; - } + /* optional */ + if (ie) { + msg->paging_drx = ie->value.choice.PagingDRX; + } else { + msg->paging_drx = NGAP_PAGING_DRX_256; + } - memset (&msg->plmn_identity[0], 0, sizeof(plmn_identity_t)*256); - memset (&msg->tac[0], 0, sizeof(int16_t)*256); - msg->tai_size = 0; /* id-TAIList */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container, NGAP_ProtocolIE_ID_id_TAIListForPaging, true); - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - NGAP_INFO("[SCTP %d] Received Paging taiList For Paging: count %d\n", assoc_id, ie->value.choice.TAIListForPaging.list.count); + NGAP_INFO("[SCTP %d] Received Paging taiList For Paging: count %d\n", assoc_id, ie->value.choice.TAIListForPaging.list.count); - for (int i = 0; i < ie->value.choice.TAIListForPaging.list.count; i++) { - NGAP_TAIListForPagingItem_t *item_p; - item_p = (NGAP_TAIListForPagingItem_t *)ie->value.choice.TAIListForPaging.list.array[i]; - TBCD_TO_MCC_MNC(&(item_p->tAI.pLMNIdentity), msg->plmn_identity[i].mcc, - msg->plmn_identity[i].mnc, - msg->plmn_identity[i].mnc_digit_length); - OCTET_STRING_TO_INT16(&(item_p->tAI.tAC), msg->tac[i]); - msg->tai_size++; - NGAP_DEBUG("[SCTP %d] Received Paging: MCC %d, MNC %d, TAC %d\n", assoc_id, - msg->plmn_identity[i].mcc, - msg->plmn_identity[i].mnc, - msg->tac[i]); - } - } else { - return -1; + for (int i = 0; i < ie->value.choice.TAIListForPaging.list.count; i++) { + NGAP_TAIListForPagingItem_t *item_p; + item_p = (NGAP_TAIListForPagingItem_t *)ie->value.choice.TAIListForPaging.list.array[i]; + TBCD_TO_MCC_MNC(&(item_p->tAI.pLMNIdentity), msg->plmn_identity[i].mcc, msg->plmn_identity[i].mnc, msg->plmn_identity[i].mnc_digit_length); + OCTET_STRING_TO_INT16(&(item_p->tAI.tAC), msg->tac[i]); + msg->tai_size++; + NGAP_DEBUG("[SCTP %d] Received Paging: MCC %d, MNC %d, TAC %d\n", assoc_id, msg->plmn_identity[i].mcc, msg->plmn_identity[i].mnc, msg->tac[i]); } //paging parameter values @@ -1579,14 +1080,9 @@ int ngap_gNB_handle_paging(uint32_t assoc_id, return 0; } -static -int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id, - uint32_t stream, - NGAP_NGAP_PDU_t *pdu) { - - int i, nb_of_pdusessions_failed; - ngap_gNB_amf_data_t *amf_desc_p = NULL; - ngap_gNB_ue_context_t *ue_desc_p = NULL; +static int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu) +{ + ngap_gNB_amf_data_t *amf_desc_p = NULL; NGAP_PDUSessionResourceModifyRequest_t *container; NGAP_PDUSessionResourceModifyRequestIEs_t *ie; NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; @@ -1614,184 +1110,69 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id, NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ gnb_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; - } else { - return -1; - } - - if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance, - gnb_ue_ngap_id)) == NULL) { - NGAP_ERROR("[SCTP %d] Received PDUSession Resource modify request for non " - "existing UE context 0x%08lx\n", assoc_id, - gnb_ue_ngap_id); - return -1; - } + ngap_gNB_ue_context_t *ue_desc_p = ngap_get_ue_context(gnb_ue_ngap_id); + if (!ue_desc_p) { + NGAP_ERROR( + "[SCTP %d] Received PDUSession Resource modify request for non " + "existing UE context 0x%08lx\n", + assoc_id, + gnb_ue_ngap_id); + return -1; + } ue_desc_p->rx_stream = stream; + /* id-PDUSessionResourceModifyListModReq */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModReq, true); if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { NGAP_WARN("UE context amf_ue_ngap_id is different form that of the message (%ld != %ld)", (uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id); MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP); ngap_pdusession_modify_resp_t* msg=&NGAP_PDUSESSION_MODIFY_RESP(message_p); + memset(msg, 0, sizeof(*msg)); msg->gNB_ue_ngap_id = gnb_ue_ngap_id; - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container, - NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModReq, true); - - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - for(nb_of_pdusessions_failed = 0; nb_of_pdusessions_failed < ie->value.choice.PDUSessionResourceModifyListModReq.list.count; nb_of_pdusessions_failed++) { + for (int nb_of_pdusessions_failed = 0; nb_of_pdusessions_failed < ie->value.choice.PDUSessionResourceModifyListModReq.list.count; nb_of_pdusessions_failed++) { NGAP_PDUSessionResourceModifyItemModReq_t *item_p; item_p = (NGAP_PDUSessionResourceModifyItemModReq_t *)ie->value.choice.PDUSessionResourceModifyListModReq.list.array[nb_of_pdusessions_failed]; - - msg->pdusessions_failed[nb_of_pdusessions_failed].pdusession_id = item_p->pDUSessionID; - msg->pdusessions_failed[nb_of_pdusessions_failed].cause = NGAP_CAUSE_RADIO_NETWORK; - msg->pdusessions_failed[nb_of_pdusessions_failed].cause_value = NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID; + pdusession_failed_t *tmp = &msg->pdusessions_failed[nb_of_pdusessions_failed]; + tmp->pdusession_id = item_p->pDUSessionID; + tmp->cause = NGAP_CAUSE_RADIO_NETWORK; + tmp->cause_value = NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID; } - } else { - return -1; - } - - msg->nb_of_pdusessions_failed = nb_of_pdusessions_failed; + msg->nb_of_pdusessions_failed = ie->value.choice.PDUSessionResourceModifyListModReq.list.count; ngap_gNB_pdusession_modify_resp(amf_desc_p->ngap_gNB_instance->instance,msg); - itti_free(TASK_RRC_GNB,message_p); - message_p = NULL; + itti_free(TASK_RRC_GNB, message_p); return -1; } MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_MODIFY_REQ); ngap_pdusession_modify_req_t * msg=&NGAP_PDUSESSION_MODIFY_REQ(message_p); - msg->ue_initial_id = ue_desc_p->ue_initial_id; + memset(msg, 0, sizeof(*msg)); msg->amf_ue_ngap_id = amf_ue_ngap_id; - msg->gNB_ue_ngap_id = gnb_ue_ngap_id; - /* id-PDUSessionResourceModifyListModReq */ - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container, - NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModReq, true); + msg->gNB_ue_ngap_id = gnb_ue_ngap_id; - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - msg->nb_pdusessions_tomodify = - ie->value.choice.PDUSessionResourceModifyListModReq.list.count; + msg->nb_pdusessions_tomodify = ie->value.choice.PDUSessionResourceModifyListModReq.list.count; - for (i = 0; i < ie->value.choice.PDUSessionResourceModifyListModReq.list.count; i++) { - NGAP_PDUSessionResourceModifyItemModReq_t *item_p; - asn_dec_rval_t dec_rval; - NGAP_PDUSessionResourceModifyRequestTransfer_t *pdusessionTransfer_p = NULL; - NGAP_PDUSessionResourceModifyRequestTransferIEs_t *pdusessionTransfer_ies = NULL; - - item_p = (NGAP_PDUSessionResourceModifyItemModReq_t *)ie->value.choice.PDUSessionResourceModifyListModReq.list.array[i]; - - msg->pdusession_modify_params[i].pdusession_id = item_p->pDUSessionID; + for (int i = 0; i < ie->value.choice.PDUSessionResourceModifyListModReq.list.count; i++) { + NGAP_PDUSessionResourceModifyItemModReq_t *item_p = ie->value.choice.PDUSessionResourceModifyListModReq.list.array[i]; - // check for the NAS PDU - if (item_p->nAS_PDU != NULL && item_p->nAS_PDU->size > 0 ) { - msg->pdusession_modify_params[i].nas_pdu.length = item_p->nAS_PDU->size; - msg->pdusession_modify_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU->size); - memcpy(msg->pdusession_modify_params[i].nas_pdu.buffer, - item_p->nAS_PDU->buf, item_p->nAS_PDU->size); - } else { - msg->pdusession_modify_params[i].nas_pdu.length = 0; - msg->pdusession_modify_params[i].nas_pdu.buffer = NULL; - continue; - } + msg->pdusession_modify_params[i].pdusession_id = item_p->pDUSessionID; - dec_rval = aper_decode(NULL, - &asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, - (void **)&pdusessionTransfer_p, - item_p->pDUSessionResourceModifyRequestTransfer.buf, - item_p->pDUSessionResourceModifyRequestTransfer.size, 0, 0); - - if(dec_rval.code != RC_OK) { - NGAP_ERROR("could not decode PDUSessionResourceModifyRequestTransfer\n"); - return -1; - } - - for(int j=0; j< pdusessionTransfer_p->protocolIEs.list.count; j++) { - pdusessionTransfer_ies = pdusessionTransfer_p->protocolIEs.list.array[j]; - switch(pdusessionTransfer_ies->id) { - /* optional PDUSessionAggregateMaximumBitRate */ - case NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate: - // TODO - NGAP_ERROR("Cant' handle NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate\n"); - break; - - /* optional UL-NGU-UP-TNLModifyList */ - case NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLModifyList: - // TODO - NGAP_ERROR("Cant' handle NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLModifyList\n"); - break; - - /* optional NetworkInstance */ - case NGAP_ProtocolIE_ID_id_NetworkInstance: - // TODO - NGAP_ERROR("Cant' handle NGAP_ProtocolIE_ID_id_NetworkInstance\n"); - break; - - /* optional QosFlowAddOrModifyRequestList */ - case NGAP_ProtocolIE_ID_id_QosFlowAddOrModifyRequestList: - { - NGAP_QosFlowAddOrModifyRequestItem_t *qosFlowItem_p; - - NGAP_DEBUG("QosFlowAddOrModifyRequestList.list.count %d\n", pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count); - DevAssert(pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count > 0); - DevAssert(pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count <= NGAP_maxnoofQosFlows); - - msg->pdusession_modify_params[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count; - - for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count; qosIdx++) { - qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.array[qosIdx]; - - /* Set the QOS informations */ - msg->pdusession_modify_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; - if(qosFlowItem_p->qosFlowLevelQosParameters) { - if (qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI) { - msg->pdusession_modify_params[i].qos[qosIdx].fiveQI = - qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics.choice.nonDynamic5QI->fiveQI; - } else if (qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics.present == NGAP_QosCharacteristics_PR_dynamic5QI) { - // TODO - } - msg->pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.priority_level = - qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.priorityLevelARP; - msg->pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = - qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.pre_emptionCapability; - msg->pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = - qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.pre_emptionVulnerability; - } - } - } - break; - - /* optional QosFlowToReleaseList */ - case NGAP_ProtocolIE_ID_id_QosFlowToReleaseList: - // TODO - NGAP_ERROR("Cant' handle NGAP_ProtocolIE_ID_id_QosFlowToReleaseList\n"); - break; - - /* optional AdditionalUL-NGU-UP-TNLInformation */ - case NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation: - // TODO - NGAP_ERROR("Cant' handle NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation\n"); - break; - - /* optional CommonNetworkInstance */ - case NGAP_ProtocolIE_ID_id_CommonNetworkInstance: - // TODO - NGAP_ERROR("Cant' handle NGAP_ProtocolIE_ID_id_CommonNetworkInstance\n"); - break; - - default: - NGAP_ERROR("could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id); - return -1; - } - } + // check for the NAS PDU + if (item_p->nAS_PDU != NULL && item_p->nAS_PDU->size > 0) { + allocCopy(&msg->pdusession_modify_params[i].nas_pdu, *item_p->nAS_PDU); + allocCopy(&msg->pdusession_modify_params[i].pdusessionTransfer, item_p->pDUSessionResourceModifyRequestTransfer); + } else { + LOG_W(NGAP, "received pdu session modify with void content for UE %u, pdu session %lu\n", msg->gNB_ue_ngap_id, item_p->pDUSessionID); + continue; } - - itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); - } else { /* of if (ie != NULL)*/ - return -1; } + itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); return 0; } + // handle pdu session release command and send it to rrc_end static int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id, @@ -1799,8 +1180,7 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id, NGAP_NGAP_PDU_t *pdu) { int i; - ngap_gNB_amf_data_t *amf_desc_p = NULL; - ngap_gNB_ue_context_t *ue_desc_p = NULL; + ngap_gNB_amf_data_t *amf_desc_p = NULL; NGAP_PDUSessionResourceReleaseCommand_t *container; NGAP_PDUSessionResourceReleaseCommandIEs_t *ie; NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; @@ -1834,20 +1214,13 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id, return -1; } - if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance, - gnb_ue_ngap_id)) == NULL) { + ngap_gNB_ue_context_t *ue_desc_p = ngap_get_ue_context(gnb_ue_ngap_id); + if (!ue_desc_p) { NGAP_ERROR("[SCTP %d] Received PDUSession Resource release command for non existing UE context 0x%08lx\n", assoc_id, ie->value.choice.RAN_UE_NGAP_ID); return -1; } - /* Initial context request = UE-related procedure -> stream != 0 */ - // if (stream == 0) { - // NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n", - // assoc_id, stream); - // return -1; - // } - ue_desc_p->rx_stream = stream; if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { @@ -1859,6 +1232,7 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id, assoc_id, gnb_ue_ngap_id, amf_ue_ngap_id); MessageDef * message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_RELEASE_COMMAND); ngap_pdusession_release_command_t * msg=&NGAP_PDUSESSION_RELEASE_COMMAND(message_p); + memset(msg, 0, sizeof(*msg)); msg->gNB_ue_ngap_id = gnb_ue_ngap_id; msg->amf_ue_ngap_id = amf_ue_ngap_id; @@ -1866,44 +1240,20 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id, NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceReleaseCommandIEs_t, ie, container, NGAP_ProtocolIE_ID_id_NAS_PDU, false); - if(ie && ie->value.choice.NAS_PDU.size > 0) { - msg->nas_pdu.length = ie->value.choice.NAS_PDU.size; - msg->nas_pdu.buffer = malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size); - memcpy(msg->nas_pdu.buffer, - ie->value.choice.NAS_PDU.buf, - ie->value.choice.NAS_PDU.size); - } else { - msg->nas_pdu.length = 0; - msg->nas_pdu.buffer = NULL; - } + if (ie) + allocCopy(&msg->nas_pdu, ie->value.choice.NAS_PDU); /* id-PDUSessionResourceToReleaseListRelCmd */ NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceReleaseCommandIEs_t, ie, container, NGAP_ProtocolIE_ID_id_PDUSessionResourceToReleaseListRelCmd, true); - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - msg->nb_pdusessions_torelease = ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; + msg->nb_pdusessions_torelease = ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; - for (i = 0; i < ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; i++) { - NGAP_PDUSessionResourceToReleaseItemRelCmd_t *item_p; - item_p = (NGAP_PDUSessionResourceToReleaseItemRelCmd_t *)ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.array[i]; - - msg->pdusession_release_params[i].pdusession_id = item_p->pDUSessionID; - if(item_p->pDUSessionResourceReleaseCommandTransfer.size > 0) { - msg->pdusession_release_params[i].transfer_length = item_p->pDUSessionResourceReleaseCommandTransfer.size; - msg->pdusession_release_params[i].transfer_buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionResourceReleaseCommandTransfer.size); - memcpy(msg->pdusession_release_params[i].transfer_buffer, - item_p->pDUSessionResourceReleaseCommandTransfer.buf, - item_p->pDUSessionResourceReleaseCommandTransfer.size); - }else { - msg->pdusession_release_params[i].transfer_length = 0; - msg->pdusession_release_params[i].transfer_buffer = NULL; - NGAP_ERROR("[NGAP] Received pdu session release command for pDUSessionResourceReleaseCommandTransfer is NULL!\n"); - } - NGAP_DEBUG("[NGAP] Received pdu session release command for pDUSessionID id %ld\n", item_p->pDUSessionID); - } - } else { - return -1; + for (i = 0; i < ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; i++) { + NGAP_PDUSessionResourceToReleaseItemRelCmd_t *item_p; + item_p = ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.array[i]; + msg->pdusession_release_params[i].pdusession_id = item_p->pDUSessionID; + allocCopy(&msg->pdusession_release_params[i].data, item_p->pDUSessionResourceReleaseCommandTransfer); } itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); @@ -1937,3 +1287,94 @@ int ngap_gNB_handle_ng_ENDC_pdusession_modification_confirm(uint32_t return 0; } +/* Handlers matrix. Only gNB related procedure present here */ +ngap_message_decoded_callback ngap_messages_callback[][3] = { + {0, 0, 0}, /* AMFConfigurationUpdate */ + {0, 0, 0}, /* AMFStatusIndication */ + {0, 0, 0}, /* CellTrafficTrace */ + {ngap_gNB_handle_deactivate_trace, 0, 0}, /* DeactivateTrace */ + {ngap_gNB_handle_nas_downlink, 0, 0}, /* DownlinkNASTransport */ + {0, 0, 0}, /* DownlinkNonUEAssociatedNRPPaTransport */ + {0, 0, 0}, /* DownlinkRANConfigurationTransfer */ + {0, 0, 0}, /* DownlinkRANStatusTransfer */ + {0, 0, 0}, /* DownlinkUEAssociatedNRPPaTransport */ + {ngap_gNB_handle_error_indication, 0, 0}, /* ErrorIndication */ + {0, 0, 0}, /* HandoverCancel */ + {0, 0, 0}, /* HandoverNotification */ + {0, 0, 0}, /* HandoverPreparation */ + {0, 0, 0}, /* HandoverResourceAllocation */ + {ngap_gNB_handle_initial_context_request, 0, 0}, /* InitialContextSetup */ + {0, 0, 0}, /* InitialUEMessage */ + {0, 0, 0}, /* LocationReportingControl */ + {0, 0, 0}, /* LocationReportingFailureIndication */ + {0, 0, 0}, /* LocationReport */ + {0, 0, 0}, /* NASNonDeliveryIndication */ + {0, 0, 0}, /* NGReset */ + {0, ngap_gNB_handle_ng_setup_response, ngap_gNB_handle_ng_setup_failure}, /* NGSetup */ + {0, 0, 0}, /* OverloadStart */ + {0, 0, 0}, /* OverloadStop */ + {ngap_gNB_handle_paging, 0, 0}, /* Paging */ + {0, ngap_gNB_handle_ng_path_switch_request_ack, ngap_gNB_handle_ng_path_switch_request_failure}, /* PathSwitchRequest */ + {ngap_gNB_handle_pdusession_modify_request, 0, 0}, /* PDUSessionResourceModify */ + {0, ngap_gNB_handle_ng_ENDC_pdusession_modification_confirm, 0}, /* PDUSessionResourceModifyIndication */ + {ngap_gNB_handle_pdusession_release_command, 0, 0}, /* PDUSessionResourceRelease */ + {ngap_gNB_handle_pdusession_setup_request, 0, 0}, /* PDUSessionResourceSetup */ + {0, 0, 0}, /* PDUSessionResourceNotify */ + {0, 0, 0}, /* PrivateMessage */ + {0, 0, 0}, /* PWSCancel */ + {0, 0, 0}, /* PWSFailureIndication */ + {0, 0, 0}, /* PWSRestartIndication */ + {0, 0, 0}, /* RANConfigurationUpdate */ + {0, 0, 0}, /* RerouteNASRequest */ + {0, 0, 0}, /* RRCInactiveTransitionReport */ + {0, 0, 0}, /* TraceFailureIndication */ + {ngap_gNB_handle_trace_start, 0, 0}, /* TraceStart */ + {0, 0, 0}, /* UEContextModification */ + {ngap_gNB_handle_ue_context_release_command, 0, 0}, /* UEContextRelease */ + {0, 0, 0}, /* UEContextReleaseRequest */ + {0, 0, 0}, /* UERadioCapabilityCheck */ + {0, 0, 0}, /* UERadioCapabilityInfoIndication */ + {0, 0, 0}, /* UETNLABindingRelease */ + {0, 0, 0}, /* UplinkNASTransport */ + {0, 0, 0}, /* UplinkNonUEAssociatedNRPPaTransport */ + {0, 0, 0}, /* UplinkRANConfigurationTransfer */ + {0, 0, 0}, /* UplinkRANStatusTransfer */ + {0, 0, 0}, /* UplinkUEAssociatedNRPPaTransport */ + {0, 0, 0}, /* WriteReplaceWarning */ + {0, 0, 0}, /* SecondaryRATDataUsageReport */ + +}; + +int ngap_gNB_handle_message(uint32_t assoc_id, int32_t stream, const uint8_t *const data, const uint32_t data_length) +{ + NGAP_NGAP_PDU_t pdu; + int ret; + DevAssert(data != NULL); + memset(&pdu, 0, sizeof(pdu)); + + if (ngap_gNB_decode_pdu(&pdu, data, data_length) < 0) { + NGAP_ERROR("Failed to decode PDU\n"); + return -1; + } + + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage->procedureCode >= sizeof(ngap_messages_callback) / (3 * sizeof(ngap_message_decoded_callback)) || (pdu.present > NGAP_NGAP_PDU_PR_unsuccessfulOutcome)) { + NGAP_ERROR("[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", assoc_id, pdu.choice.initiatingMessage->procedureCode, pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for gNB (wrong direction). + */ + if (ngap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) { + NGAP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", assoc_id, pdu.choice.initiatingMessage->procedureCode, ngap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return -1; + } + + /* Calling the right handler */ + ret = (*ngap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])(assoc_id, stream, &pdu); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return ret; +} diff --git a/openair3/NGAP/ngap_gNB_itti_messaging.c b/openair3/NGAP/ngap_gNB_itti_messaging.c index ab10fa46e2..87b4ba4c73 100644 --- a/openair3/NGAP/ngap_gNB_itti_messaging.c +++ b/openair3/NGAP/ngap_gNB_itti_messaging.c @@ -44,16 +44,12 @@ void ngap_gNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin sctp_data_req->assoc_id = assoc_id; sctp_data_req->buffer = buffer; sctp_data_req->buffer_length = buffer_length; - sctp_data_req->stream = stream; + sctp_data_req->stream = stream; itti_send_msg_to_task(TASK_SCTP, instance, message_p); } -void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, - uint16_t ue_initial_id, - uint32_t gNB_ue_ngap_id, - uint8_t *nas_pdu, - uint32_t nas_pdu_length) +void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ngap_id, uint8_t *nas_pdu, uint32_t nas_pdu_length) { MessageDef *message_p; ngap_downlink_nas_t *ngap_downlink_nas; @@ -62,7 +58,6 @@ void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, ngap_downlink_nas = &message_p->ittiMsg.ngap_downlink_nas; - ngap_downlink_nas->ue_initial_id = ue_initial_id; ngap_downlink_nas->gNB_ue_ngap_id = gNB_ue_ngap_id; ngap_downlink_nas->nas_pdu.buffer = malloc(sizeof(uint8_t) * nas_pdu_length); memcpy(ngap_downlink_nas->nas_pdu.buffer, nas_pdu, nas_pdu_length); diff --git a/openair3/NGAP/ngap_gNB_itti_messaging.h b/openair3/NGAP/ngap_gNB_itti_messaging.h index 94d4058178..08224a27f5 100644 --- a/openair3/NGAP/ngap_gNB_itti_messaging.h +++ b/openair3/NGAP/ngap_gNB_itti_messaging.h @@ -33,11 +33,7 @@ void ngap_gNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, uint32_t buffer_length, uint16_t stream); -void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, - uint16_t ue_initial_id, - uint32_t gNB_ue_ngap_id, - uint8_t *nas_pdu, - uint32_t nas_pdu_length); +void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ngap_id, uint8_t *nas_pdu, uint32_t nas_pdu_length); void ngap_gNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id); diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 7c5fb453f2..fdbe6ce0f9 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -49,73 +49,80 @@ #include "ngap_gNB_nas_procedures.h" #include "ngap_gNB_management_procedures.h" +static void allocCopy(OCTET_STRING_t *out, ngap_pdu_t in) +{ + if (in.length) { + out->buf = malloc(in.length); + memcpy(out->buf, in.buffer, in.length); + } + out->size = in.length; +} + +static void allocAddrCopy(BIT_STRING_t *out, ngap_transport_layer_addr_t in) +{ + if (in.length) { + out->buf = malloc(in.length); + memcpy(out->buf, in.buffer, in.length); + out->size = in.length; + out->bits_unused = 0; + } +} + //------------------------------------------------------------------------------ -int ngap_gNB_handle_nas_first_req( - instance_t instance, ngap_nas_first_req_t *ngap_nas_first_req_p) +int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEfirstReq) //------------------------------------------------------------------------------ { ngap_gNB_instance_t *instance_p = NULL; - struct ngap_gNB_amf_data_s *amf_desc_p = NULL; - struct ngap_gNB_ue_context_s *ue_desc_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_InitialUEMessage_t *out; - NGAP_InitialUEMessage_IEs_t *ie; - NGAP_UserLocationInformationNR_t *userinfo_nr_p = NULL; + struct ngap_gNB_amf_data_s *amf_desc_p = NULL; + NGAP_NGAP_PDU_t pdu; uint8_t *buffer = NULL; uint32_t length = 0; - DevAssert(ngap_nas_first_req_p != NULL); + DevAssert(UEfirstReq != NULL); /* Retrieve the NGAP gNB instance associated with Mod_id */ instance_p = ngap_gNB_get_instance(instance); DevAssert(instance_p != NULL); memset(&pdu, 0, sizeof(pdu)); pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t)); - pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_InitialUEMessage; - pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; - pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_InitialUEMessage; - out = &pdu.choice.initiatingMessage->value.choice.InitialUEMessage; + asn1cCalloc(pdu.choice.initiatingMessage, head); + head->procedureCode = NGAP_ProcedureCode_id_InitialUEMessage; + head->criticality = NGAP_Criticality_ignore; + head->value.present = NGAP_InitiatingMessage__value_PR_InitialUEMessage; + NGAP_InitialUEMessage_t *out = &head->value.choice.InitialUEMessage; /* Select the AMF corresponding to the provided GUAMI. */ //TODO have not be test. it's should be test - if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_guami) { - amf_desc_p = ngap_gNB_nnsf_select_amf_by_guami( - instance_p, - ngap_nas_first_req_p->establishment_cause, - ngap_nas_first_req_p->ue_identity.guami); + if (UEfirstReq->ue_identity.presenceMask & NGAP_UE_IDENTITIES_guami) { + amf_desc_p = ngap_gNB_nnsf_select_amf_by_guami(instance_p, UEfirstReq->establishment_cause, UEfirstReq->ue_identity.guami); if (amf_desc_p) { - NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through GUAMI MCC %d MNC %d AMFRI %d AMFSI %d AMFPT %d\n", - instance, - amf_desc_p->amf_name, - amf_desc_p->assoc_id, - ngap_nas_first_req_p->ue_identity.guami.mcc, - ngap_nas_first_req_p->ue_identity.guami.mnc, - ngap_nas_first_req_p->ue_identity.guami.amf_region_id, - ngap_nas_first_req_p->ue_identity.guami.amf_set_id, - ngap_nas_first_req_p->ue_identity.guami.amf_pointer); + NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through GUAMI MCC %d MNC %d AMFRI %d AMFSI %d AMFPT %d\n", + instance, + amf_desc_p->amf_name, + amf_desc_p->assoc_id, + UEfirstReq->ue_identity.guami.mcc, + UEfirstReq->ue_identity.guami.mnc, + UEfirstReq->ue_identity.guami.amf_region_id, + UEfirstReq->ue_identity.guami.amf_set_id, + UEfirstReq->ue_identity.guami.amf_pointer); } } if (amf_desc_p == NULL) { /* Select the AMF corresponding to the provided s-TMSI. */ //TODO have not be test. it's should be test - if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_FiveG_s_tmsi) { - amf_desc_p = ngap_gNB_nnsf_select_amf_by_amf_setid( - instance_p, - ngap_nas_first_req_p->establishment_cause, - ngap_nas_first_req_p->selected_plmn_identity, - ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id); + if (UEfirstReq->ue_identity.presenceMask & NGAP_UE_IDENTITIES_FiveG_s_tmsi) { + amf_desc_p = ngap_gNB_nnsf_select_amf_by_amf_setid(instance_p, UEfirstReq->establishment_cause, UEfirstReq->selected_plmn_identity, UEfirstReq->ue_identity.s_tmsi.amf_set_id); - if (amf_desc_p) { - NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through S-TMSI AMFSI %d and selected PLMN Identity index %d MCC %d MNC %d\n", - instance, - amf_desc_p->amf_name, - amf_desc_p->assoc_id, - ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id, - ngap_nas_first_req_p->selected_plmn_identity, - instance_p->mcc[ngap_nas_first_req_p->selected_plmn_identity], - instance_p->mnc[ngap_nas_first_req_p->selected_plmn_identity]); - } + if (amf_desc_p) { + NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through S-TMSI AMFSI %d and selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + amf_desc_p->amf_name, + amf_desc_p->assoc_id, + UEfirstReq->ue_identity.s_tmsi.amf_set_id, + UEfirstReq->selected_plmn_identity, + instance_p->mcc[UEfirstReq->selected_plmn_identity], + instance_p->mnc[UEfirstReq->selected_plmn_identity]); + } } } @@ -123,19 +130,16 @@ int ngap_gNB_handle_nas_first_req( /* Select AMF based on the selected PLMN identity, received through RRC * Connection Setup Complete */ //TODO have not be test. it's should be test - amf_desc_p = ngap_gNB_nnsf_select_amf_by_plmn_id( - instance_p, - ngap_nas_first_req_p->establishment_cause, - ngap_nas_first_req_p->selected_plmn_identity); + amf_desc_p = ngap_gNB_nnsf_select_amf_by_plmn_id(instance_p, UEfirstReq->establishment_cause, UEfirstReq->selected_plmn_identity); if (amf_desc_p) { - NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", - instance, - amf_desc_p->amf_name, - amf_desc_p->assoc_id, - ngap_nas_first_req_p->selected_plmn_identity, - instance_p->mcc[ngap_nas_first_req_p->selected_plmn_identity], - instance_p->mnc[ngap_nas_first_req_p->selected_plmn_identity]); + NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + amf_desc_p->amf_name, + amf_desc_p->assoc_id, + UEfirstReq->selected_plmn_identity, + instance_p->mcc[UEfirstReq->selected_plmn_identity], + instance_p->mnc[UEfirstReq->selected_plmn_identity]); } } @@ -145,15 +149,10 @@ int ngap_gNB_handle_nas_first_req( * identity, selects the AMF with the highest capacity. */ //TODO have not be test. it's should be test - amf_desc_p = ngap_gNB_nnsf_select_amf( - instance_p, - ngap_nas_first_req_p->establishment_cause); + amf_desc_p = ngap_gNB_nnsf_select_amf(instance_p, UEfirstReq->establishment_cause); if (amf_desc_p) { - NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through highest relative capacity\n", - instance, - amf_desc_p->amf_name, - amf_desc_p->assoc_id); + NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through highest relative capacity\n", instance, amf_desc_p->amf_name, amf_desc_p->assoc_id); } } @@ -170,120 +169,94 @@ int ngap_gNB_handle_nas_first_req( /* The gNB should allocate a unique gNB UE NGAP ID for this UE. The value * will be used for the duration of the connectivity. */ - ue_desc_p = ngap_gNB_allocate_new_UE_context(); + struct ngap_gNB_ue_context_s *ue_desc_p = calloc(1, sizeof(*ue_desc_p)); DevAssert(ue_desc_p != NULL); /* Keep a reference to the selected AMF */ ue_desc_p->amf_ref = amf_desc_p; - ue_desc_p->ue_initial_id = ngap_nas_first_req_p->ue_initial_id; + ue_desc_p->gNB_ue_ngap_id = UEfirstReq->gNB_ue_ngap_id; ue_desc_p->gNB_instance = instance_p; - ue_desc_p->selected_plmn_identity = ngap_nas_first_req_p->selected_plmn_identity; + ue_desc_p->selected_plmn_identity = UEfirstReq->selected_plmn_identity; - do { - struct ngap_gNB_ue_context_s *collision_p; - /* Peek a random value for the gNB_ue_ngap_id */ - ue_desc_p->gNB_ue_ngap_id = (random() + random()) & 0xffffffff; - - if ((collision_p = RB_INSERT(ngap_ue_map, &instance_p->ngap_ue_head, ue_desc_p)) - == NULL) { - NGAP_DEBUG("Found usable gNB_ue_ngap_id: 0x%08x %u(10)\n", - ue_desc_p->gNB_ue_ngap_id, - ue_desc_p->gNB_ue_ngap_id); - /* Break the loop as the id is not already used by another UE */ - break; - } - } while(1); + // insert in master table + ngap_store_ue_context(ue_desc_p); /* mandatory */ - ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = ue_desc_p->gNB_ue_ngap_id; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialUEMessage_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_desc_p->gNB_ue_ngap_id; + } /* mandatory */ - ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_NAS_PDU; -#if 1 - ie->value.choice.NAS_PDU.buf = ngap_nas_first_req_p->nas_pdu.buffer; -#else - ie->value.choice.NAS_PDU.buf = malloc(ngap_nas_first_req_p->nas_pdu.length); - memcpy(ie->value.choice.NAS_PDU.buf, - ngap_nas_first_req_p->nas_pdu.buffer, - ngap_nas_first_req_p->nas_pdu.length); -#endif - ie->value.choice.NAS_PDU.size = ngap_nas_first_req_p->nas_pdu.length; - asn1cSeqAdd(&out->protocolIEs.list, ie); - + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialUEMessage_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_NAS_PDU; + allocCopy(&ie->value.choice.NAS_PDU, UEfirstReq->nas_pdu); + } + /* mandatory */ - ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_UserLocationInformation; + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialUEMessage_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_UserLocationInformation; - ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; + ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; - ie->value.choice.UserLocationInformation.choice.userLocationInformationNR = - CALLOC(1, sizeof(*ie->value.choice.UserLocationInformation.choice.userLocationInformationNR)); - userinfo_nr_p = ie->value.choice.UserLocationInformation.choice.userLocationInformationNR; + asn1cCalloc(ie->value.choice.UserLocationInformation.choice.userLocationInformationNR, userinfo_nr_p); - /* Set nRCellIdentity. default userLocationInformationNR */ - MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id, - 0, // Cell ID - &userinfo_nr_p->nR_CGI.nRCellIdentity); - MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], - instance_p->mnc[ue_desc_p->selected_plmn_identity], - instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], - &userinfo_nr_p->nR_CGI.pLMNIdentity); - - /* Set TAI */ - INT24_TO_OCTET_STRING(instance_p->tac, &userinfo_nr_p->tAI.tAC); - MCC_MNC_TO_PLMNID(instance_p->mcc[ue_desc_p->selected_plmn_identity], + /* Set nRCellIdentity. default userLocationInformationNR */ + MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id, + 0, // Cell ID + &userinfo_nr_p->nR_CGI.nRCellIdentity); + MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], instance_p->mnc[ue_desc_p->selected_plmn_identity], instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], - &userinfo_nr_p->tAI.pLMNIdentity); - - asn1cSeqAdd(&out->protocolIEs.list, ie); + &userinfo_nr_p->nR_CGI.pLMNIdentity); + /* Set TAI */ + INT24_TO_OCTET_STRING(instance_p->tac, &userinfo_nr_p->tAI.tAC); + MCC_MNC_TO_PLMNID(instance_p->mcc[ue_desc_p->selected_plmn_identity], + instance_p->mnc[ue_desc_p->selected_plmn_identity], + instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], + &userinfo_nr_p->tAI.pLMNIdentity); + } /* Set the establishment cause according to those provided by RRC */ - DevCheck(ngap_nas_first_req_p->establishment_cause < NGAP_RRC_CAUSE_LAST, - ngap_nas_first_req_p->establishment_cause, NGAP_RRC_CAUSE_LAST, 0); - + DevCheck(UEfirstReq->establishment_cause < NGAP_RRC_CAUSE_LAST, UEfirstReq->establishment_cause, NGAP_RRC_CAUSE_LAST, 0); + /* mandatory */ - ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RRCEstablishmentCause; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RRCEstablishmentCause; - ie->value.choice.RRCEstablishmentCause = ngap_nas_first_req_p->establishment_cause; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialUEMessage_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RRCEstablishmentCause; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RRCEstablishmentCause; + ie->value.choice.RRCEstablishmentCause = UEfirstReq->establishment_cause; + } /* optional */ - if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_FiveG_s_tmsi) { + if (UEfirstReq->ue_identity.presenceMask & NGAP_UE_IDENTITIES_FiveG_s_tmsi) { NGAP_DEBUG("FIVEG_S_TMSI_PRESENT\n"); - ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialUEMessage_IEs_t, ie); ie->id = NGAP_ProtocolIE_ID_id_FiveG_S_TMSI; ie->criticality = NGAP_Criticality_reject; ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_FiveG_S_TMSI; - AMF_SETID_TO_BIT_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id, - &ie->value.choice.FiveG_S_TMSI.aMFSetID); - AMF_SETID_TO_BIT_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.amf_pointer, - &ie->value.choice.FiveG_S_TMSI.aMFPointer); - M_TMSI_TO_OCTET_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.m_tmsi, - &ie->value.choice.FiveG_S_TMSI.fiveG_TMSI); - asn1cSeqAdd(&out->protocolIEs.list, ie); + AMF_SETID_TO_BIT_STRING(UEfirstReq->ue_identity.s_tmsi.amf_set_id, &ie->value.choice.FiveG_S_TMSI.aMFSetID); + AMF_SETID_TO_BIT_STRING(UEfirstReq->ue_identity.s_tmsi.amf_pointer, &ie->value.choice.FiveG_S_TMSI.aMFPointer); + M_TMSI_TO_OCTET_STRING(UEfirstReq->ue_identity.s_tmsi.m_tmsi, &ie->value.choice.FiveG_S_TMSI.fiveG_TMSI); } - /* optional */ - ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_UEContextRequest; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_UEContextRequest; - ie->value.choice.UEContextRequest = NGAP_UEContextRequest_requested; - asn1cSeqAdd(&out->protocolIEs.list, ie); - + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialUEMessage_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_UEContextRequest; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_UEContextRequest; + ie->value.choice.UEContextRequest = NGAP_UEContextRequest_requested; + } if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { /* Failed to encode message */ @@ -342,9 +315,7 @@ int ngap_gNB_handle_nas_downlink(uint32_t assoc_id, // } if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { - NGAP_ERROR( - "[SCTP %d] Received NAS downlink message for non existing AMF context\n", - assoc_id); + NGAP_ERROR("[SCTP %d] Received NAS downlink message for non existing AMF context\n", assoc_id); return -1; } @@ -360,8 +331,7 @@ int ngap_gNB_handle_nas_downlink(uint32_t assoc_id, NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); gnb_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; - if ((ue_desc_p = ngap_gNB_get_ue_context(ngap_gNB_instance, - gnb_ue_ngap_id)) == NULL) { + if ((ue_desc_p = ngap_get_ue_context(gnb_ue_ngap_id)) == NULL) { NGAP_ERROR("[SCTP %d] Received NAS downlink message for non existing UE context gNB_UE_NGAP_ID: 0x%lx\n", assoc_id, gnb_ue_ngap_id); @@ -384,23 +354,15 @@ int ngap_gNB_handle_nas_downlink(uint32_t assoc_id, } else { /* We already have a amf ue ngap id check the received is the same */ if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { - NGAP_ERROR("[SCTP %d] Mismatch in AMF UE NGAP ID (0x%lx != 0x%"PRIx64"\n", - assoc_id, - amf_ue_ngap_id, - (uint64_t)ue_desc_p->amf_ue_ngap_id - ); - return -1; + NGAP_ERROR("[SCTP %d] Mismatch in AMF UE NGAP ID (0x%lx != 0x%" PRIx64 "\n", assoc_id, amf_ue_ngap_id, (uint64_t)ue_desc_p->amf_ue_ngap_id); + return -1; } } NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNASTransport_IEs_t, ie, container, NGAP_ProtocolIE_ID_id_NAS_PDU, true); /* Forward the NAS PDU to NR-RRC */ - ngap_gNB_itti_send_nas_downlink_ind(ngap_gNB_instance->instance, - ue_desc_p->ue_initial_id, - ue_desc_p->gNB_ue_ngap_id, - ie->value.choice.NAS_PDU.buf, - ie->value.choice.NAS_PDU.size); + ngap_gNB_itti_send_nas_downlink_ind(ngap_gNB_instance->instance, ue_desc_p->gNB_ue_ngap_id, ie->value.choice.NAS_PDU.buf, ie->value.choice.NAS_PDU.size); return 0; } @@ -411,10 +373,7 @@ int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_ { struct ngap_gNB_ue_context_s *ue_context_p; ngap_gNB_instance_t *ngap_gNB_instance_p; - NGAP_NGAP_PDU_t pdu; - NGAP_UplinkNASTransport_t *out; - NGAP_UplinkNASTransport_IEs_t *ie; - NGAP_UserLocationInformationNR_t *userinfo_nr_p = NULL; + NGAP_NGAP_PDU_t pdu; uint8_t *buffer; uint32_t length; DevAssert(ngap_uplink_nas_p != NULL); @@ -422,7 +381,7 @@ int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_ ngap_gNB_instance_p = ngap_gNB_get_instance(instance); DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, ngap_uplink_nas_p->gNB_ue_ngap_id)) == NULL) { + if ((ue_context_p = ngap_get_ue_context(ngap_uplink_nas_p->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: %08x\n", ngap_uplink_nas_p->gNB_ue_ngap_id); @@ -432,8 +391,7 @@ int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_ /* 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)) { + 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: %u, current state: %d\n", ngap_uplink_nas_p->gNB_ue_ngap_id, ue_context_p->ue_state); @@ -443,63 +401,63 @@ int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_ /* Prepare the NGAP message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t)); - pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UplinkNASTransport; - pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; - pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UplinkNASTransport; - out = &pdu.choice.initiatingMessage->value.choice.UplinkNASTransport; + asn1cCalloc(pdu.choice.initiatingMessage, head); + head->procedureCode = NGAP_ProcedureCode_id_UplinkNASTransport; + head->criticality = NGAP_Criticality_ignore; + head->value.present = NGAP_InitiatingMessage__value_PR_UplinkNASTransport; + NGAP_UplinkNASTransport_t *out = &head->value.choice.UplinkNASTransport; /* mandatory */ - ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UplinkNASTransport_IEs__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); - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkNASTransport_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNASTransport_IEs__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 */ - ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = ue_context_p->gNB_ue_ngap_id; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkNASTransport_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_context_p->gNB_ue_ngap_id; + } /* mandatory */ - ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_NAS_PDU; - ie->value.choice.NAS_PDU.buf = ngap_uplink_nas_p->nas_pdu.buffer; - ie->value.choice.NAS_PDU.size = ngap_uplink_nas_p->nas_pdu.length; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkNASTransport_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_NAS_PDU; + ie->value.choice.NAS_PDU.buf = ngap_uplink_nas_p->nas_pdu.buffer; + ie->value.choice.NAS_PDU.size = ngap_uplink_nas_p->nas_pdu.length; + } /* mandatory */ - ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_UserLocationInformation; + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkNASTransport_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_UserLocationInformation; - ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; - ie->value.choice.UserLocationInformation.choice.userLocationInformationNR = CALLOC(1,sizeof(struct NGAP_UserLocationInformationNR)); - userinfo_nr_p = ie->value.choice.UserLocationInformation.choice.userLocationInformationNR; + ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; + asn1cCalloc(ie->value.choice.UserLocationInformation.choice.userLocationInformationNR, userinfo_nr_p); - /* Set nRCellIdentity. default userLocationInformationNR */ - MACRO_GNB_ID_TO_CELL_IDENTITY(ngap_gNB_instance_p->gNB_id, - 0, // Cell ID - &userinfo_nr_p->nR_CGI.nRCellIdentity); - MCC_MNC_TO_TBCD(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], - ngap_gNB_instance_p->mnc[ue_context_p->selected_plmn_identity], - ngap_gNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], - &userinfo_nr_p->nR_CGI.pLMNIdentity); - - /* Set TAI */ - INT24_TO_OCTET_STRING(ngap_gNB_instance_p->tac, &userinfo_nr_p->tAI.tAC); - MCC_MNC_TO_PLMNID(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + /* Set nRCellIdentity. default userLocationInformationNR */ + MACRO_GNB_ID_TO_CELL_IDENTITY(ngap_gNB_instance_p->gNB_id, + 0, // Cell ID + &userinfo_nr_p->nR_CGI.nRCellIdentity); + MCC_MNC_TO_TBCD(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], ngap_gNB_instance_p->mnc[ue_context_p->selected_plmn_identity], ngap_gNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], - &userinfo_nr_p->tAI.pLMNIdentity); - - - asn1cSeqAdd(&out->protocolIEs.list, ie); + &userinfo_nr_p->nR_CGI.pLMNIdentity); + /* Set TAI */ + INT24_TO_OCTET_STRING(ngap_gNB_instance_p->tac, &userinfo_nr_p->tAI.tAC); + MCC_MNC_TO_PLMNID(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + ngap_gNB_instance_p->mnc[ue_context_p->selected_plmn_identity], + ngap_gNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], + &userinfo_nr_p->tAI.pLMNIdentity); + } if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { NGAP_ERROR("Failed to encode uplink NAS transport\n"); /* Encode procedure has failed... */ @@ -522,9 +480,7 @@ int ngap_gNB_nas_non_delivery_ind(instance_t instance, { struct ngap_gNB_ue_context_s *ue_context_p; ngap_gNB_instance_t *ngap_gNB_instance_p; - NGAP_NGAP_PDU_t pdu; - NGAP_NASNonDeliveryIndication_t *out; - NGAP_NASNonDeliveryIndication_IEs_t *ie; + NGAP_NGAP_PDU_t pdu; uint8_t *buffer; uint32_t length; DevAssert(ngap_nas_non_delivery_ind != NULL); @@ -532,7 +488,7 @@ int ngap_gNB_nas_non_delivery_ind(instance_t instance, ngap_gNB_instance_p = ngap_gNB_get_instance(instance); DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, ngap_nas_non_delivery_ind->gNB_ue_ngap_id)) == NULL) { + if ((ue_context_p = ngap_get_ue_context(ngap_nas_non_delivery_ind->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: %08x\n", ngap_nas_non_delivery_ind->gNB_ue_ngap_id); @@ -542,42 +498,46 @@ int ngap_gNB_nas_non_delivery_ind(instance_t instance, /* Prepare the NGAP message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t)); - pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_NASNonDeliveryIndication; - pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; - pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_NASNonDeliveryIndication; - out = &pdu.choice.initiatingMessage->value.choice.NASNonDeliveryIndication; + asn1cCalloc(pdu.choice.initiatingMessage, head); + head->procedureCode = NGAP_ProcedureCode_id_NASNonDeliveryIndication; + head->criticality = NGAP_Criticality_ignore; + head->value.present = NGAP_InitiatingMessage__value_PR_NASNonDeliveryIndication; + NGAP_NASNonDeliveryIndication_t *out = &head->value.choice.NASNonDeliveryIndication; /* mandatory */ - ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_AMF_UE_NGAP_ID; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_NASNonDeliveryIndication_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + } /* mandatory */ - ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = ue_context_p->gNB_ue_ngap_id; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_NASNonDeliveryIndication_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_context_p->gNB_ue_ngap_id; + } /* mandatory */ - ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_NAS_PDU; - ie->value.choice.NAS_PDU.buf = ngap_nas_non_delivery_ind->nas_pdu.buffer; - ie->value.choice.NAS_PDU.size = ngap_nas_non_delivery_ind->nas_pdu.length; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_NASNonDeliveryIndication_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_NAS_PDU; + ie->value.choice.NAS_PDU.buf = ngap_nas_non_delivery_ind->nas_pdu.buffer; + ie->value.choice.NAS_PDU.size = ngap_nas_non_delivery_ind->nas_pdu.length; + } /* mandatory */ - ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_Cause; - ie->criticality = NGAP_Criticality_ignore; - /* Send a dummy cause */ - ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_Cause; - ie->value.choice.Cause.present = NGAP_Cause_PR_radioNetwork; - ie->value.choice.Cause.choice.radioNetwork = NGAP_CauseRadioNetwork_radio_connection_with_ue_lost; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_NASNonDeliveryIndication_IEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_Cause; + ie->criticality = NGAP_Criticality_ignore; + /* Send a dummy cause */ + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_Cause; + ie->value.choice.Cause.present = NGAP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = NGAP_CauseRadioNetwork_radio_connection_with_ue_lost; + } if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { NGAP_ERROR("Failed to encode NAS NON delivery indication\n"); @@ -594,30 +554,23 @@ int ngap_gNB_nas_non_delivery_ind(instance_t instance, } //------------------------------------------------------------------------------ -int ngap_gNB_initial_ctxt_resp( - instance_t instance, ngap_initial_context_setup_resp_t *initial_ctxt_resp_p) +int ngap_gNB_initial_ctxt_resp(instance_t instance, ngap_initial_context_setup_resp_t *initial_ctxt_resp_p) //------------------------------------------------------------------------------ { ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; struct ngap_gNB_ue_context_s *ue_context_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_InitialContextSetupResponse_t *out; - NGAP_InitialContextSetupResponseIEs_t *ie; - uint8_t *buffer = NULL; - uint8_t pdusessionTransfer_buffer[1000]; + NGAP_NGAP_PDU_t pdu; + uint8_t *buffer = NULL; uint32_t length; - int i; - asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + int i; - /* Retrieve the NGAP gNB instance associated with Mod_id */ ngap_gNB_instance_p = ngap_gNB_get_instance(instance); DevAssert(initial_ctxt_resp_p != NULL); DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - initial_ctxt_resp_p->gNB_ue_ngap_id)) == NULL) { + if ((ue_context_p = ngap_get_ue_context(initial_ctxt_resp_p->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_resp_p->gNB_ue_ngap_id); @@ -627,8 +580,7 @@ int ngap_gNB_initial_ctxt_resp( /* 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)) { + 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_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); @@ -638,142 +590,101 @@ int ngap_gNB_initial_ctxt_resp( /* Prepare the NGAP message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome)); - pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_InitialContextSetup; - pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; - pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_InitialContextSetupResponse; - out = &pdu.choice.successfulOutcome->value.choice.InitialContextSetupResponse; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NGAP_ProcedureCode_id_InitialContextSetup; + head->criticality = NGAP_Criticality_reject; + head->value.present = NGAP_SuccessfulOutcome__value_PR_InitialContextSetupResponse; + NGAP_InitialContextSetupResponse_t *out = &head->value.choice.InitialContextSetupResponse; /* mandatory */ - ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_InitialContextSetupResponseIEs__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); - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialContextSetupResponseIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupResponseIEs__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 */ - ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = initial_ctxt_resp_p->gNB_ue_ngap_id; - asn1cSeqAdd(&out->protocolIEs.list, ie); - + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialContextSetupResponseIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = initial_ctxt_resp_p->gNB_ue_ngap_id; + } /* optional */ if (initial_ctxt_resp_p->nb_of_pdusessions){ - ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialContextSetupResponseIEs_t, ie); ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtRes; ie->criticality = NGAP_Criticality_ignore; ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_PDUSessionResourceSetupListCxtRes; for (i = 0; i < initial_ctxt_resp_p->nb_of_pdusessions; i++) { - NGAP_PDUSessionResourceSetupItemCxtRes_t *item; - NGAP_PDUSessionResourceSetupResponseTransfer_t *pdusessionTransfer_p = NULL; - - /* mandatory */ - item = (NGAP_PDUSessionResourceSetupItemCxtRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupItemCxtRes_t)); - + asn1cSequenceAdd(ie->value.choice.PDUSessionResourceSetupListCxtRes.list, NGAP_PDUSessionResourceSetupItemCxtRes_t, item); /* pDUSessionID */ item->pDUSessionID = initial_ctxt_resp_p->pdusessions[i].pdusession_id; /* dLQosFlowPerTNLInformation */ - pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t)); + NGAP_PDUSessionResourceSetupResponseTransfer_t pdusessionTransfer = {0}; - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; - - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel = (NGAP_GTPTunnel_t *)calloc(1, sizeof(NGAP_GTPTunnel_t)); - struct NGAP_GTPTunnel *tmp=pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel; + pdusessionTransfer.dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; + + asn1cCalloc(pdusessionTransfer.dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel, tmp); GTP_TEID_TO_ASN1(initial_ctxt_resp_p->pdusessions[i].gtp_teid, &tmp->gTP_TEID); + allocAddrCopy(&tmp->transportLayerAddress, initial_ctxt_resp_p->pdusessions[i].gNB_addr); - tmp->transportLayerAddress.buf = malloc(initial_ctxt_resp_p->pdusessions[i].gNB_addr.length); - - memcpy(tmp->transportLayerAddress.buf, - initial_ctxt_resp_p->pdusessions[i].gNB_addr.buffer, - initial_ctxt_resp_p->pdusessions[i].gNB_addr.length); - tmp->transportLayerAddress.size = initial_ctxt_resp_p->pdusessions[i].gNB_addr.length; - tmp->transportLayerAddress.bits_unused = 0; - - NGAP_DEBUG("initial_ctxt_resp_p: pdusession ID %ld\n", - item->pDUSessionID); + NGAP_DEBUG("initial_ctxt_resp_p: pdusession ID %ld\n", item->pDUSessionID); /* associatedQosFlowList. number of 1? */ for(int j=0; j < initial_ctxt_resp_p->pdusessions[i].nb_of_qos_flow; j++) { - NGAP_AssociatedQosFlowItem_t *ass_qos_item_p; - ass_qos_item_p = (NGAP_AssociatedQosFlowItem_t *)calloc(1, sizeof(NGAP_AssociatedQosFlowItem_t)); - + asn1cSequenceAdd(pdusessionTransfer.dLQosFlowPerTNLInformation.associatedQosFlowList.list, NGAP_AssociatedQosFlowItem_t, ass_qos_item_p); /* qosFlowIdentifier */ ass_qos_item_p->qosFlowIdentifier = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qfi; - - /* qosFlowMappingIndication */ - //if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) { - // ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication)); - // *ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind; - // } - asn1cSeqAdd(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p); - } - - //res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); - //item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer; - //item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded; - - if (asn1_xer_print) { - xer_fprint(stdout, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); } - memset(pdusessionTransfer_buffer, 0, 1000); - asn_enc_rval_t enc_rval = aper_encode_to_buffer(&asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, - NULL, - pdusessionTransfer_p, - pdusessionTransfer_buffer,1000); - AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - item->pDUSessionResourceSetupResponseTransfer.buf = pdusessionTransfer_buffer; - item->pDUSessionResourceSetupResponseTransfer.size = enc_rval.encoded; + void *pdusessionTransfer_buffer; + ssize_t encoded = aper_encode_to_new_buffer(&asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, NULL, &pdusessionTransfer, &pdusessionTransfer_buffer); + AssertFatal(encoded > 0, "ASN1 message encoding failed !\n"); + item->pDUSessionResourceSetupResponseTransfer.buf = pdusessionTransfer_buffer; + item->pDUSessionResourceSetupResponseTransfer.size = encoded; - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); - - asn1cSeqAdd(&ie->value.choice.PDUSessionResourceSetupListCxtRes.list, item); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, &pdusessionTransfer); } - - asn1cSeqAdd(&out->protocolIEs.list, ie); } /* optional */ if (initial_ctxt_resp_p->nb_of_pdusessions_failed) { - ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialContextSetupResponseIEs_t, ie); ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToSetupListCxtRes; ie->criticality = NGAP_Criticality_ignore; ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_PDUSessionResourceFailedToSetupListCxtRes; for (i = 0; i < initial_ctxt_resp_p->nb_of_pdusessions_failed; i++) { - NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t *item = calloc(1, sizeof *item); - NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = calloc(1, sizeof *pdusessionUnTransfer_p); + asn1cSequenceAdd(ie->value.choice.PDUSessionResourceFailedToSetupListCxtRes.list, NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t, item); + NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t pdusessionUnTransfer = {0}; /* pDUSessionID */ item->pDUSessionID = initial_ctxt_resp_p->pdusessions_failed[i].pdusession_id; /* cause */ - switch(initial_ctxt_resp_p->pdusessions_failed[i].cause) { + pdusessionUnTransfer.cause.present = initial_ctxt_resp_p->pdusessions_failed[i].cause; + switch (pdusessionUnTransfer.cause.present) { case NGAP_CAUSE_RADIO_NETWORK: - pdusessionUnTransfer_p->cause.present = NGAP_Cause_PR_radioNetwork; - pdusessionUnTransfer_p->cause.choice.radioNetwork = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + pdusessionUnTransfer.cause.choice.radioNetwork = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; break; case NGAP_CAUSE_TRANSPORT: - pdusessionUnTransfer_p->cause.present = NGAP_Cause_PR_transport; - pdusessionUnTransfer_p->cause.choice.transport = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + pdusessionUnTransfer.cause.choice.transport = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; break; case NGAP_CAUSE_NAS: - pdusessionUnTransfer_p->cause.present = NGAP_Cause_PR_nas; - pdusessionUnTransfer_p->cause.choice.nas = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + pdusessionUnTransfer.cause.choice.nas = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; break; case NGAP_CAUSE_PROTOCOL: - pdusessionUnTransfer_p->cause.present = NGAP_Cause_PR_protocol; - pdusessionUnTransfer_p->cause.choice.protocol = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + pdusessionUnTransfer.cause.choice.protocol = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; break; case NGAP_CAUSE_MISC: - pdusessionUnTransfer_p->cause.present = NGAP_Cause_PR_misc; - pdusessionUnTransfer_p->cause.choice.misc = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + pdusessionUnTransfer.cause.choice.misc = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; break; case NGAP_CAUSE_NOTHING: @@ -782,27 +693,22 @@ int ngap_gNB_initial_ctxt_resp( } NGAP_DEBUG("initial context setup response: failed pdusession ID %ld\n", item->pDUSessionID); - - memset(&res, 0, sizeof(res)); - res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, &pdusessionUnTransfer); + AssertFatal(res.buffer, "ASN1 message encoding failed (%s, %lu)!\n", res.result.failed_type->name, res.result.encoded); item->pDUSessionResourceSetupUnsuccessfulTransfer.buf = res.buffer; item->pDUSessionResourceSetupUnsuccessfulTransfer.size = res.result.encoded; - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); - asn1cSeqAdd(&ie->value.choice.PDUSessionResourceFailedToSetupListCxtRes.list, item); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, &pdusessionUnTransfer); } - - asn1cSeqAdd(&out->protocolIEs.list, ie); } /* optional */ if (0) { - ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialContextSetupResponseIEs_t, ie); ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; ie->criticality = NGAP_Criticality_ignore; ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_CriticalityDiagnostics; // ie->value.choice.CriticalityDiagnostics =; - asn1cSeqAdd(&out->protocolIEs.list, ie); } if (asn1_xer_print) { @@ -817,23 +723,17 @@ int ngap_gNB_initial_ctxt_resp( /* UE associated signalling -> use the allocated stream */ LOG_I(NR_RRC,"Send message to sctp: NGAP_InitialContextSetupResponse\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); + 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) +int ngap_gNB_ue_capabilities(instance_t instance, ngap_ue_cap_info_ind_t *ue_cap_info_ind_p) //------------------------------------------------------------------------------ { ngap_gNB_instance_t *ngap_gNB_instance_p; struct ngap_gNB_ue_context_s *ue_context_p; - NGAP_NGAP_PDU_t pdu; - NGAP_UERadioCapabilityInfoIndication_t *out; - NGAP_UERadioCapabilityInfoIndicationIEs_t *ie; uint8_t *buffer; uint32_t length; /* Retrieve the NGAP gNB instance associated with Mod_id */ @@ -841,56 +741,57 @@ int ngap_gNB_ue_capabilities(instance_t instance, DevAssert(ue_cap_info_ind_p != NULL); DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - ue_cap_info_ind_p->gNB_ue_ngap_id)) == NULL) { + if ((ue_context_p = ngap_get_ue_context(ue_cap_info_ind_p->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: %u\n", - ue_cap_info_ind_p->gNB_ue_ngap_id); + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n", ue_cap_info_ind_p->gNB_ue_ngap_id); return -1; } /* UE radio capabilities message 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: %u, current state: %d\n", - ue_cap_info_ind_p->gNB_ue_ngap_id, ue_context_p->ue_state); + 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: %u, current state: %d\n", + ue_cap_info_ind_p->gNB_ue_ngap_id, + ue_context_p->ue_state); return -1; } /* Prepare the NGAP message to encode */ - memset(&pdu, 0, sizeof(pdu)); + NGAP_NGAP_PDU_t pdu = {0}; pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t)); - pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication; - pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; - pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UERadioCapabilityInfoIndication; - out = &pdu.choice.initiatingMessage->value.choice.UERadioCapabilityInfoIndication; + asn1cCalloc(pdu.choice.initiatingMessage, head); + head->procedureCode = NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication; + head->criticality = NGAP_Criticality_ignore; + head->value.present = NGAP_InitiatingMessage__value_PR_UERadioCapabilityInfoIndication; + NGAP_UERadioCapabilityInfoIndication_t *out = &head->value.choice.UERadioCapabilityInfoIndication; /* mandatory */ - ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__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); - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UERadioCapabilityInfoIndicationIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + } /* mandatory */ - ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = ue_cap_info_ind_p->gNB_ue_ngap_id; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UERadioCapabilityInfoIndicationIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = (int64_t)ue_cap_info_ind_p->gNB_ue_ngap_id; + } /* mandatory */ - ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_UERadioCapability; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_UERadioCapability; - ie->value.choice.UERadioCapability.buf = ue_cap_info_ind_p->ue_radio_cap.buffer; - ie->value.choice.UERadioCapability.size = ue_cap_info_ind_p->ue_radio_cap.length; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UERadioCapabilityInfoIndicationIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_UERadioCapability; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_UERadioCapability; + ie->value.choice.UERadioCapability.buf = ue_cap_info_ind_p->ue_radio_cap.buffer; + ie->value.choice.UERadioCapability.size = ue_cap_info_ind_p->ue_radio_cap.length; + } /* optional */ //NGAP_UERadioCapabilityForPaging TBD if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { @@ -900,22 +801,17 @@ int ngap_gNB_ue_capabilities(instance_t instance, } /* UE associated signalling -> use the allocated stream */ - 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); + 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_pdusession_setup_resp(instance_t instance, - ngap_pdusession_setup_resp_t *pdusession_setup_resp_p) +int ngap_gNB_pdusession_setup_resp(instance_t instance, ngap_pdusession_setup_resp_t *pdusession_setup_resp_p) //------------------------------------------------------------------------------ { ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; struct ngap_gNB_ue_context_s *ue_context_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_PDUSessionResourceSetupResponse_t *out; - NGAP_PDUSessionResourceSetupResponseIEs_t *ie; + NGAP_NGAP_PDU_t pdu = {0}; uint8_t *buffer = NULL; uint32_t length; @@ -924,155 +820,134 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance, DevAssert(pdusession_setup_resp_p != NULL); DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - pdusession_setup_resp_p->gNB_ue_ngap_id)) == NULL) { + if ((ue_context_p = ngap_get_ue_context(pdusession_setup_resp_p->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", - pdusession_setup_resp_p->gNB_ue_ngap_id); + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", pdusession_setup_resp_p->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", - pdusession_setup_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); + 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", + pdusession_setup_resp_p->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_successfulOutcome; - pdu.choice.successfulOutcome = calloc(1,sizeof *pdu.choice.successfulOutcome); - pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceSetup; - pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; - pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceSetupResponse; - out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceSetupResponse; + asn1cCalloc(pdu.choice.successfulOutcome, successfulOutcome); + successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceSetup; + successfulOutcome->criticality = NGAP_Criticality_reject; + successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceSetupResponse; + NGAP_PDUSessionResourceSetupResponse_t *out = &successfulOutcome->value.choice.PDUSessionResourceSetupResponse; /* mandatory */ - ie = calloc(1, sizeof *ie); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_AMF_UE_NGAP_ID; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceSetupResponseIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + } /* mandatory */ - ie = calloc(1, sizeof *ie ); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = pdusession_setup_resp_p->gNB_ue_ngap_id; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceSetupResponseIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = pdusession_setup_resp_p->gNB_ue_ngap_id; + } /* optional */ if (pdusession_setup_resp_p->nb_of_pdusessions > 0) { - ie = calloc(1, sizeof *ie ); - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSURes; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceSetupListSURes; + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceSetupResponseIEs_t, ie3); + ie3->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSURes; + ie3->criticality = NGAP_Criticality_ignore; + ie3->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceSetupListSURes; for (int i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions; i++) { - NGAP_PDUSessionResourceSetupItemSURes_t *item=calloc(1, sizeof *item ); - NGAP_PDUSessionResourceSetupResponseTransfer_t *pdusessionTransfer_p = calloc(1, sizeof *pdusessionTransfer_p ); - + pdusession_setup_t *pdusession = pdusession_setup_resp_p->pdusessions + i; + asn1cSequenceAdd(ie3->value.choice.PDUSessionResourceSetupListSURes.list, NGAP_PDUSessionResourceSetupItemSURes_t, item); /* pDUSessionID */ - item->pDUSessionID = pdusession_setup_resp_p->pdusessions[i].pdusession_id; + item->pDUSessionID = pdusession->pdusession_id; /* dLQosFlowPerTNLInformation */ - - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel = - calloc(1, sizeof(struct NGAP_GTPTunnel)); - struct NGAP_GTPTunnel *tmp=pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel; - GTP_TEID_TO_ASN1(pdusession_setup_resp_p->pdusessions[i].gtp_teid, &tmp->gTP_TEID); - if (pdusession_setup_resp_p->pdusessions[i].gNB_addr.length) { - tmp->transportLayerAddress.buf = malloc(pdusession_setup_resp_p->pdusessions[i].gNB_addr.length); - - memcpy(tmp->transportLayerAddress.buf, - pdusession_setup_resp_p->pdusessions[i].gNB_addr.buffer, - pdusession_setup_resp_p->pdusessions[i].gNB_addr.length); - tmp->transportLayerAddress.size = pdusession_setup_resp_p->pdusessions[i].gNB_addr.length; - tmp->transportLayerAddress.bits_unused = 0; - - NGAP_DEBUG("pdusession_setup_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld \n", - item->pDUSessionID, - tmp->transportLayerAddress.buf[0], - tmp->transportLayerAddress.buf[1], - tmp->transportLayerAddress.buf[2], - tmp->transportLayerAddress.buf[3], - tmp->transportLayerAddress.size); - } - + NGAP_PDUSessionResourceSetupResponseTransfer_t pdusessionTransfer = {0}; + pdusessionTransfer.dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; + asn1cCalloc(pdusessionTransfer.dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel, tmp); + GTP_TEID_TO_ASN1(pdusession->gtp_teid, &tmp->gTP_TEID); + allocAddrCopy(&tmp->transportLayerAddress, pdusession->gNB_addr); + NGAP_DEBUG("pdusession_setup_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld \n", + item->pDUSessionID, + tmp->transportLayerAddress.buf[0], + tmp->transportLayerAddress.buf[1], + tmp->transportLayerAddress.buf[2], + tmp->transportLayerAddress.buf[3], + tmp->transportLayerAddress.size); /* associatedQosFlowList. number of 1? */ for(int j=0; j < pdusession_setup_resp_p->pdusessions[i].nb_of_qos_flow; j++) { - NGAP_AssociatedQosFlowItem_t *ass_qos_item_p = calloc(1, sizeof *ass_qos_item_p); + asn1cSequenceAdd(pdusessionTransfer.dLQosFlowPerTNLInformation.associatedQosFlowList.list, NGAP_AssociatedQosFlowItem_t, ass_qos_item_p); /* qosFlowIdentifier */ ass_qos_item_p->qosFlowIdentifier = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qfi; /* qosFlowMappingIndication */ - //if(pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) { - // ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication)); - // *ass_qos_item_p->qosFlowMappingIndication = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind; - //} - asn1cSeqAdd(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p); + // if(pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) { + // ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication)); + // *ass_qos_item_p->qosFlowMappingIndication = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind; + // } } - asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, - &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, &pdusessionTransfer); AssertFatal (res.buffer, "ASN1 message encoding failed (%s, %lu)!\n", res.result.failed_type->name, res.result.encoded); item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer; item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded; - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); - - asn1cSeqAdd(&ie->value.choice.PDUSessionResourceSetupListSURes.list, item); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, &pdusessionTransfer); } - asn1cSeqAdd(&out->protocolIEs.list, ie); } /* optional */ if (pdusession_setup_resp_p->nb_of_pdusessions_failed > 0) { - ie = calloc(1, sizeof *ie); + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceSetupResponseIEs_t, ie); ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToSetupListSURes; ie->criticality = NGAP_Criticality_ignore; ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceFailedToSetupListSURes; for (int i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions_failed; i++) { LOG_W(NGAP,"add a failed session\n"); - NGAP_PDUSessionResourceFailedToSetupItemSURes_t *item=calloc(1, sizeof *item); - NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = calloc(1, sizeof *pdusessionUnTransfer_p); + pdusession_failed_t *pdusession_failed = pdusession_setup_resp_p->pdusessions_failed + i; + asn1cSequenceAdd(ie->value.choice.PDUSessionResourceFailedToSetupListSURes.list, NGAP_PDUSessionResourceFailedToSetupItemSURes_t, item); + NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t pdusessionUnTransfer_p = {0}; /* pDUSessionID */ - item->pDUSessionID = pdusession_setup_resp_p->pdusessions_failed[i].pdusession_id; + item->pDUSessionID = pdusession_failed->pdusession_id; /* cause */ - switch(pdusession_setup_resp_p->pdusessions_failed[i].cause) { + pdusessionUnTransfer_p.cause.present = pdusession_failed->cause; + switch (pdusessionUnTransfer_p.cause.present) { case NGAP_CAUSE_RADIO_NETWORK: - pdusessionUnTransfer_p->cause.present = NGAP_Cause_PR_radioNetwork; - pdusessionUnTransfer_p->cause.choice.radioNetwork = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + pdusessionUnTransfer_p.cause.choice.radioNetwork = pdusession_failed->cause_value; break; case NGAP_CAUSE_TRANSPORT: - pdusessionUnTransfer_p->cause.present = NGAP_Cause_PR_transport; - pdusessionUnTransfer_p->cause.choice.transport = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + pdusessionUnTransfer_p.cause.choice.transport = pdusession_failed->cause_value; break; case NGAP_CAUSE_NAS: - pdusessionUnTransfer_p->cause.present = NGAP_Cause_PR_nas; - pdusessionUnTransfer_p->cause.choice.nas = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + pdusessionUnTransfer_p.cause.choice.nas = pdusession_failed->cause_value; break; case NGAP_CAUSE_PROTOCOL: - pdusessionUnTransfer_p->cause.present = NGAP_Cause_PR_protocol; - pdusessionUnTransfer_p->cause.choice.protocol = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + pdusessionUnTransfer_p.cause.choice.protocol = pdusession_failed->cause_value; break; case NGAP_CAUSE_MISC: - pdusessionUnTransfer_p->cause.present = NGAP_Cause_PR_misc; - pdusessionUnTransfer_p->cause.choice.misc = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + pdusessionUnTransfer_p.cause.choice.misc = pdusession_failed->cause_value; break; case NGAP_CAUSE_NOTHING: @@ -1082,31 +957,23 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance, NGAP_DEBUG("pdusession setup response: failed pdusession ID %ld\n", item->pDUSessionID); - asn_encode_to_new_buffer_result_t res = - asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, - &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, &pdusessionUnTransfer_p); item->pDUSessionResourceSetupUnsuccessfulTransfer.buf = res.buffer; item->pDUSessionResourceSetupUnsuccessfulTransfer.size = res.result.encoded; - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); - - asn1cSeqAdd(&ie->value.choice.PDUSessionResourceFailedToSetupListSURes.list, item); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, &pdusessionUnTransfer_p); } - - asn1cSeqAdd(&out->protocolIEs.list, ie); } /* optional */ if (0) { - ie = calloc(1, sizeof *ie); - ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_CriticalityDiagnostics; - // ie->value.choice.CriticalityDiagnostics = ; - asn1cSeqAdd(&out->protocolIEs.list, ie); + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceSetupResponseIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_CriticalityDiagnostics; + // ie->value.choice.CriticalityDiagnostics = ; } - if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { NGAP_ERROR("Failed to encode uplink transport\n"); /* Encode procedure has failed... */ @@ -1114,100 +981,90 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance, } /* UE associated signalling -> use the allocated stream */ - 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); + 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_pdusession_modify_resp(instance_t instance, - ngap_pdusession_modify_resp_t *pdusession_modify_resp_p) +int ngap_gNB_pdusession_modify_resp(instance_t instance, ngap_pdusession_modify_resp_t *pdusession_modify_resp_p) //------------------------------------------------------------------------------ { ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; struct ngap_gNB_ue_context_s *ue_context_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_PDUSessionResourceModifyResponse_t *out; - NGAP_PDUSessionResourceModifyResponseIEs_t *ie; + NGAP_NGAP_PDU_t pdu; uint8_t *buffer = NULL; uint32_t length; - int i; - asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; - + /* Retrieve the NGAP gNB instance associated with Mod_id */ ngap_gNB_instance_p = ngap_gNB_get_instance(instance); DevAssert(pdusession_modify_resp_p != NULL); DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - pdusession_modify_resp_p->gNB_ue_ngap_id)) == NULL) { + if ((ue_context_p = ngap_get_ue_context(pdusession_modify_resp_p->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", - pdusession_modify_resp_p->gNB_ue_ngap_id); + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", pdusession_modify_resp_p->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", - pdusession_modify_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); + 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", + pdusession_modify_resp_p->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_successfulOutcome; - pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome)); - pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceModify; - pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; - pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceModifyResponse; - out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceModifyResponse; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceModify; + head->criticality = NGAP_Criticality_reject; + head->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceModifyResponse; + NGAP_PDUSessionResourceModifyResponse_t *out = &head->value.choice.PDUSessionResourceModifyResponse; /* mandatory */ - ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_AMF_UE_NGAP_ID; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceModifyResponseIEs_t, ie); + ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + asn1cSeqAdd(&out->protocolIEs.list, ie); + } /* mandatory */ - ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = pdusession_modify_resp_p->gNB_ue_ngap_id; - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceModifyResponseIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = pdusession_modify_resp_p->gNB_ue_ngap_id; + } /* PDUSessionResourceModifyListModRes optional */ if (pdusession_modify_resp_p->nb_of_pdusessions > 0) { - ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceModifyResponseIEs_t, ie); ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModRes; ie->criticality = NGAP_Criticality_ignore; ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_PDUSessionResourceModifyListModRes; - for (i = 0; i < pdusession_modify_resp_p->nb_of_pdusessions; i++) { - NGAP_PDUSessionResourceModifyItemModRes_t *item; - NGAP_PDUSessionResourceModifyResponseTransfer_t *transfer_p = NULL; - - item = (NGAP_PDUSessionResourceModifyItemModRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyItemModRes_t)); + for (int i = 0; i < pdusession_modify_resp_p->nb_of_pdusessions; i++) { + asn1cSequenceAdd(ie->value.choice.PDUSessionResourceModifyListModRes.list, NGAP_PDUSessionResourceModifyItemModRes_t, item); item->pDUSessionID = pdusession_modify_resp_p->pdusessions[i].pdusession_id; - transfer_p = (NGAP_PDUSessionResourceModifyResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseTransfer_t)); - transfer_p->qosFlowAddOrModifyResponseList = (NGAP_QosFlowAddOrModifyResponseList_t *)calloc(1, sizeof(NGAP_QosFlowAddOrModifyResponseList_t)); + NGAP_PDUSessionResourceModifyResponseTransfer_t transfer = {0}; + asn1cCalloc(transfer.qosFlowAddOrModifyResponseList, tmp); - uint8_t qos_flow_index; - for (qos_flow_index = 0; qos_flow_index < pdusession_modify_resp_p->pdusessions[i].nb_of_qos_flow; qos_flow_index++) { - NGAP_QosFlowAddOrModifyResponseItem_t *qosFlowAddOrModifyResponseItem_p = calloc(1, sizeof(NGAP_QosFlowAddOrModifyResponseItem_t)); - qosFlowAddOrModifyResponseItem_p->qosFlowIdentifier = - pdusession_modify_resp_p->pdusessions[i].qos[qos_flow_index].qfi; - asn1cSeqAdd(&transfer_p->qosFlowAddOrModifyResponseList->list, qosFlowAddOrModifyResponseItem_p); + for (int qos_flow_index = 0; qos_flow_index < pdusession_modify_resp_p->pdusessions[i].nb_of_qos_flow; qos_flow_index++) { + asn1cSequenceAdd(tmp->list, NGAP_QosFlowAddOrModifyResponseItem_t, qos); + qos->qosFlowIdentifier = pdusession_modify_resp_p->pdusessions[i].qos[qos_flow_index].qfi; } - - memset(&res, 0, sizeof(res)); + asn_encode_to_new_buffer_result_t res = {0}; + NGAP_PDUSessionResourceModifyResponseTransfer_t *transfer_p = NULL; res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceModifyResponseTransfer, transfer_p); item->pDUSessionResourceModifyResponseTransfer.buf = res.buffer; item->pDUSessionResourceModifyResponseTransfer.size = res.result.encoded; @@ -1215,52 +1072,42 @@ int ngap_gNB_pdusession_modify_resp(instance_t instance, ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceModifyResponseTransfer, transfer_p); NGAP_DEBUG("pdusession_modify_resp: modified pdusession ID %ld\n", item->pDUSessionID); - asn1cSeqAdd(&ie->value.choice.PDUSessionResourceModifyListModRes.list, item); } - - asn1cSeqAdd(&out->protocolIEs.list, ie); } /* optional */ if (pdusession_modify_resp_p->nb_of_pdusessions_failed > 0) { - ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceModifyResponseIEs_t, ie); ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToModifyListModRes; ie->criticality = NGAP_Criticality_ignore; ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_PDUSessionResourceFailedToModifyListModRes; - for (i = 0; i < pdusession_modify_resp_p->nb_of_pdusessions_failed; i++) { - NGAP_PDUSessionResourceFailedToModifyItemModRes_t *item; - NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t *pdusessionTransfer_p = NULL; - - item = (NGAP_PDUSessionResourceFailedToModifyItemModRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToModifyItemModRes_t)); + for (int i = 0; i < pdusession_modify_resp_p->nb_of_pdusessions_failed; i++) { + asn1cSequenceAdd(ie->value.choice.PDUSessionResourceFailedToModifyListModRes.list, NGAP_PDUSessionResourceFailedToModifyItemModRes_t, item); item->pDUSessionID = pdusession_modify_resp_p->pdusessions_failed[i].pdusession_id; - pdusessionTransfer_p = (NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t)); - - switch(pdusession_modify_resp_p->pdusessions_failed[i].cause) { + NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t pdusessionTransfer = {0}; + pdusessionTransfer.cause.present = pdusession_modify_resp_p->pdusessions_failed[i].cause; + + switch (pdusessionTransfer.cause.present) { case NGAP_CAUSE_RADIO_NETWORK: - pdusessionTransfer_p->cause.present = NGAP_Cause_PR_radioNetwork; - pdusessionTransfer_p->cause.choice.radioNetwork = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + pdusessionTransfer.cause.choice.radioNetwork = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; break; case NGAP_CAUSE_TRANSPORT: - pdusessionTransfer_p->cause.present = NGAP_Cause_PR_transport; - pdusessionTransfer_p->cause.choice.transport = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + pdusessionTransfer.cause.choice.transport = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; break; case NGAP_CAUSE_NAS: - pdusessionTransfer_p->cause.present = NGAP_Cause_PR_nas; - pdusessionTransfer_p->cause.choice.nas = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + pdusessionTransfer.cause.choice.nas = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; break; case NGAP_CAUSE_PROTOCOL: - pdusessionTransfer_p->cause.present = NGAP_Cause_PR_protocol; - pdusessionTransfer_p->cause.choice.protocol = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + pdusessionTransfer.cause.choice.protocol = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; break; case NGAP_CAUSE_MISC: - pdusessionTransfer_p->cause.present = NGAP_Cause_PR_misc; - pdusessionTransfer_p->cause.choice.misc = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + pdusessionTransfer.cause.choice.misc = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; break; case NGAP_CAUSE_NOTHING: @@ -1268,33 +1115,27 @@ int ngap_gNB_pdusession_modify_resp(instance_t instance, break; } - memset(&res, 0, sizeof(res)); - res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceModifyUnsuccessfulTransfer, pdusessionTransfer_p); + asn_encode_to_new_buffer_result_t res = {0}; + NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t *pdusessionTransfer_p = NULL; + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceModifyUnsuccessfulTransfer, &pdusessionTransfer); item->pDUSessionResourceModifyUnsuccessfulTransfer.buf = res.buffer; item->pDUSessionResourceModifyUnsuccessfulTransfer.size = res.result.encoded; ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceModifyUnsuccessfulTransfer, pdusessionTransfer_p); - NGAP_DEBUG("pdusession_modify_resp: failed pdusession ID %ld\n", item->pDUSessionID); - asn1cSeqAdd(&ie->value.choice.PDUSessionResourceFailedToModifyListModRes.list, item); } - - asn1cSeqAdd(&out->protocolIEs.list, ie); } /* optional */ if (0) { - ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceModifyResponseIEs_t, ie); ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; ie->criticality = NGAP_Criticality_ignore; ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_CriticalityDiagnostics; // ie->value.choice.CriticalityDiagnostics = ; - asn1cSeqAdd(&out->protocolIEs.list, ie); } - fprintf(stderr, "start encode\n"); - if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { NGAP_ERROR("Failed to encode uplink transport\n"); /* Encode procedure has failed... */ @@ -1302,22 +1143,17 @@ int ngap_gNB_pdusession_modify_resp(instance_t instance, } /* UE associated signalling -> use the allocated stream */ - 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); + 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_pdusession_release_resp(instance_t instance, - ngap_pdusession_release_resp_t *pdusession_release_resp_p) +int ngap_gNB_pdusession_release_resp(instance_t instance, ngap_pdusession_release_resp_t *pdusession_release_resp_p) //------------------------------------------------------------------------------ { ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; struct ngap_gNB_ue_context_s *ue_context_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_PDUSessionResourceReleaseResponse_t *out; - NGAP_PDUSessionResourceReleaseResponseIEs_t *ie; + NGAP_NGAP_PDU_t pdu; uint8_t *buffer = NULL; uint32_t length; int i; @@ -1326,68 +1162,52 @@ int ngap_gNB_pdusession_release_resp(instance_t instance, DevAssert(pdusession_release_resp_p != NULL); DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - pdusession_release_resp_p->gNB_ue_ngap_id)) == NULL) { + if ((ue_context_p = ngap_get_ue_context(pdusession_release_resp_p->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", - pdusession_release_resp_p->gNB_ue_ngap_id); + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", pdusession_release_resp_p->gNB_ue_ngap_id); return -1; } /* Prepare the NGAP message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome)); - pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceRelease; - pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; - pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceReleaseResponse; - out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceReleaseResponse; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceRelease; + head->criticality = NGAP_Criticality_reject; + head->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceReleaseResponse; + NGAP_PDUSessionResourceReleaseResponse_t *out = &head->value.choice.PDUSessionResourceReleaseResponse; /* mandatory */ - ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_AMF_UE_NGAP_ID; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceReleaseResponseIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + } /* mandatory */ - ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = pdusession_release_resp_p->gNB_ue_ngap_id; - asn1cSeqAdd(&out->protocolIEs.list, ie); - - /* optional */ - if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) { - ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes; - - for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) { - NGAP_PDUSessionResourceReleasedItemRelRes_t *item; - item = (NGAP_PDUSessionResourceReleasedItemRelRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleasedItemRelRes_t)); - - item->pDUSessionID = pdusession_release_resp_p->pdusession_release[i].pdusession_id; - if(pdusession_release_resp_p->pdusession_release[i].transfer_length > 0){ - item->pDUSessionResourceReleaseResponseTransfer.size = pdusession_release_resp_p->pdusession_release[i].transfer_length; - item->pDUSessionResourceReleaseResponseTransfer.buf = malloc(sizeof(uint8_t) * pdusession_release_resp_p->pdusession_release[i].transfer_length); - memcpy(item->pDUSessionResourceReleaseResponseTransfer.buf, - pdusession_release_resp_p->pdusession_release[i].transfer_buffer, - pdusession_release_resp_p->pdusession_release[i].transfer_length); - }else { - item->pDUSessionResourceReleaseResponseTransfer.size = 0; - item->pDUSessionResourceReleaseResponseTransfer.buf = NULL; - NGAP_DEBUG("pdusession_release_resp: transfer_buffer is NULL!\n"); - } - NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID); - asn1cSeqAdd(&ie->value.choice.PDUSessionResourceReleasedListRelRes.list, item); - } - - asn1cSeqAdd(&out->protocolIEs.list, ie); + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceReleaseResponseIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = pdusession_release_resp_p->gNB_ue_ngap_id; } - + /* optional */ + if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceReleaseResponseIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes; + + for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) { + asn1cSequenceAdd(ie->value.choice.PDUSessionResourceReleasedListRelRes.list, NGAP_PDUSessionResourceReleasedItemRelRes_t, item); + item->pDUSessionID = pdusession_release_resp_p->pdusession_release[i].pdusession_id; + allocCopy(&item->pDUSessionResourceReleaseResponseTransfer, pdusession_release_resp_p->pdusession_release[i].data); + NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID); + } + } + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { NGAP_ERROR("Failed to encode release response\n"); /* Encode procedure has failed... */ @@ -1395,17 +1215,17 @@ int ngap_gNB_pdusession_release_resp(instance_t instance, } /* UE associated signalling -> use the allocated stream */ - 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); + 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); NGAP_INFO("pdusession_release_response sended gNB_UE_NGAP_ID %u amf_ue_ngap_id %lu nb_of_pdusessions_released %d nb_of_pdusessions_failed %d\n", - pdusession_release_resp_p->gNB_ue_ngap_id, (uint64_t)ue_context_p->amf_ue_ngap_id,pdusession_release_resp_p->nb_of_pdusessions_released,pdusession_release_resp_p->nb_of_pdusessions_failed); + pdusession_release_resp_p->gNB_ue_ngap_id, + (uint64_t)ue_context_p->amf_ue_ngap_id, + pdusession_release_resp_p->nb_of_pdusessions_released, + pdusession_release_resp_p->nb_of_pdusessions_failed); return 0; } -int ngap_gNB_path_switch_req(instance_t instance, - ngap_path_switch_req_t *path_switch_req_p) +int ngap_gNB_path_switch_req(instance_t instance, ngap_path_switch_req_t *path_switch_req_p) //------------------------------------------------------------------------------ { //TODO @@ -1413,13 +1233,9 @@ int ngap_gNB_path_switch_req(instance_t instance, return 0; } -int ngap_gNB_generate_PDUSESSION_Modification_Indication( - instance_t instance, - ngap_pdusession_modification_ind_t *pdusession_modification_ind) +int ngap_gNB_generate_PDUSESSION_Modification_Indication(instance_t instance, ngap_pdusession_modification_ind_t *pdusession_modification_ind) //----------------------------------------------------------------------------- { //TODO return 0; } - - diff --git a/openair3/NGAP/ngap_gNB_trace.h b/openair3/NGAP/ngap_gNB_trace.h index 91ea07ae80..70863e3737 100644 --- a/openair3/NGAP/ngap_gNB_trace.h +++ b/openair3/NGAP/ngap_gNB_trace.h @@ -30,23 +30,10 @@ #ifndef NGAP_GNB_TRACE_H_ #define NGAP_GNB_TRACE_H_ -// int ngap_gNB_generate_trace_failure(sctp_data_t *sctp_data_p, -// int32_t stream, -// uint32_t gNB_ue_ngap_id, -// uint32_t amf_ue_ngap_id, -// E_UTRAN_Trace_ID_t *trace_id, -// Cause_t *cause_p); - -// int ngap_gNB_handle_trace_start(gNB_amf_desc_t *gNB_desc_p, -// sctp_queue_item_t *packet_p, -// struct ngap_message_s *message_p); int ngap_gNB_handle_trace_start(uint32_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu); -// int ngap_gNB_handle_deactivate_trace(gNB_amf_desc_t *gNB_desc_p, -// sctp_queue_item_t *packet_p, -// struct ngap_message_s *message_p); int ngap_gNB_handle_deactivate_trace(uint32_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu); diff --git a/openair3/NGAP/ngap_gNB_ue_context.c b/openair3/NGAP/ngap_gNB_ue_context.c index 8beb4d9485..0be4fc480e 100644 --- a/openair3/NGAP/ngap_gNB_ue_context.c +++ b/openair3/NGAP/ngap_gNB_ue_context.c @@ -40,8 +40,15 @@ #include "ngap_gNB_defs.h" #include "ngap_gNB_ue_context.h" -int ngap_gNB_compare_gNB_ue_ngap_id( - struct ngap_gNB_ue_context_s *p1, struct ngap_gNB_ue_context_s *p2) +/* Tree of UE ordered by gNB_ue_ngap_id's + * NO INSTANCE, the 32 bits id is large enough to handle all UEs, regardless the cell, gNB, ... + */ +static RB_HEAD(ngap_ue_map, ngap_gNB_ue_context_s) ngap_ue_head = RB_INITIALIZER(&ngap_ue_head); + +/* Generate the tree management functions prototypes */ +RB_PROTOTYPE(ngap_ue_map, ngap_gNB_ue_context_s, entries, ngap_gNB_compare_gNB_ue_ngap_id); + +static int ngap_gNB_compare_gNB_ue_ngap_id(struct ngap_gNB_ue_context_s *p1, struct ngap_gNB_ue_context_s *p2) { if (p1->gNB_ue_ngap_id > p2->gNB_ue_ngap_id) { return 1; @@ -58,46 +65,26 @@ int ngap_gNB_compare_gNB_ue_ngap_id( RB_GENERATE(ngap_ue_map, ngap_gNB_ue_context_s, entries, ngap_gNB_compare_gNB_ue_ngap_id); -struct ngap_gNB_ue_context_s *ngap_gNB_allocate_new_UE_context(void) +void ngap_store_ue_context(struct ngap_gNB_ue_context_s *ue_desc_p) { - struct ngap_gNB_ue_context_s *new_p; + if (RB_INSERT(ngap_ue_map, &ngap_ue_head, ue_desc_p)) + LOG_E(NGAP, "Bug in UE uniq number allocation %u, we try to add a existing UE\n", ue_desc_p->gNB_ue_ngap_id); + return; +} - new_p = malloc(sizeof(struct ngap_gNB_ue_context_s)); +struct ngap_gNB_ue_context_s *ngap_get_ue_context(uint32_t gNB_ue_ngap_id) +{ + ngap_gNB_ue_context_t temp = {.gNB_ue_ngap_id = gNB_ue_ngap_id}; + return RB_FIND(ngap_ue_map, &ngap_ue_head, &temp); +} - if (new_p == NULL) { - NGAP_ERROR("Cannot allocate new ue context\n"); +struct ngap_gNB_ue_context_s *ngap_detach_ue_context(uint32_t gNB_ue_ngap_id) +{ + struct ngap_gNB_ue_context_s *tmp = ngap_get_ue_context(gNB_ue_ngap_id); + if (tmp == NULL) { + NGAP_ERROR("Trying to free a NULL UE context, %u\n", gNB_ue_ngap_id); return NULL; } - - memset(new_p, 0, sizeof(struct ngap_gNB_ue_context_s)); - - return new_p; -} - -struct ngap_gNB_ue_context_s *ngap_gNB_get_ue_context( - ngap_gNB_instance_t *instance_p, - uint32_t gNB_ue_ngap_id) -{ - ngap_gNB_ue_context_t temp; - - memset(&temp, 0, sizeof(struct ngap_gNB_ue_context_s)); - - /* gNB ue ngap id = 32 bits wide */ - temp.gNB_ue_ngap_id = gNB_ue_ngap_id & 0xFFFFFFFF; - - return RB_FIND(ngap_ue_map, &instance_p->ngap_ue_head, &temp); -} - -void ngap_gNB_free_ue_context(struct ngap_gNB_ue_context_s *ue_context_p) -{ - if (ue_context_p == NULL) { - NGAP_ERROR("Trying to free a NULL context\n"); - return; - } - - /* TODO: check that context is currently not in the tree of known - * contexts. - */ - - free(ue_context_p); + RB_REMOVE(ngap_ue_map, &ngap_ue_head, tmp); + return tmp; } diff --git a/openair3/NGAP/ngap_gNB_ue_context.h b/openair3/NGAP/ngap_gNB_ue_context.h index 4b300c6fea..8de03b63ba 100644 --- a/openair3/NGAP/ngap_gNB_ue_context.h +++ b/openair3/NGAP/ngap_gNB_ue_context.h @@ -37,7 +37,6 @@ // Forward declarations struct ngap_gNB_amf_data_s; -struct ngap_ue_map; struct gNB_amf_desc_s; typedef enum { @@ -59,11 +58,7 @@ typedef struct ngap_gNB_ue_context_s { */ uint32_t gNB_ue_ngap_id; - /* UE id for initial connection to NGAP */ - uint16_t ue_initial_id; - - /* Uniquely identifies the UE within AMF. Encoded on 32 bits. */ - uint64_t amf_ue_ngap_id:40; + uint64_t amf_ue_ngap_id; /* Stream used for this particular UE */ int32_t tx_stream; @@ -84,20 +79,9 @@ typedef struct ngap_gNB_ue_context_s { ngap_gNB_instance_t *gNB_instance; } ngap_gNB_ue_context_t; -int ngap_gNB_compare_gNB_ue_ngap_id( - struct ngap_gNB_ue_context_s *p1, struct ngap_gNB_ue_context_s *p2); - -/* Generate the tree management functions prototypes */ -RB_PROTOTYPE(ngap_ue_map, ngap_gNB_ue_context_s, entries, - ngap_gNB_compare_gNB_ue_ngap_id); - -struct ngap_gNB_ue_context_s *ngap_gNB_allocate_new_UE_context(void); - -struct ngap_gNB_ue_context_s *ngap_gNB_get_ue_context( - ngap_gNB_instance_t *instance_p, - uint32_t gNB_ue_ngap_id); - -void ngap_gNB_free_ue_context(struct ngap_gNB_ue_context_s *ue_context_p); +void ngap_store_ue_context(ngap_gNB_ue_context_t *ue_desc_p); +ngap_gNB_ue_context_t *ngap_get_ue_context(uint32_t gNB_ue_ngap_id); +ngap_gNB_ue_context_t *ngap_detach_ue_context(uint32_t gNB_ue_ngap_id); #endif /* NGAP_GNB_UE_CONTEXT_H_ */ diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index 14128dd53e..7706137b2e 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -650,7 +650,7 @@ static void sctp_send_data(sctp_data_req_t *sctp_data_req_p) /* TODO: notify upper layer */ return; } - + free(sctp_data_req_p->buffer); // assuming it has been malloced SCTP_DEBUG("Successfully sent %u bytes on stream %d for assoc_id %u\n", sctp_data_req_p->buffer_length, sctp_data_req_p->stream, sctp_cnx->assoc_id);