diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 9788a70966..3b99bedbe9 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -103,11 +103,6 @@ void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } -void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) -{ - return; -} - void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); } void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) { abort(); } diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 74c9d56918..71f92aebd3 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -103,15 +103,6 @@ void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t { } -void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) -{ - return; -} - -int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { - return 0; -} - void nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]) { (void)alg_type; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 2be1c9a846..e08a8cfb3a 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -99,11 +99,6 @@ void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration -void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) -{ - return; -} - void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); } void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) { abort(); } @@ -696,7 +691,6 @@ int main(int argc, char *argv[]) //Configure UE NR_UE_RRC_INST_t rrcue = {0}; - rrcue.mib = mib->message.choice.mib; rrcue.scell_group_config = secondaryCellGroup; nr_l2_init_ue(&rrcue); diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index 8609aa45d2..e4881f8d8a 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -76,7 +76,7 @@ MESSAGE_DEF(NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, NasConnRelea MESSAGE_DEF(NAS_UPLINK_DATA_CNF, MESSAGE_PRIORITY_MED, NasUlDataCnf, nas_ul_data_cnf) MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd, nas_dl_data_ind) -// eNB: realtime -> RRC messages +// xNB: realtime -> RRC messages MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeProcess, rrc_subframe_process) MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFrameProcess, nr_rrc_frame_process) diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index a566a15d66..5e77829680 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -42,7 +42,6 @@ #include "SCHED_NR_UE/fapi_nr_ue_l1.h" #include "executables/softmodem-common.h" #include "openair2/RRC/NR_UE/rrc_proto.h" -#include "openair2/RRC/NR_UE/rrc_vars.h" #include "openair2/GNB_APP/L1_nr_paramdef.h" #include "openair2/GNB_APP/gnb_paramdef.h" #include "radio/ETHERNET/if_defs.h" diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 0cdac830d0..9c5746ce00 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -5380,8 +5380,6 @@ openair_rrc_top_init_ue( for (module_id = 0; module_id < NB_UE_INST; module_id++) { UE_rrc_inst[module_id].UECap = UECap; - UE_rrc_inst[module_id].UECapability = UECap->sdu; - UE_rrc_inst[module_id].UECapability_size = UECap->sdu_size; } LOG_I(RRC,"[UE] eMBMS active state is %d \n", eMBMS_active); @@ -6596,9 +6594,6 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len) { fill_ue_capability(NULL, received_nr_msg); UE_rrc_inst[module_id].UECap = UE_rrc_inst->UECap; - UE_rrc_inst[module_id].UECapability = UE_rrc_inst->UECap->sdu; - UE_rrc_inst[module_id].UECapability_size = UE_rrc_inst->UECap->sdu_size; - if (!is_en_dc_supported(UE_rrc_inst->UECap->UE_EUTRA_Capability)) { LOG_E(RRC, "en_dc is NOT supported! Not sending RRC_DCCH_DATA_COPY_IND to update UE_Capability_INFO\n"); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 3093298005..c6115c555d 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -771,41 +771,37 @@ int16_t do_RRCReconfiguration(const gNB_RRC_UE_t *UE, return((enc_rval.encoded+7)/8); } - -int do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, uint8_t *rv) +int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv) { - asn_enc_rval_t enc_rval; - uint8_t buf[5],buf2=0; - NR_UL_CCCH_Message_t ul_ccch_msg; - NR_RRCSetupRequest_t *rrcSetupRequest; - memset((void *)&ul_ccch_msg,0,sizeof(NR_UL_CCCH_Message_t)); + NR_UL_CCCH_Message_t ul_ccch_msg = {0}; ul_ccch_msg.message.present = NR_UL_CCCH_MessageType_PR_c1; - ul_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_CCCH_MessageType__c1)); - ul_ccch_msg.message.choice.c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest; - ul_ccch_msg.message.choice.c1->choice.rrcSetupRequest = CALLOC(1, sizeof(NR_RRCSetupRequest_t)); - rrcSetupRequest = ul_ccch_msg.message.choice.c1->choice.rrcSetupRequest; - + asn1cCalloc(ul_ccch_msg.message.choice.c1, c1); + c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest; + asn1cCalloc(c1->choice.rrcSetupRequest, rrcSetupRequest); if (1) { rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_randomValue; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.size = 5; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.bits_unused = 1; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf = buf; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[0] = rv[0]; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[1] = rv[1]; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[2] = rv[2]; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[3] = rv[3]; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[4] = rv[4]&0xfe; + BIT_STRING_t *str = &rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue; + str->size = 5; + str->bits_unused = 1; + str->buf = CALLOC(1, str->size); + str->buf[0] = rv[0]; + str->buf[1] = rv[1]; + str->buf[2] = rv[2]; + str->buf[3] = rv[3]; + str->buf[4] = rv[4] & 0xfe; } else { rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.size = 1; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.bits_unused = 0; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.buf = buf; - rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.buf[0] = 0x12; + BIT_STRING_t *str = &rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1; + str->size = 1; + str->bits_unused = 0; + str->buf = CALLOC(1, str->size); + str->buf[0] = 0x12; } rrcSetupRequest->rrcSetupRequest.establishmentCause = NR_EstablishmentCause_mo_Signalling; //EstablishmentCause_mo_Data; - rrcSetupRequest->rrcSetupRequest.spare.buf = &buf2; + rrcSetupRequest->rrcSetupRequest.spare.buf = CALLOC(1, 1); + rrcSetupRequest->rrcSetupRequest.spare.buf[0] = 0; // spare not used rrcSetupRequest->rrcSetupRequest.spare.size=1; rrcSetupRequest->rrcSetupRequest.spare.bits_unused = 7; @@ -813,13 +809,10 @@ int do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, uint xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg); } - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message, - NULL, - (void *)&ul_ccch_msg, - buffer, - buffer_size); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message, NULL, (void *)&ul_ccch_msg, buffer, buffer_size); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); LOG_D(NR_RRC,"[UE] RRCSetupRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_CCCH_Message, &ul_ccch_msg); return((enc_rval.encoded+7)/8); } @@ -857,42 +850,28 @@ do_NR_RRCReconfigurationComplete_for_nsa( } //------------------------------------------------------------------------------ -uint8_t -do_NR_RRCReconfigurationComplete( - const protocol_ctxt_t *const ctxt_pP, - uint8_t *buffer, - size_t buffer_size, - const uint8_t Transaction_id -) +uint8_t do_NR_RRCReconfigurationComplete(uint8_t *buffer, size_t buffer_size, const uint8_t Transaction_id) //------------------------------------------------------------------------------ { - asn_enc_rval_t enc_rval; - NR_UL_DCCH_Message_t ul_dcch_msg; - NR_RRCReconfigurationComplete_t *rrcReconfigurationComplete; - memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); + NR_UL_DCCH_Message_t ul_dcch_msg = {0}; ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; - ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1)); - ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete; - ul_dcch_msg.message.choice.c1->choice.rrcReconfigurationComplete = CALLOC(1, sizeof(NR_RRCReconfigurationComplete_t)); - rrcReconfigurationComplete = ul_dcch_msg.message.choice.c1->choice.rrcReconfigurationComplete; - rrcReconfigurationComplete->rrc_TransactionIdentifier = Transaction_id; - rrcReconfigurationComplete->criticalExtensions.choice.rrcReconfigurationComplete = CALLOC(1, sizeof(NR_RRCReconfigurationComplete_IEs_t)); - rrcReconfigurationComplete->criticalExtensions.present = - NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete; - rrcReconfigurationComplete->criticalExtensions.choice.rrcReconfigurationComplete->nonCriticalExtension = NULL; - rrcReconfigurationComplete->criticalExtensions.choice.rrcReconfigurationComplete->lateNonCriticalExtension = NULL; + asn1cCalloc(ul_dcch_msg.message.choice.c1, c1); + c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete; + asn1cCalloc(c1->choice.rrcReconfigurationComplete, reconfComplete); + reconfComplete->rrc_TransactionIdentifier = Transaction_id; + reconfComplete->criticalExtensions.present = NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete; + asn1cCalloc(reconfComplete->criticalExtensions.choice.rrcReconfigurationComplete, extension); + extension->nonCriticalExtension = NULL; + extension->lateNonCriticalExtension = NULL; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); } - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, - NULL, - (void *)&ul_dcch_msg, - buffer, - buffer_size); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, buffer_size); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); LOG_I(NR_RRC,"rrcReconfigurationComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg); return((enc_rval.encoded+7)/8); } diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 737f65cb85..a0ffb8971f 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -117,16 +117,11 @@ uint8_t do_RRCSetupComplete(uint8_t Mod_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS); -int do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, uint8_t *rv); +int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv); uint8_t do_NR_RRCReconfigurationComplete_for_nsa(uint8_t *buffer, size_t buffer_size, NR_RRC_TransactionIdentifier_t Transaction_id); -uint8_t do_NR_RRCReconfigurationComplete( - const protocol_ctxt_t *const ctxt_pP, - uint8_t *buffer, - size_t buffer_size, - const uint8_t Transaction_id - ); +uint8_t do_NR_RRCReconfigurationComplete(uint8_t *buffer, size_t buffer_size, const uint8_t Transaction_id); uint8_t do_NR_DLInformationTransfer(uint8_t Mod_id, uint8_t *buffer, diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 3a90e099e8..583210bb53 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -33,9 +33,9 @@ #include "rrc_defs.h" #include "rrc_proto.h" #include "assertions.h" -#include "rrc_vars.h" #include "MAC/mac.h" #include "LAYER2/NR_MAC_COMMON/nr_mac.h" +#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" typedef uint32_t channel_t; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index b8a55e71e3..e6712676e0 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -34,7 +34,6 @@ #define RRC_UE_C #include "oai_asn1.h" - #include "NR_DL-DCCH-Message.h" //asn_DEF_NR_DL_DCCH_Message #include "NR_DL-CCCH-Message.h" //asn_DEF_NR_DL_CCCH_Message #include "NR_BCCH-BCH-Message.h" //asn_DEF_NR_BCCH_BCH_Message @@ -49,7 +48,6 @@ #include "rrc_defs.h" #include "rrc_proto.h" -#include "rrc_vars.h" #include "LAYER2/NR_MAC_UE/mac_proto.h" #include "COMMON/mac_rrc_primitives.h" @@ -75,155 +73,218 @@ #include "nr_nas_msg_sim.h" -NR_UE_RRC_INST_t *NR_UE_rrc_inst; +static NR_UE_RRC_INST_t *NR_UE_rrc_inst; /* NAS Attach request with IMSI */ -static const char nr_nas_attach_req_imsi[] = { - 0x07, 0x41, - /* EPS Mobile identity = IMSI */ - 0x71, 0x08, 0x29, 0x80, 0x43, 0x21, 0x43, 0x65, 0x87, - 0xF9, - /* End of EPS Mobile Identity */ - 0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03, - 0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00, - 0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2, - 0x01, 0x27, 0x11, +static const char nr_nas_attach_req_imsi_dummy_NSA_case[] = { + 0x07, + 0x41, + /* EPS Mobile identity = IMSI */ + 0x71, + 0x08, + 0x29, + 0x80, + 0x43, + 0x21, + 0x43, + 0x65, + 0x87, + 0xF9, + /* End of EPS Mobile Identity */ + 0x02, + 0xE0, + 0xE0, + 0x00, + 0x20, + 0x02, + 0x03, + 0xD0, + 0x11, + 0x27, + 0x1A, + 0x80, + 0x80, + 0x21, + 0x10, + 0x01, + 0x00, + 0x00, + 0x10, + 0x81, + 0x06, + 0x00, + 0x00, + 0x00, + 0x00, + 0x83, + 0x06, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0D, + 0x00, + 0x00, + 0x0A, + 0x00, + 0x52, + 0x12, + 0xF2, + 0x01, + 0x27, + 0x11, }; -void -nr_rrc_ue_process_ueCapabilityEnquiry( - const protocol_ctxt_t *const ctxt_pP, - NR_UECapabilityEnquiry_t *UECapabilityEnquiry, - uint8_t gNB_index -); +static void nr_rrc_manage_rlc_bearers(const instance_t instance, + const NR_CellGroupConfig_t *cellGroupConfig, + rrcPerNB_t *rrc, + const rnti_t rnti); -uint8_t do_NR_RRCReconfigurationComplete( - const protocol_ctxt_t *const ctxt_pP, - uint8_t *buffer, - size_t buffer_size, - const uint8_t Transaction_id - ); +static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, + rnti_t rnti, + rrcPerNB_t *rrcNB, + NR_RadioBearerConfig_t *const radioBearerConfig); +static void nr_rrc_ue_generate_RRCSetupRequest(rnti_t rnti); +static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment); +static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_len); +static void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config); +static void nr_rrc_ue_process_rrcReconfiguration(const instance_t instance, + int gNB_index, + rnti_t rnti, + NR_RRCReconfiguration_t *rrcReconfiguration); -void -nr_rrc_ue_generate_rrcReestablishmentComplete( - const protocol_ctxt_t *const ctxt_pP, - NR_RRCReestablishment_t *rrcReestablishment, - uint8_t gNB_index -); +static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECapabilityEnquiry_t *UECapabilityEnquiry); +static void nr_rrc_ue_process_masterCellGroup(instance_t instance, + rnti_t rnti, + rrcPerNB_t *rrcNB, + OCTET_STRING_t *masterCellGroup, + long *fullConfig); -mui_t nr_rrc_mui=0; +void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig); // from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded) -int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, NR_CellGroupConfig_t *cell_group_config) +static int8_t nr_rrc_ue_decode_secondary_cellgroup_config(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cell_group_config) { - if(NR_UE_rrc_inst[module_id].scell_group_config == NULL) - NR_UE_rrc_inst[module_id].scell_group_config = cell_group_config; + if (rrc->scell_group_config == NULL) + rrc->scell_group_config = cell_group_config; else SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 0); if(cell_group_config->spCellConfig != NULL) - configure_spcell(&NR_UE_rrc_inst[module_id], cell_group_config->spCellConfig); + configure_spcell(rrc, cell_group_config->spCellConfig); return 0; } -// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (decoded) -// RRCReconfiguration -int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration) +static void nr_rrc_ue_process_rrcReconfiguration(const instance_t instance, + int gNB_index, + rnti_t rnti, + NR_RRCReconfiguration_t *rrcReconfiguration) { - switch(rrcReconfiguration->criticalExtensions.present){ - case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration: - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig != NULL){ - if(NR_UE_rrc_inst[module_id].radio_bearer_config == NULL){ - NR_UE_rrc_inst[module_id].radio_bearer_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig; - }else{ - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - struct NR_RadioBearerConfig *RadioBearerConfig = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig; - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *) RadioBearerConfig); + NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance]; + rrcPerNB_t *rrcNB = NR_UE_rrc_inst[instance].perNB + gNB_index; + + switch (rrcReconfiguration->criticalExtensions.present) { + case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration: { + NR_RRCReconfiguration_IEs_t *ie = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration; + + if (ie->radioBearerConfig != NULL) { + if (rrc->radio_bearer_config == NULL) + rrc->radio_bearer_config = ie->radioBearerConfig; + LOG_I(NR_RRC, "radio Bearer Configuration is present\n"); + nr_rrc_ue_process_RadioBearerConfig(rrc, rnti, rrcNB, ie->radioBearerConfig); + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ie->radioBearerConfig); + } + + if (ie->nonCriticalExtension) { + NR_RRCReconfiguration_v1530_IEs_t *ext = ie->nonCriticalExtension; + if (ext->masterCellGroup) + nr_rrc_ue_process_masterCellGroup(instance, rnti, rrcNB, ext->masterCellGroup, ext->fullConfig); + /* Check if there is dedicated NAS information to forward to NAS */ + if (ie->nonCriticalExtension->dedicatedNAS_MessageList) { + struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *tmp = ext->dedicatedNAS_MessageList; + for (int i = 0; i < tmp->list.count; i++) { + MessageDef *ittiMsg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_ESTABLI_CNF); + NasConnEstabCnf *msg = &NAS_CONN_ESTABLI_CNF(ittiMsg); + msg->errCode = AS_SUCCESS; + msg->nasMsg.length = tmp->list.array[i]->size; + msg->nasMsg.data = tmp->list.array[i]->buf; + itti_send_msg_to_task(TASK_NAS_NRUE, instance, ittiMsg); } + tmp->list.count = 0; // to prevent the automatic free by ASN1_FREE } } - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){ - NR_CellGroupConfig_t *cellGroupConfig = NULL; - int size = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size; - uint8_t *buffer = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf; - asn_dec_rval_t dec_rval = - uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, // might be added prefix later - (void **)&cellGroupConfig, - (uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf, - size, - 0, - 0); + + if (ie->secondaryCellGroup != NULL) { + NR_CellGroupConfig_t *secondCellGroupConfig = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_CellGroupConfig, // might be added prefix later + (void **)&secondCellGroupConfig, + (uint8_t *)ie->secondaryCellGroup->buf, + ie->secondaryCellGroup->size, + 0, + 0); if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + uint8_t *buffer = ie->secondaryCellGroup->buf; LOG_E(NR_RRC, "NR_CellGroupConfig decode error\n"); - for (int i = 0; i < size; i++) + for (int i = 0; i < ie->secondaryCellGroup->size; i++) LOG_E(NR_RRC, "%02x ", buffer[i]); LOG_E(NR_RRC, "\n"); // free the memory - SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cellGroupConfig, 1); - return -1; + SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)secondCellGroupConfig, 1); + return; } - - if (get_softmodem_params()->sa || get_softmodem_params()->nsa) - nr_rrc_manage_rlc_bearers(cellGroupConfig, &NR_UE_rrc_inst[module_id], 0, module_id, NR_UE_rrc_inst[module_id].rnti); + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *)secondCellGroupConfig); if (get_softmodem_params()->sa || get_softmodem_params()->nsa) { - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); - } - - if(NR_UE_rrc_inst[module_id].cell_group_config == NULL) { - // first time receive the configuration, just use the memory allocated from uper_decoder. TODO this is not good implementation, need to maintain RRC_INST own structure every time. - NR_UE_rrc_inst[module_id].cell_group_config = cellGroupConfig; - }else { + // remote NB index lost ???? + nr_rrc_manage_rlc_bearers(instance, secondCellGroupConfig, rrc->perNB + 0, rrc->rnti); + if (rrc->cell_group_config == NULL) { + // first time receive the configuration, just use the memory allocated from uper_decoder. TODO this is not good + // implementation, need to maintain RRC_INST own structure every time. + rrc->cell_group_config = secondCellGroupConfig; + } else { // after first time, update it and free the memory after. - SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)NR_UE_rrc_inst[module_id].cell_group_config, 0); - NR_UE_rrc_inst[module_id].cell_group_config = cellGroupConfig; + SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)rrc->cell_group_config, 0); + rrc->cell_group_config = secondCellGroupConfig; } - if(cellGroupConfig->spCellConfig != NULL) - configure_spcell(&NR_UE_rrc_inst[module_id], cellGroupConfig->spCellConfig); + if (secondCellGroupConfig->spCellConfig != NULL) + configure_spcell(rrc, secondCellGroupConfig->spCellConfig); if (get_softmodem_params()->nsa) { - nr_rrc_mac_config_req_scg(0, 0, cellGroupConfig); + nr_rrc_mac_config_req_scg(0, 0, secondCellGroupConfig); } } else - nr_rrc_ue_decode_secondary_cellgroup_config(module_id, cellGroupConfig); + nr_rrc_ue_decode_secondary_cellgroup_config(rrc, secondCellGroupConfig); } - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig != NULL){ - if(NR_UE_rrc_inst[module_id].meas_config == NULL){ - NR_UE_rrc_inst[module_id].meas_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig; - }else{ + if (ie->measConfig != NULL) { + LOG_I(NR_RRC, "Measurement Configuration is present\n"); + if (rrc->meas_config == NULL) { + rrc->meas_config = ie->measConfig; + } else { // if some element need to be updated - nr_rrc_ue_process_meas_config(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig); + nr_rrc_ue_process_measConfig(rrcNB, ie->measConfig); } } - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->lateNonCriticalExtension != NULL){ + if (ie->lateNonCriticalExtension != NULL) { // unuse now } - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->nonCriticalExtension != NULL){ - // unuse now - } - break; - + } break; + case NR_RRCReconfiguration__criticalExtensions_PR_NOTHING: case NR_RRCReconfiguration__criticalExtensions_PR_criticalExtensionsFuture: default: break; } - return 0; + return; } -int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config){ - - return 0; -} - -void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len) +static void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len) { - module_id_t module_id=0; // TODO switch (nsa_message_type) { case nr_SecondaryCellGroupConfig_r15: { @@ -240,7 +301,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 ); return; } - nr_rrc_ue_process_rrcReconfiguration(module_id,RRCReconfiguration); + nr_rrc_ue_process_rrcReconfiguration(0, 0, rrc->rnti, RRCReconfiguration); ASN_STRUCT_FREE(asn_DEF_NR_RRCReconfiguration, RRCReconfiguration); } break; @@ -261,19 +322,15 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, return; } if (get_softmodem_params()->nsa) { - protocol_ctxt_t ctxt; - NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_id, ENB_FLAG_YES, mac->crnti, 0, 0, 0); LOG_D(NR_RRC, "Calling nr_rrc_ue_process_RadioBearerConfig() at %d with: e_rab_id = %ld, drbID = %ld, cipher_algo = %ld, key = %ld \n", __LINE__, RadioBearerConfig->drb_ToAddModList->list.array[0]->cnAssociation->choice.eps_BearerIdentity, RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity, RadioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm, *RadioBearerConfig->securityConfig->keyToUse); - nr_rrc_ue_process_RadioBearerConfig(&ctxt, 0, RadioBearerConfig); - } - else if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *) RadioBearerConfig); + nr_rrc_ue_process_RadioBearerConfig(rrc, rrc->rnti, rrc->perNB + 0, RadioBearerConfig); } + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)RadioBearerConfig); ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, RadioBearerConfig); } break; @@ -298,15 +355,15 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi rrc->as_security_activated = false; for (int i = 0; i < NB_CNX_UE; i++) { - memset((void *)&rrc->SInfo[i], 0, sizeof(rrc->SInfo[i])); + rrcPerNB_t *ptr = &rrc->perNB[i]; + ptr->SInfo = (NR_UE_RRC_SI_INFO){0}; for (int j = 0; j < NR_NUM_SRB; j++) - memset((void *)&rrc->Srb[i][j], 0, sizeof(rrc->Srb[i][j])); + ptr->Srb[j] = (NR_UE_RRC_SRB_INFO_t){0}; for (int j = 0; j < MAX_DRBS_PER_UE; j++) - rrc->active_DRBs[i][j] = false; + ptr->active_DRBs[j] = false; // SRB0 activated by default - rrc->Srb[i][0].status = RB_ESTABLISHED; + ptr->Srb[0].status = RB_ESTABLISHED; } - rrc->ra_trigger = RA_NOT_RUNNING; } NR_UE_rrc_inst->uecap_file = uecap_file; @@ -351,21 +408,6 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi return NR_UE_rrc_inst; } -int8_t nr_ue_process_secondary_cell_list(NR_CellGroupConfig_t *cell_group_config){ - - return 0; -} - -int8_t nr_ue_process_mac_cell_group_config(NR_MAC_CellGroupConfig_t *mac_cell_group_config){ - - return 0; -} - -int8_t nr_ue_process_physical_cell_group_config(NR_PhysicalCellGroupConfig_t *phy_cell_group_config){ - - return 0; -} - bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type) { switch (si_type) { @@ -453,41 +495,34 @@ int check_si_status(NR_UE_RRC_SI_INFO *SI_info) } /*brief decode BCCH-BCH (MIB) message*/ -int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) +static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(const instance_t instance, + const uint8_t gNB_index, + uint8_t *const bufferP, + const uint8_t buffer_len) { NR_BCCH_BCH_Message_t *bcch_message = NULL; - if (NR_UE_rrc_inst[module_id].mib == NULL) - LOG_A(NR_RRC, "Configuring MAC for first MIB reception\n"); - asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)&bcch_message, (const void *)bufferP, buffer_len); - int ret; if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { LOG_E(NR_RRC, "NR_BCCH_BCH decode error\n"); - ret = -1; - } else { - // link to rrc instance - ASN_STRUCT_FREE(asn_DEF_NR_MIB, NR_UE_rrc_inst[module_id].mib); - NR_UE_rrc_inst[module_id].mib = bcch_message->message.choice.mib; - bcch_message->message.choice.mib = NULL; - - int get_sib = 0; - if (get_softmodem_params()->sa && NR_UE_rrc_inst[module_id].mib->cellBarred == NR_MIB__cellBarred_notBarred) { - NR_UE_RRC_SI_INFO *SI_info = &NR_UE_rrc_inst[module_id].SInfo[gNB_index]; - // to schedule MAC to get SI if required - get_sib = check_si_status(SI_info); - } - nr_rrc_mac_config_req_mib(module_id, 0, NR_UE_rrc_inst[module_id].mib, get_sib); - ret = 0; + return; } + + int get_sib = 0; + if (get_softmodem_params()->sa && bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred) { + NR_UE_RRC_SI_INFO *SI_info = &NR_UE_rrc_inst[instance].perNB[gNB_index].SInfo; + // to schedule MAC to get SI if required + get_sib = check_si_status(SI_info); + } + nr_rrc_mac_config_req_mib(instance, 0, bcch_message->message.choice.mib, get_sib); + bcch_message->message.choice.mib = NULL; ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, bcch_message); - return ret; + return; } -int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_SystemInformation_t *si) +static int nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si) { - NR_UE_RRC_SI_INFO *SI_info = &NR_UE_rrc_inst[module_id].SInfo[gNB_index]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN ); // Dump contents @@ -503,22 +538,20 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System for (int i = 0; i < si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count; i++) { SystemInformation_IEs__sib_TypeAndInfo__Member *typeandinfo; typeandinfo = si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.array[i]; - + LOG_I(RRC, "Found SIB%d\n", typeandinfo->present + 1); switch(typeandinfo->present) { case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2: if(!SI_info->sib2) SI_info->sib2 = calloc(1, sizeof(*SI_info->sib2)); memcpy(SI_info->sib2, typeandinfo->choice.sib2, sizeof(NR_SIB2_t)); SI_info->sib2_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB2 from gNB %"PRIu8"\n", module_id, gNB_index); - break; // case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 + break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3: if(!SI_info->sib3) SI_info->sib3 = calloc(1, sizeof(*SI_info->sib3)); memcpy(SI_info->sib3, typeandinfo->choice.sib3, sizeof(NR_SIB3_t)); SI_info->sib3_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB3 from gNB %"PRIu8"\n", module_id, gNB_index ); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib4: @@ -526,7 +559,6 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System SI_info->sib4 = calloc(1, sizeof(*SI_info->sib4)); memcpy(SI_info->sib4, typeandinfo->choice.sib4, sizeof(NR_SIB4_t)); SI_info->sib4_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB4 from gNB %"PRIu8"\n", module_id, gNB_index); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib5: @@ -534,7 +566,6 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System SI_info->sib5 = calloc(1, sizeof(*SI_info->sib5)); memcpy(SI_info->sib5, typeandinfo->choice.sib5, sizeof(NR_SIB5_t)); SI_info->sib5_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB5 from gNB %"PRIu8"\n", module_id, gNB_index); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib6: @@ -542,7 +573,6 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System SI_info->sib6 = calloc(1, sizeof(*SI_info->sib6)); memcpy(SI_info->sib6, typeandinfo->choice.sib6, sizeof(NR_SIB6_t)); SI_info->sib6_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB6 from gNB %"PRIu8"\n", module_id, gNB_index); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib7: @@ -550,7 +580,6 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System SI_info->sib7 = calloc(1, sizeof(*SI_info->sib7)); memcpy(SI_info->sib7, typeandinfo->choice.sib7, sizeof(NR_SIB7_t)); SI_info->sib7_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB7 from gNB %"PRIu8"\n", module_id, gNB_index); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib8: @@ -558,7 +587,6 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System SI_info->sib8 = calloc(1, sizeof(*SI_info->sib8)); memcpy(SI_info->sib8, typeandinfo->choice.sib8, sizeof(NR_SIB8_t)); SI_info->sib8_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB8 from gNB %"PRIu8"\n", module_id, gNB_index); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib9: @@ -566,7 +594,6 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System SI_info->sib9 = calloc(1, sizeof(*SI_info->sib9)); memcpy(SI_info->sib9, typeandinfo->choice.sib9, sizeof(NR_SIB9_t)); SI_info->sib9_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB9 from gNB %"PRIu8"\n", module_id, gNB_index); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib10_v1610: @@ -574,7 +601,6 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System SI_info->sib10 = calloc(1, sizeof(*SI_info->sib10)); memcpy(SI_info->sib10, typeandinfo->choice.sib10_v1610, sizeof(NR_SIB10_r16_t)); SI_info->sib10_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB10 from gNB %"PRIu8"\n", module_id, gNB_index); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib11_v1610: @@ -582,7 +608,6 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System SI_info->sib11 = calloc(1, sizeof(*SI_info->sib11)); memcpy(SI_info->sib11, typeandinfo->choice.sib11_v1610, sizeof(NR_SIB11_r16_t)); SI_info->sib11_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB11 from gNB %"PRIu8"\n", module_id, gNB_index); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib12_v1610: @@ -590,7 +615,6 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System SI_info->sib12 = calloc(1, sizeof(*SI_info->sib12)); memcpy(SI_info->sib12, typeandinfo->choice.sib12_v1610, sizeof(NR_SIB12_r16_t)); SI_info->sib12_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB12 from gNB %"PRIu8"\n", module_id, gNB_index); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib13_v1610: @@ -598,7 +622,6 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System SI_info->sib13 = calloc(1, sizeof(*SI_info->sib13)); memcpy(SI_info->sib13, typeandinfo->choice.sib13_v1610, sizeof(NR_SIB13_r16_t)); SI_info->sib13_timer = 0; - LOG_I( RRC, "[UE %"PRIu8"] Found SIB13 from gNB %"PRIu8"\n", module_id, gNB_index ); break; case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib14_v1610: @@ -606,8 +629,7 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System SI_info->sib14 = calloc(1, sizeof(*SI_info->sib14)); memcpy(SI_info->sib12, typeandinfo->choice.sib14_v1610, sizeof(NR_SIB14_r16_t)); SI_info->sib14_timer = 0; - LOG_I(RRC, "[UE %"PRIu8"] Found SIB14 from gNB %"PRIu8"\n", module_id, gNB_index); - break; + break; default: break; } @@ -616,12 +638,12 @@ int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_System return 0; } -void nr_rrc_ue_generate_ra_msg(module_id_t module_id, int rnti) +void nr_rrc_ue_generate_ra_msg(instance_t instance, RA_trigger_t trigger, rnti_t rnti) { - switch(NR_UE_rrc_inst[module_id].ra_trigger) { + switch (trigger) { case INITIAL_ACCESS_FROM_RRC_IDLE: // After SIB1 is received, prepare RRCConnectionRequest - nr_rrc_ue_generate_RRCSetupRequest(module_id, rnti); + nr_rrc_ue_generate_RRCSetupRequest(rnti); break; case RRC_CONNECTION_REESTABLISHMENT: AssertFatal(1==0, "ra_trigger not implemented yet!\n"); @@ -650,7 +672,7 @@ void nr_rrc_ue_generate_ra_msg(module_id_t module_id, int rnti) } } -void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, int rnti) +static void nr_rrc_ue_generate_RRCSetupRequest(rnti_t rnti) { uint8_t rv[6]; // Get RRCConnectionRequest, fill random for now @@ -665,7 +687,7 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, int rnti) } uint8_t buf[1024]; - int len = do_RRCSetupRequest(module_id, buf, sizeof(buf), rv); + int len = do_RRCSetupRequest(buf, sizeof(buf), rv); /* convention: RNTI for SRB0 is zero, as it changes all the time */ nr_rlc_srb_recv_sdu(rnti, 0, buf, len); @@ -688,13 +710,13 @@ void nr_rrc_configure_default_SI(NR_UE_RRC_SI_INFO *SI_info, } /**\brief decode NR BCCH-DLSCH (SI) messages - \param module_idP module id + \param instanceP module id \param gNB_index gNB index \param sduP pointer to buffer of ASN message BCCH-DLSCH \param sdu_len length of buffer \param rsrq RSRQ \param rsrp RSRP*/ -static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, +static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(instance_t instance, const uint8_t gNB_index, uint8_t *const Sdu, const uint8_t Sdu_len, @@ -702,8 +724,8 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, const uint8_t rsrp) { NR_BCCH_DL_SCH_Message_t *bcch_message = NULL; - NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[module_id]; - NR_UE_RRC_SI_INFO *SI_info = &rrc->SInfo[gNB_index]; + NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance]; + NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN); asn_dec_rval_t dec_rval = uper_decode_complete(NULL, @@ -717,9 +739,7 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, } if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", - module_id, - dec_rval.consumed); + LOG_E(NR_RRC, "[UE %ld] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", instance, dec_rval.consumed); log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n"); // free the memory SEQUENCE_free(&asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1); @@ -730,7 +750,7 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) { switch (bcch_message->message.choice.c1->present) { case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: - LOG_D(NR_RRC, "[UE %"PRIu8"] Decoding SIB1\n", module_id); + LOG_D(NR_RRC, "[UE %ld] Decoding SIB1\n", instance); if(SI_info->sib1) ASN_STRUCT_FREE(asn_DEF_NR_SIB1, SI_info->sib1); NR_SIB1_t *sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; @@ -740,8 +760,7 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, LOG_A(NR_RRC, "SIB1 decoded\n"); SI_info->sib1_timer = 0; // FIXME: improve condition for the RA trigger - if(rrc->nrRrcState == RRC_STATE_IDLE_NR) { - rrc->ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE; + if (rrc->nrRrcState == RRC_STATE_IDLE_NR) { LOG_D(PHY,"Setting state to RRC_STATE_IDLE_NR\n"); } // configure default SI @@ -750,12 +769,12 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, sib1); // take ServingCellConfigCommon and configure L1/L2 rrc->servingCellConfigCommonSIB = sib1->servingCellConfigCommon; - nr_rrc_mac_config_req_sib1(module_id, 0, sib1->si_SchedulingInfo, sib1->servingCellConfigCommon); + nr_rrc_mac_config_req_sib1(instance, 0, sib1->si_SchedulingInfo, sib1->servingCellConfigCommon); break; case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: - LOG_I(NR_RRC, "[UE %"PRIu8"] Decoding SI\n", module_id); + LOG_I(NR_RRC, "[UE %ld] Decoding SI\n", instance); NR_SystemInformation_t *si = bcch_message->message.choice.c1->choice.systemInformation; - nr_decode_SI(module_id, gNB_index, si); + nr_decode_SI(&NR_UE_rrc_inst[instance].perNB[gNB_index].SInfo, si); SEQUENCE_free(&asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1); break; case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: @@ -767,11 +786,10 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, return 0; } -void nr_rrc_manage_rlc_bearers(const NR_CellGroupConfig_t *cellGroupConfig, - NR_UE_RRC_INST_t *rrc, - int gNB_index, - module_id_t module_id, - int rnti) +static void nr_rrc_manage_rlc_bearers(const instance_t instance, + const NR_CellGroupConfig_t *cellGroupConfig, + rrcPerNB_t *rrc, + const rnti_t rnti) { if (cellGroupConfig->rlc_BearerToReleaseList != NULL) { for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) { @@ -785,12 +803,12 @@ void nr_rrc_manage_rlc_bearers(const NR_CellGroupConfig_t *cellGroupConfig, for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) { NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i]; NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity; - if (rrc->active_RLC_entity[gNB_index][lcid]) { + if (rrc->active_RLC_entity[lcid]) { if (rlc_bearer->reestablishRLC) nr_rlc_reestablish_entity(rnti, lcid); nr_rlc_reconfigure_entity(rnti, lcid, rlc_bearer->rlc_Config, rlc_bearer->mac_LogicalChannelConfig); } else { - rrc->active_RLC_entity[gNB_index][lcid] = true; + rrc->active_RLC_entity[lcid] = true; AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n"); AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING, "Invalid RB for RLC configuration\n"); @@ -804,16 +822,18 @@ void nr_rrc_manage_rlc_bearers(const NR_CellGroupConfig_t *cellGroupConfig, } } } - nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id, + nr_rrc_mac_config_req_ue_logicalChannelBearer(instance, cellGroupConfig->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToReleaseList); } -void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP, - uint8_t gNB_index, - OCTET_STRING_t *masterCellGroup, - long *fullConfig) +static void nr_rrc_ue_process_masterCellGroup(instance_t instance, + rnti_t rnti, + rrcPerNB_t *rrcNB, + OCTET_STRING_t *masterCellGroup, + long *fullConfig) { + NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance]; NR_CellGroupConfig_t *cellGroupConfig = NULL; uper_decode(NULL, &asn_DEF_NR_CellGroupConfig, //might be added prefix later @@ -825,13 +845,10 @@ void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP, xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); } - NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[ctxt_pP->module_id]; - if(rrc->cell_group_config == NULL){ rrc->cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t)); } - - nr_rrc_manage_rlc_bearers(cellGroupConfig, rrc, gNB_index, ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid); + nr_rrc_manage_rlc_bearers(instance, cellGroupConfig, rrcNB, rnti); if(cellGroupConfig->mac_CellGroupConfig != NULL){ //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5) @@ -875,12 +892,12 @@ void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP, rrc->cell_group_config = cellGroupConfig; } LOG_D(RRC,"Sending CellGroupConfig to MAC\n"); - nr_rrc_mac_config_req_mcg(ctxt_pP->module_id, 0, cellGroupConfig); + nr_rrc_mac_config_req_mcg(instance, 0, cellGroupConfig); } if(fullConfig) // full configuration after re-establishment or during RRC resume - nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, rrc->SInfo[gNB_index].sib1); + nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, rrcNB->SInfo.sib1); if( cellGroupConfig->sCellToAddModList != NULL){ //TODO (perform SCell addition/modification as specified in 5.3.5.5.9) @@ -895,7 +912,7 @@ void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP, } } -void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config) +static void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config) { nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spcell_config->rlf_TimersAndConstants); @@ -940,10 +957,7 @@ void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config) } } -static void rrc_ue_generate_RRCSetupComplete(const protocol_ctxt_t *const ctxt_pP, - const uint8_t gNB_index, - const uint8_t Transaction_id, - uint8_t sel_plmn_id) +static void rrc_ue_generate_RRCSetupComplete(instance_t instance, rnti_t rnti, const uint8_t Transaction_id, uint8_t sel_plmn_id) { uint8_t buffer[100]; uint8_t size; @@ -952,62 +966,43 @@ static void rrc_ue_generate_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p if (get_softmodem_params()->sa) { as_nas_info_t initialNasMsg; - nr_ue_nas_t *nas = get_ue_nas_info(ctxt_pP->module_id); + nr_ue_nas_t *nas = get_ue_nas_info(instance); generateRegistrationRequest(&initialNasMsg, nas); nas_msg = (char*)initialNasMsg.data; nas_msg_length = initialNasMsg.length; } else { - nas_msg = nr_nas_attach_req_imsi; - nas_msg_length = sizeof(nr_nas_attach_req_imsi); + nas_msg = nr_nas_attach_req_imsi_dummy_NSA_case; + nas_msg_length = sizeof(nr_nas_attach_req_imsi_dummy_NSA_case); } - size = do_RRCSetupComplete(ctxt_pP->module_id, buffer, sizeof(buffer), - Transaction_id, sel_plmn_id, nas_msg_length, nas_msg); - LOG_I(NR_RRC, - "[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n", - ctxt_pP->module_id, - ctxt_pP->frame, - size, - gNB_index); + size = do_RRCSetupComplete(instance, buffer, sizeof(buffer), Transaction_id, sel_plmn_id, nas_msg_length, nas_msg); + LOG_I(NR_RRC, "[UE %ld][RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d)\n", instance, size); int srb_id = 1; // RRC setup complete on SRB1 - LOG_D(NR_RRC, - "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCSetupComplete to gNB %d MUI %d) --->][PDCP][MOD %02d][RB " - "%02d]\n", - ctxt_pP->frame, - ctxt_pP->module_id, - size, - gNB_index, - nr_rrc_mui, - ctxt_pP->module_id + NB_eNB_INST, - srb_id); + LOG_D(NR_RRC, "[RRC_UE %ld] PDCP_DATA_REQ/%d Bytes RRCSetupComplete ---> %d\n", instance, size, srb_id); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, srb_id, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL); + nr_pdcp_data_req_srb(rnti, srb_id, 0, size, buffer, deliver_pdu_srb_rlc, NULL); } -static int8_t nr_rrc_ue_decode_ccch(const protocol_ctxt_t *const ctxt_pP, const uint8_t *buf, int len, const uint8_t gNB_index) +static int8_t nr_rrc_ue_decode_ccch(const instance_t instance, + const rnti_t rnti, + const NRRrcMacCcchDataInd *ind, + const uint8_t gNB_index) { - NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[ctxt_pP->module_id]; + NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance]; + NR_DL_CCCH_Message_t *dl_ccch_msg=NULL; asn_dec_rval_t dec_rval; int rval=0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN); - LOG_D(RRC, - "[NR UE%d] Decoding DL-CCCH message (%d bytes), State %d\n", - ctxt_pP->module_id, - len, - rrc->nrRrcState); + LOG_D(RRC, "[NR UE%ld] Decoding DL-CCCH message (%d bytes), State %d\n", instance, ind->sdu_size, rrc->nrRrcState); - dec_rval = uper_decode(NULL, &asn_DEF_NR_DL_CCCH_Message, (void **)&dl_ccch_msg, buf, len, 0, 0); + dec_rval = uper_decode(NULL, &asn_DEF_NR_DL_CCCH_Message, (void **)&dl_ccch_msg, ind->sdu, ind->sdu_size, 0, 0); if (LOG_DEBUGFLAG(DEBUG_ASN1)) xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)dl_ccch_msg); - if (dec_rval.code != RC_OK && dec_rval.consumed == 0) { - LOG_E(RRC, - "[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n", - ctxt_pP->module_id, - ctxt_pP->frame, - dec_rval.consumed); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC, "[UE %ld] Failed to decode DL-CCCH-Message (%zu bytes)\n", instance, dec_rval.consumed); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); return -1; } @@ -1015,166 +1010,73 @@ static int8_t nr_rrc_ue_decode_ccch(const protocol_ctxt_t *const ctxt_pP, const if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) { switch (dl_ccch_msg->message.choice.c1->present) { case NR_DL_CCCH_MessageType__c1_PR_NOTHING: - LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n", - ctxt_pP->module_id, - ctxt_pP->frame); - rval = 0; - break; + LOG_I(NR_RRC, "[UE%ld] Received PR_NOTHING on DL-CCCH-Message\n", instance); + rval = 0; + break; case NR_DL_CCCH_MessageType__c1_PR_rrcReject: - LOG_I(NR_RRC, - "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCReject \n", - ctxt_pP->module_id, - ctxt_pP->frame); - rval = 0; - break; + LOG_I(NR_RRC, "[UE%ld] Logical Channel DL-CCCH (SRB0), Received RRCReject \n", instance); + rval = 0; + break; case NR_DL_CCCH_MessageType__c1_PR_rrcSetup: - LOG_I(NR_RRC, "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %lx\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rntiMaybeUEid); + LOG_I(NR_RRC, "[UE%ld][RAPROC] Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n", instance, rnti); // Get configuration // Release T300 timer rrc->timers_and_constants.T300_active = 0; - nr_rrc_ue_process_masterCellGroup(ctxt_pP, gNB_index, &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup, NULL); - nr_rrc_ue_process_RadioBearerConfig(ctxt_pP, gNB_index, &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig); + nr_rrc_ue_process_masterCellGroup( + instance, + rnti, + rrc->perNB + gNB_index, + &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup, + NULL); + nr_rrc_ue_process_RadioBearerConfig( + rrc, + rnti, + rrc->perNB + gNB_index, + &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig); rrc->nrRrcState = RRC_STATE_CONNECTED_NR; - rrc->rnti = ctxt_pP->rntiMaybeUEid; - rrc_ue_generate_RRCSetupComplete(ctxt_pP, gNB_index, dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier, rrc->selected_plmn_identity); + rrc->rnti = rnti; + rrc_ue_generate_RRCSetupComplete(instance, + rnti, + dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier, + rrc->selected_plmn_identity); rval = 0; break; default: - LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n", - ctxt_pP->module_id, - ctxt_pP->frame); - rval = -1; - break; + LOG_E(NR_RRC, "[UE%ld] Unknown message\n", instance); + rval = -1; + break; } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); return rval; - } +} - // from NR SRB3 - int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message( - const module_id_t module_id, - const uint8_t gNB_index, - const uint8_t *bufferP, - const uint32_t buffer_len ){ - // uper_decode by nr R15 rrc_connection_reconfiguration - - int32_t i; - NR_DL_DCCH_Message_t *nr_dl_dcch_msg = NULL; - MessageDef *msg_p; - - asn_dec_rval_t dec_rval = uper_decode( NULL, - &asn_DEF_NR_DL_DCCH_Message, - (void**)&nr_dl_dcch_msg, - (uint8_t *)bufferP, - buffer_len, 0, 0); - - if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { - for (i=0; imessage.present){ - case NR_DL_DCCH_MessageType_PR_c1: - switch(nr_dl_dcch_msg->message.choice.c1->present){ - case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: - nr_rrc_ue_process_rrcReconfiguration(module_id,nr_dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration); - break; - - case NR_DL_DCCH_MessageType__c1_PR_NOTHING: - case NR_DL_DCCH_MessageType__c1_PR_rrcResume: - case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: - msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND); - if((nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) && - (nr_dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){ - nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer = - NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; - nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType = - NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; - } - itti_send_msg_to_task(TASK_RRC_NRUE,module_id,msg_p); - break; - - case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: - case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: - case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: - case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: - case NR_DL_DCCH_MessageType__c1_PR_counterCheck: - case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: - case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16: - case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16: - case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16: - case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16: - case NR_DL_DCCH_MessageType__c1_PR_spare3: - case NR_DL_DCCH_MessageType__c1_PR_spare2: - case NR_DL_DCCH_MessageType__c1_PR_spare1: - default: - // not supported or unused - break; - } - break; - case NR_DL_DCCH_MessageType_PR_NOTHING: - case NR_DL_DCCH_MessageType_PR_messageClassExtension: - default: - // not supported or unused - break; - } - - // release memory allocation - SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 ); - }else{ - // log.. - } - - return 0; - } - - -void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP, - NR_SecurityModeCommand_t *const securityModeCommand, - const uint8_t gNB_index) +static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, + NR_SecurityModeCommand_t *const securityModeCommand, + rnti_t rnti, + const uint8_t gNB_index) { - asn_enc_rval_t enc_rval; - NR_UL_DCCH_Message_t ul_dcch_msg; - uint8_t buffer[200]; - int securityMode; - LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n", - ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index); + int securityMode = 0; + LOG_I(NR_RRC, "Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n", gNB_index); - NR_SecurityConfigSMC_t *securityConfigSMC = &securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC; - NR_UE_RRC_INST_t *ue_rrc = &NR_UE_rrc_inst[ctxt_pP->module_id]; + NR_SecurityConfigSMC_t *securityConfigSMC = + &securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC; switch (securityConfigSMC->securityAlgorithmConfig.cipheringAlgorithm) { case NR_CipheringAlgorithm_nea0: - LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea0\n", - ctxt_pP->module_id); - securityMode= NR_CipheringAlgorithm_nea0; - break; - case NR_CipheringAlgorithm_nea1: - LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea1\n",ctxt_pP->module_id); - securityMode= NR_CipheringAlgorithm_nea1; - break; - case NR_CipheringAlgorithm_nea2: - LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea2\n", - ctxt_pP->module_id); - securityMode = NR_CipheringAlgorithm_nea2; + LOG_I(NR_RRC, "Security algorithm is set to nea%d\n", securityMode); + securityMode = securityConfigSMC->securityAlgorithmConfig.cipheringAlgorithm; break; - default: - LOG_I(NR_RRC,"[UE %d] Security algorithm is set to none\n",ctxt_pP->module_id); + LOG_W(NR_RRC, "Security algorithm is set to none\n"); securityMode = NR_CipheringAlgorithm_spare1; break; } @@ -1183,544 +1085,428 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP, if (securityConfigSMC->securityAlgorithmConfig.integrityProtAlgorithm != NULL) { switch (*securityConfigSMC->securityAlgorithmConfig.integrityProtAlgorithm) { case NR_IntegrityProtAlgorithm_nia1: - LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia1\n",ctxt_pP->module_id); + LOG_I(NR_RRC, "Integrity protection algorithm is set to nia1\n"); securityMode |= 1 << 5; break; case NR_IntegrityProtAlgorithm_nia2: - LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia2\n",ctxt_pP->module_id); + LOG_I(NR_RRC, "Integrity protection algorithm is set to nia2\n"); securityMode |= 1 << 6; break; default: - LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to none\n",ctxt_pP->module_id); - securityMode |= 0x70 ; + LOG_I(NR_RRC, "Integrity protection algorithm is set to none\n"); + securityMode |= 0x70; break; } ue_rrc->integrityProtAlgorithm = *securityConfigSMC->securityAlgorithmConfig.integrityProtAlgorithm; } - LOG_D(NR_RRC,"[UE %d] security mode is %x \n",ctxt_pP->module_id, securityMode); - memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); - //memset((void *)&SecurityModeCommand,0,sizeof(SecurityModeCommand_t)); + LOG_D(NR_RRC, "security mode is %x \n", securityMode); + NR_UL_DCCH_Message_t ul_dcch_msg = {0}; + + // memset((void *)&SecurityModeCommand,0,sizeof(SecurityModeCommand_t)); ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; - ul_dcch_msg.message.choice.c1 = calloc(1, sizeof(*ul_dcch_msg.message.choice.c1)); + asn1cCalloc(ul_dcch_msg.message.choice.c1, c1); if (securityMode >= NO_SECURITY_MODE) { LOG_I(NR_RRC, "rrc_ue_process_securityModeCommand, security mode complete case \n"); - ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete; + c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete; } else { LOG_I(NR_RRC, "rrc_ue_process_securityModeCommand, security mode failure case \n"); - ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeFailure; - ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete; + c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeFailure; + c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete; } uint8_t kRRCenc[16] = {0}; uint8_t kUPenc[16] = {0}; uint8_t kRRCint[16] = {0}; - nr_derive_key(UP_ENC_ALG, - ue_rrc->cipheringAlgorithm, - ue_rrc->kgnb, - kUPenc); - nr_derive_key(RRC_ENC_ALG, - ue_rrc->cipheringAlgorithm, - ue_rrc->kgnb, - kRRCenc); - nr_derive_key(RRC_INT_ALG, - ue_rrc->integrityProtAlgorithm, - ue_rrc->kgnb, - kRRCint); + nr_derive_key(UP_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kUPenc); + nr_derive_key(RRC_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kRRCenc); + nr_derive_key(RRC_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, kRRCint); - LOG_I(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB=" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x\n", - ue_rrc->kgnb[0], ue_rrc->kgnb[1], ue_rrc->kgnb[2], ue_rrc->kgnb[3], - ue_rrc->kgnb[4], ue_rrc->kgnb[5], ue_rrc->kgnb[6], ue_rrc->kgnb[7], - ue_rrc->kgnb[8], ue_rrc->kgnb[9], ue_rrc->kgnb[10], ue_rrc->kgnb[11], - ue_rrc->kgnb[12], ue_rrc->kgnb[13], ue_rrc->kgnb[14], ue_rrc->kgnb[15], - ue_rrc->kgnb[16], ue_rrc->kgnb[17], ue_rrc->kgnb[18], ue_rrc->kgnb[19], - ue_rrc->kgnb[20], ue_rrc->kgnb[21], ue_rrc->kgnb[22], ue_rrc->kgnb[23], - ue_rrc->kgnb[24], ue_rrc->kgnb[25], ue_rrc->kgnb[26], ue_rrc->kgnb[27], - ue_rrc->kgnb[28], ue_rrc->kgnb[29], ue_rrc->kgnb[30], ue_rrc->kgnb[31]); + log_dump(NR_RRC, ue_rrc->kgnb, 32, LOG_DUMP_CHAR, "driving kRRCenc, kRRCint and kUPenc from KgNB="); if (securityMode != 0xff) { uint8_t security_mode = ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4); // configure lower layers to apply SRB integrity protection and ciphering for (int i = 1; i < NR_NUM_SRB; i++) { - if (ue_rrc->Srb[gNB_index][i].status == RB_ESTABLISHED) - nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, i, security_mode, kRRCenc, kRRCint, kUPenc); + if (ue_rrc->perNB[gNB_index].Srb[i].status == RB_ESTABLISHED) + nr_pdcp_config_set_security(rnti, i, security_mode, kRRCenc, kRRCint, kUPenc); } } else { LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode); } if (securityModeCommand->criticalExtensions.present == NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand) { - ul_dcch_msg.message.choice.c1->choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_t)); - ul_dcch_msg.message.choice.c1->choice.securityModeComplete->rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier; - ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.present = NR_SecurityModeComplete__criticalExtensions_PR_securityModeComplete; - ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_IEs_t)); - ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete->nonCriticalExtension =NULL; - LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (gNB %d), rrc_TransactionIdentifier: %ld\n", - ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index, securityModeCommand->rrc_TransactionIdentifier); - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, - NULL, - (void *)&ul_dcch_msg, - buffer, - 100); - AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", - enc_rval.failed_type->name, enc_rval.encoded); + asn1cCalloc(c1->choice.securityModeComplete, modeComplete); + modeComplete->rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier; + modeComplete->criticalExtensions.present = NR_SecurityModeComplete__criticalExtensions_PR_securityModeComplete; + asn1cCalloc(modeComplete->criticalExtensions.choice.securityModeComplete, ext); + ext->nonCriticalExtension = NULL; + LOG_I(NR_RRC, + "Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (gNB %d), rrc_TransactionIdentifier: %ld\n", + gNB_index, + securityModeCommand->rrc_TransactionIdentifier); + uint8_t buffer[200]; + asn_enc_rval_t enc_rval = + uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, sizeof(buffer)); + AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); } log_dump(NR_RRC, buffer, 16, LOG_DUMP_CHAR, "securityModeComplete payload: "); - LOG_D(NR_RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); + LOG_D(NR_RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded + 7) / 8); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg); for (int i = 0; i < (enc_rval.encoded + 7) / 8; i++) { LOG_T(NR_RRC, "%02x.", buffer[i]); } LOG_T(NR_RRC, "\n"); - //TODO the SecurityModeCommand message needs to pass the integrity protection check - // for the UE to declare AS security to be activated + // TODO the SecurityModeCommand message needs to pass the integrity protection check + // for the UE to declare AS security to be activated ue_rrc->as_security_activated = true; int srb_id = 1; // SecurityModeComplete in SRB1 - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, - srb_id, - nr_rrc_mui++, - (enc_rval.encoded + 7) / 8, - buffer, - deliver_pdu_srb_rlc, - NULL); + nr_pdcp_data_req_srb(rnti, srb_id, 0, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); } else - LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n", + LOG_W(NR_RRC, + "securityModeCommand->criticalExtensions.present (%d) != " + "NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n", securityModeCommand->criticalExtensions.present); } //----------------------------------------------------------------------------- - void - nr_rrc_ue_process_measConfig( - const protocol_ctxt_t *const ctxt_pP, - const uint8_t gNB_index, - NR_MeasConfig_t *const measConfig - ) - //----------------------------------------------------------------------------- - { - int i; - long ind; - NR_MeasObjectToAddMod_t *measObj = NULL; - NR_ReportConfigToAddMod_t *reportConfig = NULL; - - if (measConfig->measObjectToRemoveList != NULL) { - for (i = 0; i < measConfig->measObjectToRemoveList->list.count; i++) { - ind = *measConfig->measObjectToRemoveList->list.array[i]; - free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]); - } - } - - if (measConfig->measObjectToAddModList != NULL) { - LOG_I(NR_RRC, "Measurement Object List is present\n"); - for (i = 0; i < measConfig->measObjectToAddModList->list.count; i++) { - measObj = measConfig->measObjectToAddModList->list.array[i]; - ind = measConfig->measObjectToAddModList->list.array[i]->measObjectId; - - if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]) { - LOG_D(NR_RRC, "Modifying measurement object %ld\n",ind); - memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1], - (char *)measObj, - sizeof(NR_MeasObjectToAddMod_t)); - } else { - LOG_I(NR_RRC, "Adding measurement object %ld\n", ind); - - if (measObj->measObject.present == NR_MeasObjectToAddMod__measObject_PR_measObjectNR) { - NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]=measObj; - } - } - } - - LOG_I(NR_RRC, "call rrc_mac_config_req \n"); - // rrc_mac_config_req_ue - } - - if (measConfig->reportConfigToRemoveList != NULL) { - for (i = 0; i < measConfig->reportConfigToRemoveList->list.count; i++) { - ind = *measConfig->reportConfigToRemoveList->list.array[i]; - free(NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]); - } - } - - if (measConfig->reportConfigToAddModList != NULL) { - LOG_I(NR_RRC,"Report Configuration List is present\n"); - for (i = 0; i < measConfig->reportConfigToAddModList->list.count; i++) { - ind = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId; - reportConfig = measConfig->reportConfigToAddModList->list.array[i]; - - if (NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]) { - LOG_I(NR_RRC, "Modifying Report Configuration %ld\n", ind-1); - memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1], - (char *)measConfig->reportConfigToAddModList->list.array[i], - sizeof(NR_ReportConfigToAddMod_t)); - } else { - LOG_D(NR_RRC,"Adding Report Configuration %ld %p \n", ind-1, measConfig->reportConfigToAddModList->list.array[i]); - if (reportConfig->reportConfig.present == NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR) { - NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i]; - } - } - } - } - - if (measConfig->measIdToRemoveList != NULL) { - for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) { - ind = *measConfig->measIdToRemoveList->list.array[i]; - free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]); - } - } - - if (measConfig->measIdToAddModList != NULL) { - for (i = 0; i < measConfig->measIdToAddModList->list.count; i++) { - ind = measConfig->measIdToAddModList->list.array[i]->measId; - - if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]) { - LOG_D(NR_RRC, "Modifying Measurement ID %ld\n",ind-1); - memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1], - (char *)measConfig->measIdToAddModList->list.array[i], - sizeof(NR_MeasIdToAddMod_t)); - } else { - LOG_D(NR_RRC, "Adding Measurement ID %ld %p\n", ind-1, measConfig->measIdToAddModList->list.array[i]); - NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i]; - } - } - } - - if (measConfig->quantityConfig != NULL) { - if (NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index]) { - LOG_D(NR_RRC,"Modifying Quantity Configuration \n"); - memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index], - (char *)measConfig->quantityConfig, - sizeof(NR_QuantityConfig_t)); - } else { - LOG_D(NR_RRC, "Adding Quantity configuration\n"); - NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index] = measConfig->quantityConfig; - } - } - - if (measConfig->measGapConfig != NULL) { - if (NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index]) { - memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index], - (char *)measConfig->measGapConfig, - sizeof(NR_MeasGapConfig_t)); - } else { - NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index] = measConfig->measGapConfig; - } - } - - if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_ssb_RSRP) { - NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.ssb_RSRP; - } else if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_csi_RSRP) { - NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.csi_RSRP; - } - } - - void nr_rrc_ue_process_RadioBearerConfig(const protocol_ctxt_t *const ctxt_pP, - const uint8_t gNB_index, - NR_RadioBearerConfig_t *const radioBearerConfig) - { - if (LOG_DEBUGFLAG(DEBUG_ASN1)) - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)radioBearerConfig); - - NR_UE_RRC_INST_t *ue_rrc = &NR_UE_rrc_inst[ctxt_pP->module_id]; - if (radioBearerConfig->srb3_ToRelease) - nr_pdcp_release_srb(ctxt_pP->rntiMaybeUEid, 3); - - uint8_t kRRCenc[16] = {0}; - uint8_t kRRCint[16] = {0}; - if (ue_rrc->as_security_activated) { - if (radioBearerConfig->securityConfig != NULL) { - // When the field is not included, continue to use the currently configured keyToUse - if (radioBearerConfig->securityConfig->keyToUse) { - AssertFatal(*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master, - "Secondary key usage seems not to be implemented\n"); - ue_rrc->keyToUse = *radioBearerConfig->securityConfig->keyToUse; - } - // When the field is not included, continue to use the currently configured security algorithm - if (radioBearerConfig->securityConfig->securityAlgorithmConfig) { - ue_rrc->cipheringAlgorithm = radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm; - ue_rrc->integrityProtAlgorithm = *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm; - } - } - nr_derive_key(RRC_ENC_ALG, - NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, - kRRCenc); - nr_derive_key(RRC_INT_ALG, - NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, - kRRCint); - } - - if (radioBearerConfig->srb_ToAddModList != NULL) { - for (int cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) { - struct NR_SRB_ToAddMod *srb = radioBearerConfig->srb_ToAddModList->list.array[cnt]; - NR_UE_RRC_SRB_INFO_t *Srb_info = &ue_rrc->Srb[gNB_index][srb->srb_Identity]; - if (Srb_info->status == RB_NOT_PRESENT) - add_srb(ctxt_pP->enb_flag, - ctxt_pP->rntiMaybeUEid, - radioBearerConfig->srb_ToAddModList->list.array[cnt], - ue_rrc->cipheringAlgorithm, - ue_rrc->integrityProtAlgorithm, - kRRCenc, - kRRCint); - else { - AssertFatal(srb->discardOnPDCP == NULL, "discardOnPDCP not yet implemented\n"); - AssertFatal(srb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n"); - if (srb->pdcp_Config && srb->pdcp_Config->t_Reordering) - nr_pdcp_reconfigure_srb(ctxt_pP->rntiMaybeUEid, srb->srb_Identity, *srb->pdcp_Config->t_Reordering); - } - Srb_info->status = RB_ESTABLISHED; - } - } - - if (radioBearerConfig->drb_ToReleaseList) { - for (int cnt = 0; cnt < radioBearerConfig->drb_ToReleaseList->list.count; cnt++) { - NR_DRB_Identity_t *DRB_id = radioBearerConfig->drb_ToReleaseList->list.array[cnt]; - if (DRB_id) - nr_pdcp_release_drb(ctxt_pP->rntiMaybeUEid, *DRB_id); - } - } - - // Establish DRBs if present - if (radioBearerConfig->drb_ToAddModList != NULL) { - for (int cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) { - struct NR_DRB_ToAddMod *drb = radioBearerConfig->drb_ToAddModList->list.array[cnt]; - int DRB_id = drb->drb_Identity; - if (ue_rrc->active_DRBs[gNB_index][DRB_id]) { - AssertFatal(drb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n"); - AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n"); - if (drb->pdcp_Config && drb->pdcp_Config->t_Reordering) - nr_pdcp_reconfigure_drb(ctxt_pP->rntiMaybeUEid, DRB_id, *drb->pdcp_Config->t_Reordering); - if (drb->cnAssociation) - AssertFatal(drb->cnAssociation->choice.sdap_Config == NULL, "SDAP reconfiguration not yet implemented\n"); - } else { - ue_rrc->active_DRBs[gNB_index][DRB_id] = true; - add_drb(ctxt_pP->enb_flag, - ctxt_pP->rntiMaybeUEid, - radioBearerConfig->drb_ToAddModList->list.array[cnt], - ue_rrc->cipheringAlgorithm, - ue_rrc->integrityProtAlgorithm, - kRRCenc, - kRRCint); - } - } - } // drb_ToAddModList // - - NR_UE_rrc_inst[ctxt_pP->module_id].nrRrcState = RRC_STATE_CONNECTED_NR; - LOG_I(NR_RRC, "[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index); - } - - //----------------------------------------------------------------------------- - static void rrc_ue_process_rrcReconfiguration(const protocol_ctxt_t *const ctxt_pP, - NR_RRCReconfiguration_t *rrcReconfiguration, - uint8_t gNB_index) - //----------------------------------------------------------------------------- - { - LOG_I(NR_RRC, "[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCReconfiguration (gNB %d)\n", - ctxt_pP->module_id, ctxt_pP->frame, gNB_index); - - NR_RRCReconfiguration_IEs_t *ie = NULL; - - if (rrcReconfiguration->criticalExtensions.present - == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration) { - ie = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration; - if (ie->measConfig != NULL) { - LOG_I(NR_RRC, "Measurement Configuration is present\n"); - // nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig); - } - - if((ie->nonCriticalExtension) && (ie->nonCriticalExtension->masterCellGroup != NULL)) { - nr_rrc_ue_process_masterCellGroup(ctxt_pP, - gNB_index, - ie->nonCriticalExtension->masterCellGroup, - ie->nonCriticalExtension->fullConfig); - } - - if (ie->radioBearerConfig != NULL) { - LOG_I(NR_RRC, "radio Bearer Configuration is present\n"); - nr_rrc_ue_process_RadioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig); - } - - /* Check if there is dedicated NAS information to forward to NAS */ - if ((ie->nonCriticalExtension) && (ie->nonCriticalExtension->dedicatedNAS_MessageList != NULL)) { - int list_count; - uint32_t pdu_length; - uint8_t *pdu_buffer; - MessageDef *msg_p; - - for (list_count = 0; list_count < ie->nonCriticalExtension->dedicatedNAS_MessageList->list.count; list_count++) { - pdu_length = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->size; - pdu_buffer = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->buf; - msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_ESTABLI_CNF); - NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS; - NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length; - NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer; - itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p); - } - - free (ie->nonCriticalExtension->dedicatedNAS_MessageList); - } - } - } - - void nr_rrc_ue_generate_RRCReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP, - const uint8_t gNB_index, - const int srb_id, - const uint8_t Transaction_id) - { - uint8_t buffer[32], size; - size = do_NR_RRCReconfigurationComplete(ctxt_pP, buffer, sizeof(buffer), Transaction_id); - LOG_I(NR_RRC, - PROTOCOL_RRC_CTXT_UE_FMT - " Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d, gNB_index %d)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - size, - gNB_index); - AssertFatal(srb_id == 1 || srb_id == 3, "Invalid SRB ID %d\n", srb_id); - LOG_D(RLC, - "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfigurationComplete to gNB %d MUI %d) " - "--->][PDCP][INST %02d][RB %02d]\n", - ctxt_pP->frame, - UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), - size, - gNB_index, - nr_rrc_mui, - UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), - srb_id); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, srb_id, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL); - } - - int nr_rrc_ue_decode_dcch(const protocol_ctxt_t *const ctxt_pP, - const srb_id_t Srb_id, - const uint8_t *const Buffer, - size_t Buffer_size, - const uint8_t gNB_indexP) - - { - asn_dec_rval_t dec_rval; - NR_DL_DCCH_Message_t *dl_dcch_msg = NULL; - MessageDef *msg_p; - - if (Srb_id != 1 && Srb_id != 2) { - LOG_E(NR_RRC, - "[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n", - ctxt_pP->module_id, - ctxt_pP->frame, - Srb_id); - } - - LOG_D(NR_RRC, "Decoding DL-DCCH Message\n"); - dec_rval = uper_decode(NULL, &asn_DEF_NR_DL_DCCH_Message, (void **)&dl_dcch_msg, Buffer, Buffer_size, 0, 0); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_DL_DCCH_Message, dl_dcch_msg); - return -1; - } - - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)dl_dcch_msg); - } - - if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) { - switch (dl_dcch_msg->message.choice.c1->present) { - case NR_DL_DCCH_MessageType__c1_PR_NOTHING: - LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n"); - break; - - case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: { - rrc_ue_process_rrcReconfiguration(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration, gNB_indexP); - nr_rrc_ue_generate_RRCReconfigurationComplete( - ctxt_pP, - gNB_indexP, - Srb_id, - dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier); - break; - } - - case NR_DL_DCCH_MessageType__c1_PR_rrcResume: - case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: - LOG_I(NR_RRC, "[UE %d] Received RRC Release (gNB %d)\n", ctxt_pP->module_id, gNB_indexP); - - msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND); - - if ((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present - == NR_RRCRelease__criticalExtensions_PR_rrcRelease) - && (dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)) { - dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq - ->deprioritisationTimer = NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; - dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq - ->deprioritisationType = NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; - } - - itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p); - break; - case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: - LOG_I(NR_RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n", ctxt_pP->module_id, gNB_indexP); - nr_rrc_ue_process_ueCapabilityEnquiry(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry, gNB_indexP); - break; - case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: - LOG_I(NR_RRC, - "[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n", - ctxt_pP->module_id, - ctxt_pP->frame); - nr_rrc_ue_generate_rrcReestablishmentComplete(ctxt_pP, - dl_dcch_msg->message.choice.c1->choice.rrcReestablishment, - gNB_indexP); - break; - case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: { - NR_DLInformationTransfer_t *dlInformationTransfer = dl_dcch_msg->message.choice.c1->choice.dlInformationTransfer; - - if (dlInformationTransfer->criticalExtensions.present - == NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) { - /* This message hold a dedicated info NAS payload, forward it to NAS */ - NR_DedicatedNAS_Message_t *dedicatedNAS_Message = - dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message; - - MessageDef *msg_p; - msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_DOWNLINK_DATA_IND); - NAS_DOWNLINK_DATA_IND(msg_p).UEid = ctxt_pP->module_id; // TODO set the UEid to something else ? - NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length = dedicatedNAS_Message->size; - NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = dedicatedNAS_Message->buf; - itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p); - } - } break; - case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: - case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16: - case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16: - case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16: - case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16: - case NR_DL_DCCH_MessageType__c1_PR_spare3: - case NR_DL_DCCH_MessageType__c1_PR_spare2: - case NR_DL_DCCH_MessageType__c1_PR_spare1: - case NR_DL_DCCH_MessageType__c1_PR_counterCheck: - break; - case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: - LOG_I(NR_RRC, "[UE %d] Received securityModeCommand (gNB %d)\n", ctxt_pP->module_id, gNB_indexP); - nr_rrc_ue_process_securityModeCommand(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.securityModeCommand, gNB_indexP); - break; - } - } - return 0; - } - -void nr_rrc_handle_ra_indication(unsigned int mod_id, bool ra_succeeded) +void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig) +//----------------------------------------------------------------------------- { - NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[mod_id].timers_and_constants; + int i; + long ind; + NR_MeasObjectToAddMod_t *measObj = NULL; + NR_ReportConfigToAddMod_t *reportConfig = NULL; + + if (measConfig->measObjectToRemoveList != NULL) { + for (i = 0; i < measConfig->measObjectToRemoveList->list.count; i++) { + ind = *measConfig->measObjectToRemoveList->list.array[i]; + free(rrc->MeasObj[ind - 1]); + } + } + + if (measConfig->measObjectToAddModList != NULL) { + LOG_I(NR_RRC, "Measurement Object List is present\n"); + for (i = 0; i < measConfig->measObjectToAddModList->list.count; i++) { + measObj = measConfig->measObjectToAddModList->list.array[i]; + ind = measConfig->measObjectToAddModList->list.array[i]->measObjectId; + + if (rrc->MeasObj[ind - 1]) { + LOG_D(NR_RRC, "Modifying measurement object %ld\n", ind); + memcpy(rrc->MeasObj[ind - 1], (char *)measObj, sizeof(NR_MeasObjectToAddMod_t)); + } else { + LOG_I(NR_RRC, "Adding measurement object %ld\n", ind); + + if (measObj->measObject.present == NR_MeasObjectToAddMod__measObject_PR_measObjectNR) { + rrc->MeasObj[ind - 1] = measObj; + } + } + } + + LOG_I(NR_RRC, "call rrc_mac_config_req \n"); + // rrc_mac_config_req_ue + } + + if (measConfig->reportConfigToRemoveList != NULL) { + for (i = 0; i < measConfig->reportConfigToRemoveList->list.count; i++) { + ind = *measConfig->reportConfigToRemoveList->list.array[i]; + free(rrc->ReportConfig[ind - 1]); + } + } + + if (measConfig->reportConfigToAddModList != NULL) { + LOG_I(NR_RRC, "Report Configuration List is present\n"); + for (i = 0; i < measConfig->reportConfigToAddModList->list.count; i++) { + ind = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId; + reportConfig = measConfig->reportConfigToAddModList->list.array[i]; + + if (rrc->ReportConfig[ind - 1]) { + LOG_I(NR_RRC, "Modifying Report Configuration %ld\n", ind - 1); + memcpy(rrc->ReportConfig[ind - 1], + (char *)measConfig->reportConfigToAddModList->list.array[i], + sizeof(NR_ReportConfigToAddMod_t)); + } else { + LOG_D(NR_RRC, "Adding Report Configuration %ld %p \n", ind - 1, measConfig->reportConfigToAddModList->list.array[i]); + if (reportConfig->reportConfig.present == NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR) { + rrc->ReportConfig[ind - 1] = measConfig->reportConfigToAddModList->list.array[i]; + } + } + } + } + + if (measConfig->measIdToRemoveList != NULL) { + for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) { + ind = *measConfig->measIdToRemoveList->list.array[i]; + free(rrc->MeasId[ind - 1]); + } + } + + if (measConfig->measIdToAddModList != NULL) { + for (i = 0; i < measConfig->measIdToAddModList->list.count; i++) { + ind = measConfig->measIdToAddModList->list.array[i]->measId; + + if (rrc->MeasId[ind - 1]) { + LOG_D(NR_RRC, "Modifying Measurement ID %ld\n", ind - 1); + memcpy(rrc->MeasId[ind - 1], (char *)measConfig->measIdToAddModList->list.array[i], sizeof(NR_MeasIdToAddMod_t)); + } else { + LOG_D(NR_RRC, "Adding Measurement ID %ld %p\n", ind - 1, measConfig->measIdToAddModList->list.array[i]); + rrc->MeasId[ind - 1] = measConfig->measIdToAddModList->list.array[i]; + } + } + } + + if (measConfig->quantityConfig != NULL) { + if (rrc->QuantityConfig) { + LOG_D(NR_RRC, "Modifying Quantity Configuration \n"); + memcpy(rrc->QuantityConfig, (char *)measConfig->quantityConfig, sizeof(NR_QuantityConfig_t)); + } else { + LOG_D(NR_RRC, "Adding Quantity configuration\n"); + rrc->QuantityConfig = measConfig->quantityConfig; + } + } + + if (measConfig->measGapConfig != NULL) { + if (rrc->measGapConfig) { + memcpy(rrc->measGapConfig, (char *)measConfig->measGapConfig, sizeof(NR_MeasGapConfig_t)); + } else { + rrc->measGapConfig = measConfig->measGapConfig; + } + } + + if (measConfig->s_MeasureConfig) { + if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_ssb_RSRP) { + rrc->s_measure = measConfig->s_MeasureConfig->choice.ssb_RSRP; + } else if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_csi_RSRP) { + rrc->s_measure = measConfig->s_MeasureConfig->choice.csi_RSRP; + } + } +} + +static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, + rnti_t rnti, + rrcPerNB_t *rrcNB, + NR_RadioBearerConfig_t *const radioBearerConfig) +{ + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)radioBearerConfig); + + if (radioBearerConfig->srb3_ToRelease) + nr_pdcp_release_srb(rnti, 3); + + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + if (ue_rrc->as_security_activated) { + if (radioBearerConfig->securityConfig != NULL) { + // When the field is not included, continue to use the currently configured keyToUse + if (radioBearerConfig->securityConfig->keyToUse) { + AssertFatal(*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master, + "Secondary key usage seems not to be implemented\n"); + ue_rrc->keyToUse = *radioBearerConfig->securityConfig->keyToUse; + } + // When the field is not included, continue to use the currently configured security algorithm + if (radioBearerConfig->securityConfig->securityAlgorithmConfig) { + ue_rrc->cipheringAlgorithm = radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm; + ue_rrc->integrityProtAlgorithm = *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm; + } + } + nr_derive_key(RRC_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kRRCenc); + nr_derive_key(RRC_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, kRRCint); + } + + if (radioBearerConfig->srb_ToAddModList != NULL) { + for (int cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) { + struct NR_SRB_ToAddMod *srb = radioBearerConfig->srb_ToAddModList->list.array[cnt]; + NR_UE_RRC_SRB_INFO_t *Srb_info = &rrcNB->Srb[srb->srb_Identity]; + if (Srb_info->status == RB_NOT_PRESENT) + add_srb(false, + rnti, + radioBearerConfig->srb_ToAddModList->list.array[cnt], + ue_rrc->cipheringAlgorithm, + ue_rrc->integrityProtAlgorithm, + kRRCenc, + kRRCint); + else { + AssertFatal(srb->discardOnPDCP == NULL, "discardOnPDCP not yet implemented\n"); + AssertFatal(srb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n"); + if (srb->pdcp_Config && srb->pdcp_Config->t_Reordering) + nr_pdcp_reconfigure_srb(rnti, srb->srb_Identity, *srb->pdcp_Config->t_Reordering); + } + Srb_info->status = RB_ESTABLISHED; + } + } + + if (radioBearerConfig->drb_ToReleaseList) { + for (int cnt = 0; cnt < radioBearerConfig->drb_ToReleaseList->list.count; cnt++) { + NR_DRB_Identity_t *DRB_id = radioBearerConfig->drb_ToReleaseList->list.array[cnt]; + if (DRB_id) + nr_pdcp_release_drb(rnti, *DRB_id); + } + } + + // Establish DRBs if present + if (radioBearerConfig->drb_ToAddModList != NULL) { + for (int cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) { + struct NR_DRB_ToAddMod *drb = radioBearerConfig->drb_ToAddModList->list.array[cnt]; + int DRB_id = drb->drb_Identity; + if (rrcNB->active_DRBs[DRB_id]) { + AssertFatal(drb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n"); + AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n"); + if (drb->pdcp_Config && drb->pdcp_Config->t_Reordering) + nr_pdcp_reconfigure_drb(rnti, DRB_id, *drb->pdcp_Config->t_Reordering); + if (drb->cnAssociation) + AssertFatal(drb->cnAssociation->choice.sdap_Config == NULL, "SDAP reconfiguration not yet implemented\n"); + } else { + rrcNB->active_DRBs[DRB_id] = true; + add_drb(false, + rnti, + radioBearerConfig->drb_ToAddModList->list.array[cnt], + ue_rrc->cipheringAlgorithm, + ue_rrc->integrityProtAlgorithm, + kRRCenc, + kRRCint); + } + } + } // drb_ToAddModList // + + ue_rrc->nrRrcState = RRC_STATE_CONNECTED_NR; + LOG_I(NR_RRC, "State = NR_RRC_CONNECTED\n"); +} + +static void nr_rrc_ue_generate_RRCReconfigurationComplete(rnti_t rnti, const int srb_id, const uint8_t Transaction_id) +{ + uint8_t buffer[32], size; + size = do_NR_RRCReconfigurationComplete(buffer, sizeof(buffer), Transaction_id); + LOG_I(NR_RRC, " Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d)\n", size); + AssertFatal(srb_id == 1 || srb_id == 3, "Invalid SRB ID %d\n", srb_id); + LOG_D(RLC, + "PDCP_DATA_REQ/%d Bytes (RRCReconfigurationComplete) " + "--->][PDCP][RB %02d]\n", + size, + srb_id); + nr_pdcp_data_req_srb(rnti, srb_id, 0, size, buffer, deliver_pdu_srb_rlc, NULL); +} + +static int nr_rrc_ue_decode_dcch(instance_t instance, + rnti_t rnti, + const srb_id_t Srb_id, + const uint8_t *const Buffer, + size_t Buffer_size, + const uint8_t gNB_indexP) + +{ + NR_DL_DCCH_Message_t *dl_dcch_msg = NULL; + NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance]; + if (Srb_id != 1 && Srb_id != 2) { + LOG_E(NR_RRC, "Received message on DL-DCCH (SRB%ld), should not have ...\n", Srb_id); + } + + LOG_D(NR_RRC, "Decoding DL-DCCH Message\n"); + asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_DL_DCCH_Message, (void **)&dl_dcch_msg, Buffer, Buffer_size, 0, 0); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_DL_DCCH_Message, dl_dcch_msg); + return -1; + } + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)dl_dcch_msg); + } + + switch (dl_dcch_msg->message.present) { + case NR_DL_DCCH_MessageType_PR_c1: { + struct NR_DL_DCCH_MessageType__c1 *c1 = dl_dcch_msg->message.choice.c1; + switch (c1->present) { + case NR_DL_DCCH_MessageType__c1_PR_NOTHING: + LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n"); + break; + + case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: { + nr_rrc_ue_process_rrcReconfiguration(instance, gNB_indexP, rnti, c1->choice.rrcReconfiguration); + nr_rrc_ue_generate_RRCReconfigurationComplete(rnti, Srb_id, c1->choice.rrcReconfiguration->rrc_TransactionIdentifier); + } break; + + case NR_DL_DCCH_MessageType__c1_PR_rrcResume: + LOG_I(NR_RRC, "Received rrcResume on DL-DCCH-Message\n"); + break; + case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: { + struct NR_RRCRelease__criticalExtensions *ext = &c1->choice.rrcRelease->criticalExtensions; + LOG_I(NR_RRC, "Received RRC Release (gNB %d)\n", gNB_indexP); + MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND); + // FixMe: this code do nothing !!!! + if (ext->present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) { + ext->choice.rrcRelease->deprioritisationReq->deprioritisationTimer = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; + ext->choice.rrcRelease->deprioritisationReq->deprioritisationType = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; + } + itti_send_msg_to_task(TASK_NAS_NRUE, instance, msg_p); + } break; + + case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: + LOG_I(NR_RRC, "Received Capability Enquiry (gNB %d)\n", gNB_indexP); + nr_rrc_ue_process_ueCapabilityEnquiry(rrc, c1->choice.ueCapabilityEnquiry); + break; + + case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: + LOG_I(NR_RRC, "Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n"); + nr_rrc_ue_generate_rrcReestablishmentComplete(c1->choice.rrcReestablishment); + break; + + case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: { + NR_DLInformationTransfer_t *dlInformationTransfer = c1->choice.dlInformationTransfer; + + if (dlInformationTransfer->criticalExtensions.present + == NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) { + /* This message hold a dedicated info NAS payload, forward it to NAS */ + NR_DedicatedNAS_Message_t *dedicatedNAS_Message = + dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message; + + MessageDef *ittiMsg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_DOWNLINK_DATA_IND); + NasDlDataInd *msg = &NAS_DOWNLINK_DATA_IND(ittiMsg); + msg->UEid = instance; // TODO set the UEid to something else ? + msg->nasMsg.length = dedicatedNAS_Message->size; + msg->nasMsg.data = dedicatedNAS_Message->buf; + itti_send_msg_to_task(TASK_NAS_NRUE, instance, ittiMsg); + dedicatedNAS_Message->buf = NULL; // to keep the buffer, up to NAS to free it + } + } break; + case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: + case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16: + case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16: + case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16: + case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16: + case NR_DL_DCCH_MessageType__c1_PR_spare3: + case NR_DL_DCCH_MessageType__c1_PR_spare2: + case NR_DL_DCCH_MessageType__c1_PR_spare1: + case NR_DL_DCCH_MessageType__c1_PR_counterCheck: + break; + case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: + LOG_I(NR_RRC, "Received securityModeCommand (gNB %d)\n", gNB_indexP); + nr_rrc_ue_process_securityModeCommand(rrc, c1->choice.securityModeCommand, rnti, gNB_indexP); + break; + } + } break; + default: + break; + } + // release memory allocation + SEQUENCE_free(&asn_DEF_NR_DL_DCCH_Message, (void *)dl_dcch_msg, 1); + return 0; +} + +void nr_rrc_handle_ra_indication(NR_UE_RRC_INST_t *rrc, bool ra_succeeded) +{ + NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; if (ra_succeeded && timers->T304_active == true) { // successful Random Access procedure triggered by reconfigurationWithSync timers->T304_active = false; @@ -1740,187 +1526,106 @@ void *rrc_nrue_task(void *args_p) void *rrc_nrue(void *notUsed) { - protocol_ctxt_t ctxt; - MessageDef *msg_p = NULL; itti_receive_msg(TASK_RRC_NRUE, &msg_p); instance_t instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); - unsigned int ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); - + NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance]; + + LOG_D(NR_RRC, "[UE %ld] Received %s\n", instance, ITTI_MSG_NAME(msg_p)); + switch (ITTI_MSG_ID(msg_p)) { - case TERMINATE_MESSAGE: - LOG_W(NR_RRC, " *** Exiting RRC thread\n"); - itti_exit_task(); - break; - - case MESSAGE_TEST: - LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME(msg_p)); - break; - - case NR_RRC_MAC_SYNC_IND: - LOG_D(NR_RRC, "[UE %d] Received %s: frame %d\n", ue_mod_id, ITTI_MSG_NAME(msg_p), NR_RRC_MAC_SYNC_IND(msg_p).frame); - nr_sync_msg_t sync_msg = NR_RRC_MAC_SYNC_IND(msg_p).in_sync ? IN_SYNC : OUT_OF_SYNC; - NR_UE_Timers_Constants_t *tac = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants; - handle_rlf_sync(tac, sync_msg); - break; - - case NRRRC_FRAME_PROCESS: - LOG_D(NR_RRC, "[UE %d] Received %s: frame %d\n", ue_mod_id, ITTI_MSG_NAME(msg_p), NRRRC_FRAME_PROCESS(msg_p).frame); - // increase the timers every 10ms (every new frame) - NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants; - nr_rrc_handle_timers(timers); - NR_UE_RRC_SI_INFO *SInfo = &NR_UE_rrc_inst[ue_mod_id].SInfo[NRRRC_FRAME_PROCESS(msg_p).gnb_id]; - nr_rrc_SI_timers(SInfo); - break; - - case NR_RRC_MAC_MSG3_IND: - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_MSG3_IND(msg_p).rnti, 0, 0); - LOG_D(NR_RRC, "[UE %d] Received %s for RNTI %d\n", ue_mod_id, ITTI_MSG_NAME(msg_p), NR_RRC_MAC_MSG3_IND(msg_p).rnti); - nr_rrc_ue_generate_ra_msg(ue_mod_id, NR_RRC_MAC_MSG3_IND(msg_p).rnti); - break; - - case NR_RRC_MAC_RA_IND: - LOG_D(NR_RRC, - "[UE %d] Received %s: frame %d RA %s\n", - ue_mod_id, - ITTI_MSG_NAME(msg_p), - NR_RRC_MAC_RA_IND(msg_p).frame, - NR_RRC_MAC_RA_IND(msg_p).RA_succeeded ? "successful" : "failed"); - nr_rrc_handle_ra_indication(ue_mod_id, NR_RRC_MAC_RA_IND(msg_p).RA_succeeded); - break; - - case NR_RRC_MAC_BCCH_DATA_IND: - LOG_D(NR_RRC, "[UE %d] Received %s: gNB %d\n", ue_mod_id, ITTI_MSG_NAME(msg_p), NR_RRC_MAC_BCCH_DATA_IND(msg_p).gnb_index); - NRRrcMacBcchDataInd *bcch = &NR_RRC_MAC_BCCH_DATA_IND(msg_p); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, bcch->frame, 0, bcch->gnb_index); - if (bcch->is_bch) - nr_rrc_ue_decode_NR_BCCH_BCH_Message(ue_mod_id, bcch->gnb_index, bcch->sdu, bcch->sdu_size); - else - nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(ctxt.module_id, - bcch->gnb_index, - bcch->sdu, - bcch->sdu_size, - bcch->rsrq, - bcch->rsrp); - break; - - case NR_RRC_MAC_CCCH_DATA_IND: - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND(msg_p).rnti, 0, 0); - nr_rrc_ue_decode_ccch(&ctxt, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size, - /* gNB_index = */ 0); - break; - + case TERMINATE_MESSAGE: + LOG_W(NR_RRC, " *** Exiting RRC thread\n"); + itti_exit_task(); + break; + + case MESSAGE_TEST: + break; + + case NR_RRC_MAC_SYNC_IND: { + nr_sync_msg_t sync_msg = NR_RRC_MAC_SYNC_IND(msg_p).in_sync ? IN_SYNC : OUT_OF_SYNC; + NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; + handle_rlf_sync(tac, sync_msg); + } break; + + case NRRRC_FRAME_PROCESS: + LOG_D(NR_RRC, "Received %s: frame %d\n", ITTI_MSG_NAME(msg_p), NRRRC_FRAME_PROCESS(msg_p).frame); + // increase the timers every 10ms (every new frame) + NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[instance].timers_and_constants; + nr_rrc_handle_timers(timers); + NR_UE_RRC_SI_INFO *SInfo = &NR_UE_rrc_inst[instance].perNB[NRRRC_FRAME_PROCESS(msg_p).gnb_id].SInfo; + nr_rrc_SI_timers(SInfo); + break; + + case NR_RRC_MAC_MSG3_IND: + nr_rrc_ue_generate_ra_msg(instance, INITIAL_ACCESS_FROM_RRC_IDLE, NR_RRC_MAC_MSG3_IND(msg_p).rnti); + break; + + case NR_RRC_MAC_RA_IND: + LOG_D(NR_RRC, + "[UE %ld] Received %s: frame %d RA %s\n", + instance, + ITTI_MSG_NAME(msg_p), + NR_RRC_MAC_RA_IND(msg_p).frame, + NR_RRC_MAC_RA_IND(msg_p).RA_succeeded ? "successful" : "failed"); + nr_rrc_handle_ra_indication(rrc, NR_RRC_MAC_RA_IND(msg_p).RA_succeeded); + break; + + case NR_RRC_MAC_BCCH_DATA_IND: + LOG_D(NR_RRC, "[UE %ld] Received %s: gNB %d\n", instance, ITTI_MSG_NAME(msg_p), NR_RRC_MAC_BCCH_DATA_IND(msg_p).gnb_index); + NRRrcMacBcchDataInd *bcch = &NR_RRC_MAC_BCCH_DATA_IND(msg_p); + if (bcch->is_bch) + nr_rrc_ue_decode_NR_BCCH_BCH_Message(instance, bcch->gnb_index, bcch->sdu, bcch->sdu_size); + else + nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(instance, bcch->gnb_index, bcch->sdu, bcch->sdu_size, bcch->rsrq, bcch->rsrp); + break; + + case NR_RRC_MAC_CCCH_DATA_IND: { + NRRrcMacCcchDataInd *ind = &NR_RRC_MAC_CCCH_DATA_IND(msg_p); + nr_rrc_ue_decode_ccch(instance, ind->rnti, ind, 0); + } break; + /* PDCP messages */ - case NR_RRC_DCCH_DATA_IND: - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, - NR_RRC_DCCH_DATA_IND(msg_p).module_id, - GNB_FLAG_NO, - NR_RRC_DCCH_DATA_IND(msg_p).rnti, - NR_RRC_DCCH_DATA_IND(msg_p).frame, - 0, - NR_RRC_DCCH_DATA_IND(msg_p).gNB_index); - LOG_D(NR_RRC, - "[UE %d] Received %s: frameP %d, DCCH %d, gNB %d\n", - NR_RRC_DCCH_DATA_IND(msg_p).module_id, - ITTI_MSG_NAME(msg_p), - NR_RRC_DCCH_DATA_IND(msg_p).frame, - NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, - NR_RRC_DCCH_DATA_IND(msg_p).gNB_index); - LOG_D(NR_RRC, - PROTOCOL_RRC_CTXT_UE_FMT "Received %s DCCH %d, gNB %d\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt), - ITTI_MSG_NAME(msg_p), - NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, - NR_RRC_DCCH_DATA_IND(msg_p).gNB_index); - nr_rrc_ue_decode_dcch(&ctxt, - NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, - NR_RRC_DCCH_DATA_IND(msg_p).sdu_p, - NR_RRC_DCCH_DATA_IND(msg_p).sdu_size, - NR_RRC_DCCH_DATA_IND(msg_p).gNB_index); - break; - - case NAS_KENB_REFRESH_REQ: - memcpy((void *)NR_UE_rrc_inst[ue_mod_id].kgnb, - (void *)NAS_KENB_REFRESH_REQ(msg_p).kenb, - sizeof(NR_UE_rrc_inst[ue_mod_id].kgnb)); - LOG_D(RRC, - "[UE %d] Received %s: refreshed RRC::KgNB = " - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x\n", - ue_mod_id, - ITTI_MSG_NAME(msg_p), - NR_UE_rrc_inst[ue_mod_id].kgnb[0], - NR_UE_rrc_inst[ue_mod_id].kgnb[1], - NR_UE_rrc_inst[ue_mod_id].kgnb[2], - NR_UE_rrc_inst[ue_mod_id].kgnb[3], - NR_UE_rrc_inst[ue_mod_id].kgnb[4], - NR_UE_rrc_inst[ue_mod_id].kgnb[5], - NR_UE_rrc_inst[ue_mod_id].kgnb[6], - NR_UE_rrc_inst[ue_mod_id].kgnb[7], - NR_UE_rrc_inst[ue_mod_id].kgnb[8], - NR_UE_rrc_inst[ue_mod_id].kgnb[9], - NR_UE_rrc_inst[ue_mod_id].kgnb[10], - NR_UE_rrc_inst[ue_mod_id].kgnb[11], - NR_UE_rrc_inst[ue_mod_id].kgnb[12], - NR_UE_rrc_inst[ue_mod_id].kgnb[13], - NR_UE_rrc_inst[ue_mod_id].kgnb[14], - NR_UE_rrc_inst[ue_mod_id].kgnb[15], - NR_UE_rrc_inst[ue_mod_id].kgnb[16], - NR_UE_rrc_inst[ue_mod_id].kgnb[17], - NR_UE_rrc_inst[ue_mod_id].kgnb[18], - NR_UE_rrc_inst[ue_mod_id].kgnb[19], - NR_UE_rrc_inst[ue_mod_id].kgnb[20], - NR_UE_rrc_inst[ue_mod_id].kgnb[21], - NR_UE_rrc_inst[ue_mod_id].kgnb[22], - NR_UE_rrc_inst[ue_mod_id].kgnb[23], - NR_UE_rrc_inst[ue_mod_id].kgnb[24], - NR_UE_rrc_inst[ue_mod_id].kgnb[25], - NR_UE_rrc_inst[ue_mod_id].kgnb[26], - NR_UE_rrc_inst[ue_mod_id].kgnb[27], - NR_UE_rrc_inst[ue_mod_id].kgnb[28], - NR_UE_rrc_inst[ue_mod_id].kgnb[29], - NR_UE_rrc_inst[ue_mod_id].kgnb[30], - NR_UE_rrc_inst[ue_mod_id].kgnb[31]); - break; - - case NAS_UPLINK_DATA_REQ: { - uint32_t length; - uint8_t *buffer; - LOG_I(NR_RRC, "[UE %d] Received %s: UEid %d\n", ue_mod_id, ITTI_MSG_NAME(msg_p), NAS_UPLINK_DATA_REQ(msg_p).UEid); - /* Create message for PDCP (ULInformationTransfer_t) */ - length = - do_NR_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ(msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ(msg_p).nasMsg.data); - /* Transfer data to PDCP */ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].rnti, 0, 0, 0); - // check if SRB2 is created, if yes request data_req on SRB2 - rb_id_t srb_id = NR_UE_rrc_inst[ue_mod_id].Srb[0][2].status == RB_ESTABLISHED ? 2 : 1; - nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, nr_rrc_mui++, length, buffer, deliver_pdu_srb_rlc, NULL); - break; - } - - default: - LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME(msg_p)); - break; + case NR_RRC_DCCH_DATA_IND: + nr_rrc_ue_decode_dcch(instance, + NR_RRC_DCCH_DATA_IND(msg_p).rnti, + NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, + NR_RRC_DCCH_DATA_IND(msg_p).sdu_p, + NR_RRC_DCCH_DATA_IND(msg_p).sdu_size, + NR_RRC_DCCH_DATA_IND(msg_p).gNB_index); + break; + + case NAS_KENB_REFRESH_REQ: + memcpy(rrc->kgnb, NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(rrc->kgnb)); + break; + + case NAS_UPLINK_DATA_REQ: { + uint32_t length; + uint8_t *buffer; + NasUlDataReq *req = &NAS_UPLINK_DATA_REQ(msg_p); + /* Create message for PDCP (ULInformationTransfer_t) */ + length = do_NR_ULInformationTransfer(&buffer, req->nasMsg.length, req->nasMsg.data); + /* Transfer data to PDCP */ + // check if SRB2 is created, if yes request data_req on SRB2 + // error: the remote gNB is hardcoded here + rb_id_t srb_id = rrc->perNB[0].Srb[2].status == RB_ESTABLISHED ? 2 : 1; + nr_pdcp_data_req_srb(rrc->rnti, srb_id, 0, length, buffer, deliver_pdu_srb_rlc, NULL); + break; } - LOG_D(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, NR_UE_rrc_inst[ue_mod_id].nrRrcState); + + default: + LOG_E(NR_RRC, "[UE %ld] Received unexpected message %s\n", instance, ITTI_MSG_NAME(msg_p)); + break; + } + LOG_D(NR_RRC, "[UE %ld] RRC Status %d\n", instance, rrc->nrRrcState); int result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); return NULL; } -void nr_rrc_ue_process_sidelink_radioResourceConfig( - module_id_t Mod_idP, - uint8_t gNB_index, - NR_SetupRelease_SL_ConfigDedicatedNR_r16_t *sl_ConfigDedicatedNR -) +void nr_rrc_ue_process_sidelink_radioResourceConfig(instance_t Mod_idP, + uint8_t gNB_index, + NR_SetupRelease_SL_ConfigDedicatedNR_r16_t *sl_ConfigDedicatedNR) { //process sl_CommConfig, configure MAC/PHY for transmitting SL communication (RRC_CONNECTED) if (sl_ConfigDedicatedNR != NULL) { @@ -1938,77 +1643,53 @@ void nr_rrc_ue_process_sidelink_radioResourceConfig( } } -void nr_rrc_ue_process_ueCapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP, - NR_UECapabilityEnquiry_t *UECapabilityEnquiry, - uint8_t gNB_index) +static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECapabilityEnquiry_t *UECapabilityEnquiry) { - asn_enc_rval_t enc_rval; - asn_dec_rval_t dec_rval; - NR_UL_DCCH_Message_t ul_dcch_msg; - NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container; - char UE_NR_Capability_xer[65536]; - size_t size; - uint8_t buffer[500]; - LOG_I(NR_RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (gNB %d)\n", - ctxt_pP->module_id, - ctxt_pP->frame, - gNB_index); + NR_UL_DCCH_Message_t ul_dcch_msg = {0}; + // + LOG_I(NR_RRC, "Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry\n"); - memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); - memset((void *)&ue_CapabilityRAT_Container,0,sizeof(NR_UE_CapabilityRAT_Container_t)); ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; - ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1)); - ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation; - ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation)); - ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier; - ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr; - NR_UE_NR_Capability_t* UE_Capability_nr = NULL; + asn1cCalloc(ul_dcch_msg.message.choice.c1, c1); + c1->present = NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation; + asn1cCalloc(c1->choice.ueCapabilityInformation, info); + info->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier; + NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container = {.rat_Type = NR_RAT_Type_nr}; - char *file_path = NR_UE_rrc_inst[ctxt_pP->module_id].uecap_file; + char *file_path = rrc->uecap_file; FILE *f = NULL; if (file_path) f = fopen(file_path, "r"); if(f){ - size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f); + char UE_NR_Capability_xer[65536]; + size_t size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f); if (size == 0 || size == sizeof UE_NR_Capability_xer) { - LOG_E(NR_RRC,"UE Capabilities XER file %s is too large (%ld)\n", file_path,size); - free(UE_Capability_nr); + LOG_E(NR_RRC, "UE Capabilities XER file %s is too large (%ld)\n", file_path, size); return; } - dec_rval = xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&UE_Capability_nr, UE_NR_Capability_xer, size); + asn_dec_rval_t dec_rval = + xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&rrc->UECap.UE_NR_Capability, UE_NR_Capability_xer, size); assert(dec_rval.code == RC_OK); } else { - UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t)); - NR_BandNR_t *nr_bandnr; - nr_bandnr = CALLOC(1,sizeof(NR_BandNR_t)); + rrc->UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t)); + asn1cSequenceAdd(rrc->UECap.UE_NR_Capability->rf_Parameters.supportedBandListNR.list, NR_BandNR_t, nr_bandnr); nr_bandnr->bandNR = 1; - asn1cSeqAdd(&UE_Capability_nr->rf_Parameters.supportedBandListNR.list, - nr_bandnr); } - OAI_NR_UECapability_t *UECap; - UECap = CALLOC(1,sizeof(OAI_NR_UECapability_t)); - UECap->UE_NR_Capability = UE_Capability_nr; - xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,(void *)UE_Capability_nr); + xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, (void *)rrc->UECap.UE_NR_Capability); - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_NR_Capability, - NULL, - (void *)UE_Capability_nr, - &UECap->sdu[0], - MAX_UE_NR_CAPABILITY_SIZE); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_NR_Capability, + NULL, + (void *)rrc->UECap.UE_NR_Capability, + &rrc->UECap.sdu[0], + MAX_UE_NR_CAPABILITY_SIZE); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - UECap->sdu_size = (enc_rval.encoded + 7) / 8; - LOG_I(PHY, "[RRC]UE NR Capability encoded, %d bytes (%zd bits)\n", - UECap->sdu_size, enc_rval.encoded + 7); + rrc->UECap.sdu_size = (enc_rval.encoded + 7) / 8; + LOG_I(PHY, "[RRC]UE NR Capability encoded, %d bytes (%zd bits)\n", rrc->UECap.sdu_size, enc_rval.encoded + 7); - NR_UE_rrc_inst[ctxt_pP->module_id].UECap = UECap; - NR_UE_rrc_inst[ctxt_pP->module_id].UECapability = UECap->sdu; - NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size = UECap->sdu_size; - OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container, - (const char *)NR_UE_rrc_inst[ctxt_pP->module_id].UECapability, - NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size); + OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container, (const char *)rrc->UECap.sdu, rrc->UECap.sdu_size); NR_UECapabilityEnquiry_IEs_t *ueCapabilityEnquiry_ie = UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry; if (get_softmodem_params()->nsa == 1) { @@ -2023,17 +1704,15 @@ void nr_rrc_ue_process_ueCapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP, NR_UECapabilityInformation_t *ueCapabilityInformation = ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation; ueCapabilityInformation->criticalExtensions.present = NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation; - ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation = - CALLOC(1, sizeof(struct NR_UECapabilityInformation_IEs)); - ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList = - CALLOC(1, sizeof(struct NR_UE_CapabilityRAT_ContainerList)); - ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count = 0; + asn1cCalloc(ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation, infoIE); + asn1cCalloc(infoIE->ue_CapabilityRAT_ContainerList, UEcapList); + UEcapList->list.count = 0; for (int i = 0; i < ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.count; i++) { if (ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.array[i]->rat_Type == NR_RAT_Type_nr) { - asn1cSeqAdd(&ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list, - &ue_CapabilityRAT_Container); - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, 500); + asn1cSeqAdd(&UEcapList->list, &ue_CapabilityRAT_Container); + uint8_t buffer[500]; + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, 500); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); @@ -2042,30 +1721,18 @@ void nr_rrc_ue_process_ueCapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP, } LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); int srb_id = 1; // UECapabilityInformation on SRB1 - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, - srb_id, - nr_rrc_mui++, - (enc_rval.encoded + 7) / 8, - buffer, - deliver_pdu_srb_rlc, - NULL); + nr_pdcp_data_req_srb(rrc->rnti, srb_id, 0, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); } } } -void -nr_rrc_ue_generate_rrcReestablishmentComplete( - const protocol_ctxt_t *const ctxt_pP, - NR_RRCReestablishment_t *rrcReestablishment, - uint8_t gNB_index -) +static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment) //----------------------------------------------------------------------------- { uint8_t buffer[RRC_BUFFER_SIZE] = {0}; int size = do_RRCReestablishmentComplete(buffer, RRC_BUFFER_SIZE, rrcReestablishment->rrc_TransactionIdentifier); - LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes%d, gNB %d)\n", - ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index); + LOG_I(NR_RRC, "[RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes %d)\n", size); } void *recv_msgs_from_lte_ue(void *args_p) @@ -2087,7 +1754,7 @@ void *recv_msgs_from_lte_ue(void *args_p) LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen); continue; } - process_lte_nsa_msg(&msg, recvLen); + process_lte_nsa_msg(NR_UE_rrc_inst, &msg, recvLen); } return NULL; } @@ -2111,13 +1778,12 @@ void start_oai_nrue_threads() abort(); } - init_nrUE_standalone_thread(ue_id_g); - + init_nrUE_standalone_thread(0); } static void nsa_rrc_ue_process_ueCapabilityEnquiry(void) { - NR_UE_NR_Capability_t *UE_Capability_nr = CALLOC(1, sizeof(NR_UE_NR_Capability_t)); + NR_UE_NR_Capability_t *UE_Capability_nr = NR_UE_rrc_inst[0].UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t)); NR_BandNR_t *nr_bandnr = CALLOC(1, sizeof(NR_BandNR_t)); nr_bandnr->bandNR = 78; asn1cSeqAdd(&UE_Capability_nr->rf_Parameters.supportedBandListNR.list, nr_bandnr); @@ -2135,23 +1801,19 @@ static void nsa_rrc_ue_process_ueCapabilityEnquiry(void) LOG_A(NR_RRC, "[NR_RRC] NRUE Capability encoded, %d bytes (%zd bits)\n", UECap->sdu_size, enc_rval.encoded + 7); - NR_UE_rrc_inst[0].UECap = UECap; - NR_UE_rrc_inst[0].UECapability = UECap->sdu; - NR_UE_rrc_inst[0].UECapability_size = UECap->sdu_size; - NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container; memset(&ue_CapabilityRAT_Container, 0, sizeof(NR_UE_CapabilityRAT_Container_t)); ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr; OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container, - (const char *)NR_UE_rrc_inst[0].UECapability, - NR_UE_rrc_inst[0].UECapability_size); + (const char *)NR_UE_rrc_inst[0].UECap.sdu, + NR_UE_rrc_inst[0].UECap.sdu_size); nsa_sendmsg_to_lte_ue(ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.buf, ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.size, NRUE_CAPABILITY_INFO); } -void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len) +static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_len) { if (msg_len < sizeof(msg->msg_type)) { @@ -2288,12 +1950,12 @@ void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len) } } -void nr_ue_rrc_timer_trigger(int module_id, int frame, int gnb_id) +void nr_ue_rrc_timer_trigger(int instance, int frame, int gnb_id) { MessageDef *message_p; message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NRRRC_FRAME_PROCESS); NRRRC_FRAME_PROCESS(message_p).frame = frame; NRRRC_FRAME_PROCESS(message_p).gnb_id = gnb_id; LOG_D(NR_RRC, "RRC timer trigger: frame %d\n", frame); - itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p); + itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p); } diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index b4d967d304..5e04b6ce4a 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -184,6 +184,19 @@ typedef struct NR_UE_RRC_SRB_INFO_s { NR_RB_status_t status; } NR_UE_RRC_SRB_INFO_t; +typedef struct rrcPerNB { + NR_MeasObjectToAddMod_t *MeasObj[MAX_MEAS_OBJ]; + NR_ReportConfigToAddMod_t *ReportConfig[MAX_MEAS_CONFIG]; + NR_QuantityConfig_t *QuantityConfig; + NR_MeasIdToAddMod_t *MeasId[MAX_MEAS_ID]; + NR_MeasGapConfig_t *measGapConfig; + NR_UE_RRC_SRB_INFO_t Srb[NR_NUM_SRB]; + bool active_DRBs[MAX_DRBS_PER_UE]; + bool active_RLC_entity[NR_MAX_NUM_LCID]; + NR_UE_RRC_SI_INFO SInfo; + NR_RSRP_Range_t s_measure; +} rrcPerNB_t; + typedef struct NR_UE_RRC_INST_s { NR_MeasConfig_t *meas_config; NR_CellGroupConfig_t *cell_group_config; @@ -191,33 +204,16 @@ typedef struct NR_UE_RRC_INST_s { NR_CellGroupConfig_t *scell_group_config; NR_RadioBearerConfig_t *radio_bearer_config; - NR_MeasObjectToAddMod_t *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ]; - NR_ReportConfigToAddMod_t *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG]; - NR_QuantityConfig_t *QuantityConfig[NB_CNX_UE]; - NR_MeasIdToAddMod_t *MeasId[NB_CNX_UE][MAX_MEAS_ID]; - NR_MeasGapConfig_t *measGapConfig[NB_CNX_UE]; - NR_RSRP_Range_t s_measure; + rrcPerNB_t perNB[NB_CNX_UE]; char *uecap_file; rnti_t rnti; - NR_UE_RRC_SRB_INFO_t Srb[NB_CNX_UE][NR_NUM_SRB]; - bool active_DRBs[NB_CNX_UE][MAX_DRBS_PER_UE]; - bool active_RLC_entity[NB_CNX_UE][NR_MAX_NUM_LCID]; - - OAI_NR_UECapability_t *UECap; - uint8_t *UECapability; - uint16_t UECapability_size; - + OAI_NR_UECapability_t UECap; NR_UE_Timers_Constants_t timers_and_constants; - - RA_trigger_t ra_trigger; - plmn_t plmnID; - NR_UE_RRC_SI_INFO SInfo[NB_CNX_UE]; - - NR_MIB_t *mib; + // NR_MIB_t *mib; // active BWPs NR_BWP_DownlinkDedicated_t *bwpd; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index c9d0e40221..95330eabd2 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -65,27 +65,6 @@ NR_UE_RRC_INST_t *nr_l3_init_ue(char *, char *, char *); /**\brief Initial the top level RRC structure instance*/ NR_UE_RRC_INST_t *openair_rrc_top_init_ue_nr(char *, char *, char *); -/**\brief Process NR RRC connection reconfiguration via SRB3 - \param rrcReconfiguration decoded rrc connection reconfiguration*/ -int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration); - -/**\prief Process measurement config from NR RRC connection reconfiguration message - \param meas_config measurement configuration*/ -int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config); - -void nr_rrc_ue_process_RadioBearerConfig(const protocol_ctxt_t *const ctxt_pP, - const uint8_t gNB_index, - NR_RadioBearerConfig_t *const radioBearerConfig); - -/**\brief decode NR BCCH-BCH (MIB) message - \param module_idP module id - \param gNB_index gNB index - \param sduP pointer to buffer of ASN message BCCH-BCH - \param sdu_len length of buffer*/ -int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len); - -int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(const module_id_t module_id, const uint8_t gNB_index, const uint8_t *buffer, const uint32_t size); - /**\brief interface between MAC and RRC thru SRB0 (RLC TM/no PDCP) \param module_id module id \param CC_id component carrier id @@ -109,8 +88,6 @@ void nr_mac_rrc_sync_ind(const module_id_t module_id, void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success); void nr_mac_rrc_msg3_ind(const module_id_t mod_id, int rnti); -int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index); - /**\brief RRC UE task. \param void *args_p Pointer on arguments to start the task. */ void *rrc_nrue_task(void *args_p); @@ -128,18 +105,12 @@ void nsa_sendmsg_to_lte_ue(const void *message, size_t msg_len, Rrc_Msg_Type_t m void start_oai_nrue_threads(void); -/**\brief RRC UE generate RRCSetupRequest message. */ -void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, int rnti); - -void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len); - int get_from_lte_ue_fd(); void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo); void nr_ue_rrc_timer_trigger(int module_id, int frame, int gnb_id); -void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config); void reset_rlf_timers_and_constants(NR_UE_Timers_Constants_t *tac); void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac); void nr_rrc_set_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1); @@ -149,12 +120,8 @@ void handle_rlf_sync(NR_UE_Timers_Constants_t *tac, void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc, struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants); -void nr_rrc_manage_rlc_bearers(const NR_CellGroupConfig_t *cellGroupConfig, - NR_UE_RRC_INST_t *rrc, - int gNB_index, - module_id_t module_id, - int rnti); - int configure_NR_SL_Preconfig(int sync_source); + +/** @}*/ #endif diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c index c628b0219b..0a7010850d 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -374,7 +374,7 @@ void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc, switch(rlf_TimersAndConstants->present){ case NR_SetupRelease_RLF_TimersAndConstants_PR_release : // use values for timers T301, T310, T311 and constants N310, N311, as included in ue-TimersAndConstants received in SIB1 - set_rlf_sib1_timers_and_constants(tac, rrc->SInfo[0].sib1); + set_rlf_sib1_timers_and_constants(tac, rrc->perNB[0].SInfo.sib1); break; case NR_SetupRelease_RLF_TimersAndConstants_PR_setup : rlf_tac = rlf_TimersAndConstants->choice.setup; diff --git a/openair2/RRC/NR_UE/rrc_vars.h b/openair2/RRC/NR_UE/rrc_vars.h deleted file mode 100644 index ecb9335131..0000000000 --- a/openair2/RRC/NR_UE/rrc_vars.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/* \file vars.h - * \brief RRC layer variables - * \author R. Knopp, K.H. HSU - * \date 2018 - * \version 0.1 - * \company Eurecom / NTUST - * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr - * \note - * \warning - */ - - -#ifndef __OPENAIR_NR_RRC_VARS_H__ -#define __OPENAIR_NR_RRC_VARS_H__ - -#include "rrc_defs.h" - -extern NR_UE_RRC_INST_t *NR_UE_rrc_inst; -extern uint16_t ue_id_g; - -#endif