diff --git a/CMakeLists.txt b/CMakeLists.txt index 110a10bf04..28d6e31572 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1457,7 +1457,7 @@ set(NR_L2_SRC_UE ${NR_RRC_DIR}/nr_rrc_config.c ${NR_UE_RRC_DIR}/rrc_UE.c ${NR_UE_RRC_DIR}/rrc_nsa.c - ${NR_RRC_DIR}/nr_rrc_config.c + ${NR_UE_RRC_DIR}/rrc_timers_and_constants.c ) set (MAC_SRC diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 38c3020dc9..1b56dfccdb 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -938,6 +938,8 @@ void *UE_thread(void *arg) { timing_advance = UE->timing_advance; } + nr_ue_rrc_timer_trigger(UE->Mod_id, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx); + // Start TX slot processing here. It runs in parallel with RX slot processing notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, &txFifo, processSlotTX); nr_rxtx_thread_data_t *curMsgTx = (nr_rxtx_thread_data_t *) NotifiedFifoData(newElt); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 231084e529..18eacbff86 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -214,10 +214,6 @@ int create_tasks_nrue(uint32_t ue_nb) { itti_wait_ready(0); - // Thread to update the RRC timers (in msec) at UE - pthread_t timers_update; - threadCreate(&timers_update, nr_rrc_timers_update, NULL, "nr_rrc_timer_update", -1, OAI_PRIORITY_RT_LOW); - return 0; } diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index 5a1c2be6e8..930e0d3840 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -38,7 +38,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const frame_t frame, - const sub_frame_t sub_frame, + const int slot, const rnti_t rnti, const channel_t channel, const uint8_t* pduP, diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index e43d0007e7..6a671eeb10 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -91,7 +91,7 @@ typedef struct RrcMacBcchDataInd_s { typedef struct NRRrcMacBcchDataInd_s { uint32_t frame; - uint8_t sub_frame; + uint8_t slot; uint32_t sdu_size; uint8_t sdu[BCCH_SDU_SIZE]; uint8_t gnb_index; @@ -140,7 +140,7 @@ typedef struct RrcMacCcchDataInd_s { typedef struct NRRrcMacCcchDataInd_s { uint32_t frame; - uint8_t sub_frame; + uint8_t slot; uint16_t rnti; uint32_t sdu_size; uint8_t sdu[CCCH_SDU_SIZE]; diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index f70c8bdd0e..12e6269da0 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -79,6 +79,7 @@ MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd // eNB: realtime -> RRC messages MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeProcess, rrc_subframe_process) +MESSAGE_DEF(NRRRC_SLOT_PROCESS, MESSAGE_PRIORITY_MED, NRRrcSlotProcess, nr_rrc_slot_process) // eNB: RLC -> RRC messages MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 359720f92f..87ad04a2dc 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -88,6 +88,7 @@ #define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind #define RRC_SUBFRAME_PROCESS(mSGpTR) (mSGpTR)->ittiMsg.rrc_subframe_process +#define NRRRC_SLOT_PROCESS(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_slot_process #define RLC_SDU_INDICATION(mSGpTR) (mSGpTR)->ittiMsg.rlc_sdu_indication #define NRDuDlReq(mSGpTR) (mSGpTR)->ittiMsg.nr_du_dl_req @@ -460,9 +461,14 @@ typedef dl_info_transfer_ind_t NasDlDataInd; // eNB: realtime -> RRC messages typedef struct rrc_subframe_process_s { protocol_ctxt_t ctxt; - int CC_id; + int CC_id; } RrcSubframeProcess; +typedef struct nrrrc_slot_process_s { + int frame; + int slot; +} NRRrcSlotProcess; + // eNB: RLC -> RRC messages typedef struct rlc_sdu_indication_s { int rnti; diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 06251fcff8..5c3b100efd 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -115,12 +115,12 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, ccch_sdu_len = rrccont->value.choice.RRCContainer.size; memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, rrccont->value.choice.RRCContainer.buf, ccch_sdu_len); - NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0; - NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0; + NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0; + NR_RRC_MAC_CCCH_DATA_IND (message_p).slot = 0; NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len; NR_RRC_MAC_CCCH_DATA_IND (message_p).nr_cellid = nr_cellid; // CU instance - NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; - NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id; + NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; + NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id; if (du2cu) { NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t)); NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = du2cu->value.choice.DUtoCURRCContainer.size; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index e80459ee5f..534279e2e2 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -206,8 +206,6 @@ typedef int (nr_ue_dl_indication_f)(nr_downlink_indication_t *dl_info); */ typedef int (nr_ue_ul_indication_f)(nr_uplink_indication_t *ul_info); -typedef int (nr_ue_dcireq_f)(nr_dcireq_t *ul_info); - // TODO check this stuff can be reuse of need modification typedef struct nr_ue_if_module_s { nr_ue_scheduled_response_f *scheduled_response; @@ -215,7 +213,6 @@ typedef struct nr_ue_if_module_s { nr_ue_synch_request_f *synch_request; nr_ue_dl_indication_f *dl_indication; nr_ue_ul_indication_f *ul_indication; - //nr_ue_dcireq_f *dcireq; uint32_t cc_mask; uint32_t current_frame; uint32_t current_slot; diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index b83c791291..ce0b2ff44b 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -39,91 +39,90 @@ typedef uint32_t channel_t; -int8_t -nr_mac_rrc_data_ind_ue( - const module_id_t module_id, - const int CC_id, - const uint8_t gNB_index, - const frame_t frame, - const sub_frame_t sub_frame, - const rnti_t rnti, - const channel_t channel, - const uint8_t* pduP, - const sdu_size_t pdu_len){ - sdu_size_t sdu_size = 0; +int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, + const int CC_id, + const uint8_t gNB_index, + const frame_t frame, + const int slot, + const rnti_t rnti, + const channel_t channel, + const uint8_t* pduP, + const sdu_size_t pdu_len) +{ + sdu_size_t sdu_size = 0; - switch(channel){ - case NR_BCCH_BCH: - AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n"); - break; + switch(channel){ + case NR_BCCH_BCH: + AssertFatal(nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n"); + break; - case NR_BCCH_DL_SCH: - if (pdu_len>0) { - LOG_T(NR_RRC, "[UE %d] Received SDU for NR-BCCH-DL-SCH on SRB %u from gNB %d\n", module_id, channel & RAB_OFFSET, - gNB_index); + case NR_BCCH_DL_SCH: + if (pdu_len>0) { + LOG_T(NR_RRC, "[UE %d] Received SDU for NR-BCCH-DL-SCH on SRB %u from gNB %d\n", module_id, channel & RAB_OFFSET, + gNB_index); - MessageDef *message_p; - int msg_sdu_size = BCCH_SDU_SIZE; + MessageDef *message_p; + int msg_sdu_size = BCCH_SDU_SIZE; - if (pdu_len > msg_sdu_size) { - LOG_E(NR_RRC, "SDU larger than NR-BCCH-DL-SCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); - sdu_size = msg_sdu_size; - } else { - sdu_size = pdu_len; - } - - message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_BCCH_DATA_IND); - memset(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); - memcpy(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, pduP, sdu_size); - NR_RRC_MAC_BCCH_DATA_IND (message_p).frame = frame; //frameP - NR_RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frame; //sub_frameP - NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; - NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index; - itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p); + if (pdu_len > msg_sdu_size) { + LOG_E(NR_RRC, "SDU larger than NR-BCCH-DL-SCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); + sdu_size = msg_sdu_size; + } else { + sdu_size = pdu_len; } - break; - case CCCH: - if (pdu_len>0) { - LOG_T(NR_RRC,"[UE %d] Received SDU for CCCH on SRB %u from gNB %d\n",module_id,channel & RAB_OFFSET,gNB_index); + message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_BCCH_DATA_IND); + memset(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); + memcpy(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, pduP, sdu_size); + NR_RRC_MAC_BCCH_DATA_IND (message_p).frame = frame; //frameP + NR_RRC_MAC_BCCH_DATA_IND (message_p).slot = slot; + NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; + NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index; + itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p); + } + break; - MessageDef *message_p; - int msg_sdu_size = CCCH_SDU_SIZE; + case CCCH: + if (pdu_len>0) { + LOG_T(NR_RRC,"[UE %d] Received SDU for CCCH on SRB %u from gNB %d\n",module_id,channel & RAB_OFFSET,gNB_index); - if (pdu_len > msg_sdu_size) { - LOG_E(NR_RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); - sdu_size = msg_sdu_size; - } else { - sdu_size = pdu_len; - } + MessageDef *message_p; + int msg_sdu_size = CCCH_SDU_SIZE; - message_p = itti_alloc_new_message (TASK_MAC_UE, 0, NR_RRC_MAC_CCCH_DATA_IND); - memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, pduP, sdu_size); - NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = frame; //frameP - NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frame; //sub_frameP - NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size; - NR_RRC_MAC_CCCH_DATA_IND (message_p).gnb_index = gNB_index; - NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; //rntiP - itti_send_msg_to_task (TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE( module_id ), message_p); + if (pdu_len > msg_sdu_size) { + LOG_E(NR_RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); + sdu_size = msg_sdu_size; + } else { + sdu_size = pdu_len; } - break; - default: - break; - } + message_p = itti_alloc_new_message (TASK_MAC_UE, 0, NR_RRC_MAC_CCCH_DATA_IND); + memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); + memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, pduP, sdu_size); + NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = frame; //frameP + NR_RRC_MAC_CCCH_DATA_IND (message_p).slot = slot; + NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size; + NR_RRC_MAC_CCCH_DATA_IND (message_p).gnb_index = gNB_index; + NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; //rntiP + itti_send_msg_to_task (TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE( module_id ), message_p); + } + break; - return(0); + default: + break; + } + + return(0); } int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, - const int CC_id, - const uint8_t gNB_id, - const frame_t frameP, - const rb_id_t Srb_id, - uint8_t *buffer_pP){ - - switch(Srb_id){ + const int CC_id, + const uint8_t gNB_id, + const frame_t frameP, + const rb_id_t Srb_id, + uint8_t *buffer_pP) +{ + switch(Srb_id) { case CCCH: @@ -148,9 +147,9 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { - if (NR_UE_rrc_inst[mod_id].timers_and_constants.T304_active == 1) { + if (NR_UE_rrc_inst[mod_id].timers_and_constants.T304_active == true) { LOG_W(NR_RRC, "T304 was stoped with value %i\n", NR_UE_rrc_inst[mod_id].timers_and_constants.T304_cnt); - NR_UE_rrc_inst[mod_id].timers_and_constants.T304_active = 0; + NR_UE_rrc_inst[mod_id].timers_and_constants.T304_active = false; NR_UE_rrc_inst[mod_id].timers_and_constants.T304_cnt = 0; } return 0; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 00546f01df..c8d4403094 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -229,7 +229,7 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, LOG_E(NR_RRC, "%02x ",buffer[i]); LOG_E(NR_RRC, "\n"); // free the memory - SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 1 ); + SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 1); return -1; } @@ -238,6 +238,9 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, 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); + return 0; } @@ -268,7 +271,7 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR (uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf, rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size, 0, 0); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); } @@ -280,6 +283,10 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR 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; } + + if(cellGroupConfig->spCellConfig != NULL) + configure_spcell(&NR_UE_rrc_inst[module_id], cellGroupConfig->spCellConfig); + if (get_softmodem_params()->nsa) { nr_rrc_mac_config_req_scg(0, 0, cellGroupConfig); } @@ -386,24 +393,28 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, } -NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_path){ - int nr_ue; - if(NB_NR_UE_INST > 0){ +NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_path) +{ + if(NB_NR_UE_INST > 0) { NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(NB_NR_UE_INST , sizeof(NR_UE_RRC_INST_t)); - for(nr_ue=0;nr_ueselected_plmn_identity = 1; + + rrc->bwpd = NULL; + rrc->ubwpd = NULL; // TODO: Put the appropriate list of SIBs - NR_UE_rrc_inst[nr_ue].requested_SI_List.buf = CALLOC(1,4); - NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[0] = SIB2 | SIB3 | SIB5; // SIB2 - SIB9 - NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[1] = 0; // SIB10 - SIB17 - NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[2] = 0; // SIB18 - SIB25 - NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[3] = 0; // SIB26 - SIB32 - NR_UE_rrc_inst[nr_ue].requested_SI_List.size= 4; - NR_UE_rrc_inst[nr_ue].requested_SI_List.bits_unused= 0; + rrc->requested_SI_List.buf = CALLOC(1,4); + rrc->requested_SI_List.buf[0] = SIB2 | SIB3 | SIB5; // SIB2 - SIB9 + rrc->requested_SI_List.buf[1] = 0; // SIB10 - SIB17 + rrc->requested_SI_List.buf[2] = 0; // SIB18 - SIB25 + rrc->requested_SI_List.buf[3] = 0; // SIB26 - SIB32 + rrc->requested_SI_List.size= 4; + rrc->requested_SI_List.bits_unused= 0; - NR_UE_rrc_inst[nr_ue].ra_trigger = RA_NOT_RUNNING; + rrc->ra_trigger = RA_NOT_RUNNING; } NR_UE_rrc_inst->uecap_file = uecap_file; @@ -473,11 +484,6 @@ int8_t nr_ue_process_physical_cell_group_config(NR_PhysicalCellGroupConfig_t *ph return 0; } -int8_t nr_ue_process_spcell_config(NR_SpCellConfig_t *spcell_config){ - - return 0; -} - /*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) { @@ -1031,32 +1037,32 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, NR_BCCH_DL_SCH_Message_t *bcch_message = NULL; NR_UE_RRC_SI_INFO *SI_info = &NR_UE_rrc_inst[module_id].SInfo[gNB_index]; NR_SIB1_t *sib1 = SI_info->sib1; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN); if (((SI_info->SIStatus & 1) == 1) && sib1->si_SchedulingInfo &&// SIB1 received (SI_info->SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) { // to prevent memory bloating - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT); return 0; } - nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR ); + nr_rrc_set_sub_state(module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR); - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_BCCH_DL_SCH_Message, - (void **)&bcch_message, - (const void *)Sdu, - Sdu_len ); + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_NR_BCCH_DL_SCH_Message, + (void **)&bcch_message, + (const void *)Sdu, + Sdu_len); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message ); + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message); } 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", + LOG_E(NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", module_id, - dec_rval.consumed ); - log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" ); + 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 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); @@ -1067,14 +1073,14 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, switch (bcch_message->message.choice.c1->present) { case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: if ((SI_info->SIStatus & 1) == 0) { - if(sib1 != NULL){ - SEQUENCE_free(&asn_DEF_NR_SIB1, (void *)sib1, 1 ); + if(sib1 != NULL) { + SEQUENCE_free(&asn_DEF_NR_SIB1, (void *)sib1, 1); } SI_info->SIStatus |= 1; sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; if (*(int64_t*)sib1 != 1) { SI_info->sib1 = sib1; - if( g_log->log_component[NR_RRC].level >= OAILOG_DEBUG ) { + if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) { xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) SI_info->sib1); } LOG_A(NR_RRC, "SIB1 decoded\n"); @@ -1083,11 +1089,13 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, // FIXME: improve condition for the RA trigger // Check for on-demand not broadcasted SI check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); - if( nr_rrc_get_state(module_id) <= RRC_STATE_IDLE_NR ) { + if(nr_rrc_get_state(module_id) <= RRC_STATE_IDLE_NR) { NR_UE_rrc_inst[module_id].ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE; LOG_D(PHY,"Setting state to RRC_STATE_IDLE_NR\n"); nr_rrc_set_state (module_id, RRC_STATE_IDLE_NR); } + // configure timers and constant + nr_rrc_set_sib1_timers_and_constants(&NR_UE_rrc_inst[module_id].timers_and_constants, sib1); // take ServingCellConfigCommon and configure L1/L2 NR_UE_rrc_inst[module_id].servingCellConfigCommonSIB = sib1->servingCellConfigCommon; nr_rrc_mac_config_req_sib1(module_id, 0, sib1->servingCellConfigCommon); @@ -1135,88 +1143,55 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, return 0; } -//----------------------------------------------------------------------------- + void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP, uint8_t gNB_index, - OCTET_STRING_t *masterCellGroup) -//----------------------------------------------------------------------------- + OCTET_STRING_t *masterCellGroup, + long *fullConfig) { - NR_CellGroupConfig_t *cellGroupConfig=NULL; + NR_CellGroupConfig_t *cellGroupConfig = NULL; uper_decode(NULL, &asn_DEF_NR_CellGroupConfig, //might be added prefix later (void **)&cellGroupConfig, (uint8_t *)masterCellGroup->buf, masterCellGroup->size, 0, 0); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); } - // TS 38.331 - Section 5.3.5.5.2 Reconfiguration with sync - if (cellGroupConfig->spCellConfig != NULL && cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL) { + NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[ctxt_pP->module_id]; - LOG_A(NR_RRC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__); - - NR_ReconfigurationWithSync_t *reconfigurationWithSync = cellGroupConfig->spCellConfig->reconfigurationWithSync; - NR_UE_Timers_Constants_t *timers_and_constants = &NR_UE_rrc_inst[ctxt_pP->module_id].timers_and_constants; - timers_and_constants->T304_active = 1; - switch (reconfigurationWithSync->t304) { - case NR_ReconfigurationWithSync__t304_ms100: - timers_and_constants->T304_cnt = 100; - break; - case NR_ReconfigurationWithSync__t304_ms150: - timers_and_constants->T304_cnt = 150; - break; - case NR_ReconfigurationWithSync__t304_ms200: - timers_and_constants->T304_cnt = 200; - break; - case NR_ReconfigurationWithSync__t304_ms500: - timers_and_constants->T304_cnt = 500; - break; - case NR_ReconfigurationWithSync__t304_ms1000: - timers_and_constants->T304_cnt = 1000; - break; - case NR_ReconfigurationWithSync__t304_ms2000: - timers_and_constants->T304_cnt = 2000; - break; - case NR_ReconfigurationWithSync__t304_ms10000: - timers_and_constants->T304_cnt = 10000; - break; - default: - timers_and_constants->T304_cnt = 50; - } + if(rrc->cell_group_config == NULL){ + rrc->cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t)); } - if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config == NULL){ - NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t)); - } - - if( cellGroupConfig->rlc_BearerToReleaseList != NULL){ + if(cellGroupConfig->rlc_BearerToReleaseList != NULL){ //TODO (perform RLC bearer release as specified in 5.3.5.5.3) } - if( cellGroupConfig->rlc_BearerToAddModList != NULL){ + if(cellGroupConfig->rlc_BearerToAddModList != NULL){ //TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4) - if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList != NULL){ + if(rrc->cell_group_config->rlc_BearerToAddModList != NULL){ // Laurent: there are cases where the not NULL value is also not coming from a previous malloc - // so it is better to let the potential memory leak than corrupting the heap //free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList); + // so it is better to let the potential memory leak than corrupting the heap //free(rrc->cell_group_config->rlc_BearerToAddModList); } - NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList = calloc(1, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList)); - memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList,cellGroupConfig->rlc_BearerToAddModList, + rrc->cell_group_config->rlc_BearerToAddModList = calloc(1, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList)); + memcpy(rrc->cell_group_config->rlc_BearerToAddModList,cellGroupConfig->rlc_BearerToAddModList, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList)); } - if( cellGroupConfig->mac_CellGroupConfig != NULL){ + if(cellGroupConfig->mac_CellGroupConfig != NULL){ //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5) LOG_I(RRC, "Received mac_CellGroupConfig from gNB\n"); - if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig != NULL){ + if(rrc->cell_group_config->mac_CellGroupConfig != NULL){ LOG_E(RRC, "UE RRC instance already contains mac CellGroupConfig which will be overwritten\n"); // Laurent: there are cases where the not NULL value is also not coming from a previous malloc // so it is better to let the potential memory leak than corrupting the heap - //free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig); + //free(rrc->cell_group_config->mac_CellGroupConfig); } - NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig)); - memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig, + rrc->cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig)); + memcpy(rrc->cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig, sizeof(struct NR_MAC_CellGroupConfig)); } @@ -1225,21 +1200,34 @@ void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP, } if(cellGroupConfig->spCellConfig != NULL) { - if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config && - NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig) { - memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig,cellGroupConfig->spCellConfig, + configure_spcell(rrc, cellGroupConfig->spCellConfig); + // TS 38.331 - Section 5.3.5.5.2 Reconfiguration with sync + if (cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL) { + if(fullConfig) + set_default_timers_and_constants(&rrc->timers_and_constants); + LOG_A(NR_RRC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__); + NR_ReconfigurationWithSync_t *reconfigurationWithSync = cellGroupConfig->spCellConfig->reconfigurationWithSync; + nr_rrc_set_T304(&rrc->timers_and_constants, reconfigurationWithSync); + } + + if (rrc->cell_group_config && + rrc->cell_group_config->spCellConfig) { + memcpy(rrc->cell_group_config->spCellConfig,cellGroupConfig->spCellConfig, sizeof(struct NR_SpCellConfig)); } else { - if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config) - NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig = cellGroupConfig->spCellConfig; + if (rrc->cell_group_config) + rrc->cell_group_config->spCellConfig = cellGroupConfig->spCellConfig; else - NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = cellGroupConfig; + 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); - //TODO (configure the SpCell as specified in 5.3.5.5.7) } + 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); + if( cellGroupConfig->sCellToAddModList != NULL){ //TODO (perform SCell addition/modification as specified in 5.3.5.5.9) } @@ -1253,6 +1241,51 @@ 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) +{ + nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spcell_config->rlf_TimersAndConstants); + + if(spcell_config->spCellConfigDedicated) { + NR_ServingCellConfig_t *scd = spcell_config->spCellConfigDedicated; + if(scd->firstActiveDownlinkBWP_Id) { + if(*scd->firstActiveDownlinkBWP_Id == 0) + rrc->bwpd = scd->initialDownlinkBWP; + else { + AssertFatal(scd->downlinkBWP_ToAddModList, "No DL BWP list configured\n"); + const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = scd->downlinkBWP_ToAddModList; + NR_BWP_Downlink_t *dl_bwp = NULL; + for (int i = 0; i < bwpList->list.count; i++) { + dl_bwp = bwpList->list.array[i]; + if(dl_bwp->bwp_Id == *scd->firstActiveDownlinkBWP_Id) + break; + } + AssertFatal(dl_bwp != NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n", *scd->firstActiveDownlinkBWP_Id); + rrc->bwpd = dl_bwp->bwp_Dedicated; + } + // if any of the reference signal(s) that are used for radio link monitoring are reconfigured by the received spCellConfigDedicated + // reset RLF timers and constants + if (rrc->bwpd->radioLinkMonitoringConfig) + reset_rlf_timers_and_constants(&rrc->timers_and_constants); + } + if(scd->uplinkConfig && scd->uplinkConfig->firstActiveUplinkBWP_Id) { + if(*scd->uplinkConfig->firstActiveUplinkBWP_Id == 0) + rrc->ubwpd = scd->uplinkConfig->initialUplinkBWP; + else { + AssertFatal(scd->uplinkConfig->uplinkBWP_ToAddModList, "No UL BWP list configured\n"); + const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = scd->uplinkConfig->uplinkBWP_ToAddModList; + NR_BWP_Uplink_t *ul_bwp = NULL; + for (int i = 0; i < ubwpList->list.count; i++) { + ul_bwp = ubwpList->list.array[i]; + if(ul_bwp->bwp_Id == *scd->uplinkConfig->firstActiveUplinkBWP_Id) + break; + } + AssertFatal(ul_bwp != NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n", *scd->uplinkConfig->firstActiveUplinkBWP_Id); + rrc->ubwpd = ul_bwp->bwp_Dedicated; + } + } + } +} + /*--------------------------------------------------*/ static void rrc_ue_generate_RRCSetupComplete( const protocol_ctxt_t *const ctxt_pP, @@ -1345,7 +1378,7 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB // Release T300 timer NR_UE_rrc_inst[ctxt_pP->module_id].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); + 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_set_state(ctxt_pP->module_id, RRC_STATE_CONNECTED_NR); nr_rrc_set_sub_state(ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED_NR); @@ -2044,11 +2077,11 @@ nr_rrc_ue_establish_srb2( // 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); + 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) { @@ -2231,15 +2264,33 @@ nr_rrc_ue_establish_srb2( return 0; } - //----------------------------------------------------------------------------- - void *rrc_nrue_task( void *args_p ) { - MessageDef *msg_p; - instance_t instance; - unsigned int ue_mod_id; - int result; - NR_SRB_INFO *srb_info_p; - protocol_ctxt_t ctxt; - itti_mark_task_ready (TASK_RRC_NRUE); + +void nr_rrc_handle_timers(unsigned int mod_id) +{ + NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[mod_id].timers_and_constants; + // T304 + if (timers->T304_active == true) { + timers->T304_cnt += 10; + if(timers->T304_cnt >= timers->T304_k) { + // TODO + // For T304 of MCG, in case of the handover from NR or intra-NR + // handover, initiate the RRC re-establishment procedure; + // In case of handover to NR, perform the actions defined in the + // specifications applicable for the source RAT. + } + } +} + + +void *rrc_nrue_task(void *args_p) +{ + MessageDef *msg_p; + instance_t instance; + unsigned int ue_mod_id; + int result; + NR_SRB_INFO *srb_info_p; + protocol_ctxt_t ctxt; + itti_mark_task_ready(TASK_RRC_NRUE); while(1) { // Wait for a message @@ -2257,16 +2308,22 @@ nr_rrc_ue_establish_srb2( LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); break; + case NRRRC_SLOT_PROCESS: + LOG_D(NR_RRC, "[UE %d] Receided %s: frame %d slot %d\n", + ue_mod_id, ITTI_MSG_NAME (msg_p), NRRRC_SLOT_PROCESS (msg_p).frame, NRRRC_SLOT_PROCESS (msg_p).slot); + nr_rrc_handle_timers(ue_mod_id); + break; + case NR_RRC_MAC_BCCH_DATA_IND: LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id, - NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index, - NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu, - NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size, - NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrq, - NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrp); + NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index, + NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu, + NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size, + NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrq, + NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrp); break; case NR_RRC_MAC_CCCH_DATA_IND: @@ -2278,18 +2335,24 @@ nr_rrc_ue_establish_srb2( NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); srb_info_p = &NR_UE_rrc_inst[ue_mod_id].Srb0[NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index]; memcpy (srb_info_p->Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu, - NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size); + NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size); srb_info_p->Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0); - // PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); - nr_rrc_ue_decode_ccch (&ctxt, - srb_info_p, - NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); + // PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); + nr_rrc_ue_decode_ccch (&ctxt, + srb_info_p, + NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); 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); + 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), @@ -2725,28 +2788,12 @@ void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len) } } -void *nr_rrc_timers_update() { - - while (1) { - - for (int mod_id = 0; mod_id < NB_NR_UE_INST; mod_id++) { - for (int i = 0; i < NB_SIG_CNX_UE; i++) { - NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[mod_id].timers_and_constants; - - // T304 - if (timers->T304_active == 1) { - if ((timers->T304_cnt % 100) == 0) { - LOG_W(NR_RRC, "T304: %u\n", timers->T304_cnt); - } - if (timers->T304_cnt == 1) { - timers->T304_active = 0; - } - timers->T304_cnt--; - } - - } - } - - usleep(1000); - } +void nr_ue_rrc_timer_trigger(int module_id, int frame, int slot) +{ + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NRRRC_SLOT_PROCESS); + NRRRC_SLOT_PROCESS(message_p).frame = frame; + NRRRC_SLOT_PROCESS(message_p).slot = slot; + LOG_D(NR_RRC, "RRC timer trigger: frame %d slot %d \n", frame, slot); + itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p); } diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index ff5754396e..996069ad68 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -224,6 +224,10 @@ typedef struct NR_UE_RRC_INST_s { NR_MIB_t *mib; + // active BWPs + NR_BWP_DownlinkDedicated_t *bwpd; + NR_BWP_UplinkDedicated_t *ubwpd; + /* KeNB as computed from parameters within USIM card */ uint8_t kgnb[32]; /* Used integrity/ciphering algorithms */ diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index da79f9a092..418c71240c 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -107,7 +107,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const frame_t frame, - const sub_frame_t sub_frame, + const int slot, const rnti_t rnti, const channel_t channel, const uint8_t* pduP, @@ -155,6 +155,16 @@ void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len); int get_from_lte_ue_fd(); +void nr_ue_rrc_timer_trigger(int module_id, int frame, int slot); + +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); +void nr_rrc_set_T304(NR_UE_Timers_Constants_t *tac, NR_ReconfigurationWithSync_t *reconfigurationWithSync); +void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc, + struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants); + /** @}*/ #endif diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c new file mode 100644 index 0000000000..f9fc11095b --- /dev/null +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -0,0 +1,422 @@ +/* + * 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 + */ + +#include "openair2/RRC/NR_UE/rrc_proto.h" + + +void nr_rrc_set_T304(NR_UE_Timers_Constants_t *tac, NR_ReconfigurationWithSync_t *reconfigurationWithSync) +{ + if(reconfigurationWithSync) { + switch (reconfigurationWithSync->t304) { + case NR_ReconfigurationWithSync__t304_ms50 : + tac->T304_k = 50; + break; + case NR_ReconfigurationWithSync__t304_ms100 : + tac->T304_k = 100; + break; + case NR_ReconfigurationWithSync__t304_ms150 : + tac->T304_k = 150; + break; + case NR_ReconfigurationWithSync__t304_ms200 : + tac->T304_k = 200; + break; + case NR_ReconfigurationWithSync__t304_ms500 : + tac->T304_k = 500; + break; + case NR_ReconfigurationWithSync__t304_ms1000 : + tac->T304_k = 1000; + break; + case NR_ReconfigurationWithSync__t304_ms2000 : + tac->T304_k = 2000; + break; + case NR_ReconfigurationWithSync__t304_ms10000 : + tac->T304_k = 10000; + break; + default : + AssertFatal(false, "Invalid T304 %ld\n", reconfigurationWithSync->t304); + } + } +} + +void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1) +{ + if(sib1 && sib1->ue_TimersAndConstants) { + switch (sib1->ue_TimersAndConstants->t301) { + case NR_UE_TimersAndConstants__t301_ms100 : + tac->T301_k = 100; + break; + case NR_UE_TimersAndConstants__t301_ms200 : + tac->T301_k = 200; + break; + case NR_UE_TimersAndConstants__t301_ms300 : + tac->T301_k = 300; + break; + case NR_UE_TimersAndConstants__t301_ms400 : + tac->T301_k = 400; + break; + case NR_UE_TimersAndConstants__t301_ms600 : + tac->T301_k = 600; + break; + case NR_UE_TimersAndConstants__t301_ms1000 : + tac->T301_k = 1000; + break; + case NR_UE_TimersAndConstants__t301_ms1500 : + tac->T301_k = 1500; + break; + case NR_UE_TimersAndConstants__t301_ms2000 : + tac->T301_k = 2000; + break; + default : + AssertFatal(false, "Invalid T301 %ld\n", sib1->ue_TimersAndConstants->t301); + } + switch (sib1->ue_TimersAndConstants->t310) { + case NR_UE_TimersAndConstants__t310_ms0 : + tac->T310_k = 0; + break; + case NR_UE_TimersAndConstants__t310_ms50 : + tac->T310_k = 50; + break; + case NR_UE_TimersAndConstants__t310_ms100 : + tac->T310_k = 100; + break; + case NR_UE_TimersAndConstants__t310_ms200 : + tac->T310_k = 200; + break; + case NR_UE_TimersAndConstants__t310_ms500 : + tac->T310_k = 500; + break; + case NR_UE_TimersAndConstants__t310_ms1000 : + tac->T310_k = 1000; + break; + case NR_UE_TimersAndConstants__t310_ms2000 : + tac->T310_k = 2000; + break; + default : + AssertFatal(false, "Invalid T310 %ld\n", sib1->ue_TimersAndConstants->t310); + } + switch (sib1->ue_TimersAndConstants->t311) { + case NR_UE_TimersAndConstants__t311_ms1000 : + tac->T311_k = 1000; + break; + case NR_UE_TimersAndConstants__t311_ms3000 : + tac->T311_k = 3000; + break; + case NR_UE_TimersAndConstants__t311_ms5000 : + tac->T311_k = 5000; + break; + case NR_UE_TimersAndConstants__t311_ms10000 : + tac->T311_k = 10000; + break; + case NR_UE_TimersAndConstants__t311_ms15000 : + tac->T311_k = 15000; + break; + case NR_UE_TimersAndConstants__t311_ms20000 : + tac->T311_k = 20000; + break; + case NR_UE_TimersAndConstants__t311_ms30000 : + tac->T311_k = 30000; + break; + default : + AssertFatal(false, "Invalid T311 %ld\n", sib1->ue_TimersAndConstants->t311); + } + switch (sib1->ue_TimersAndConstants->n310) { + case NR_UE_TimersAndConstants__n310_n1 : + tac->N310_k = 1; + break; + case NR_UE_TimersAndConstants__n310_n2 : + tac->N310_k = 2; + break; + case NR_UE_TimersAndConstants__n310_n3 : + tac->N310_k = 3; + break; + case NR_UE_TimersAndConstants__n310_n4 : + tac->N310_k = 4; + break; + case NR_UE_TimersAndConstants__n310_n6 : + tac->N310_k = 6; + break; + case NR_UE_TimersAndConstants__n310_n8 : + tac->N310_k = 8; + break; + case NR_UE_TimersAndConstants__n310_n10 : + tac->N310_k = 10; + break; + case NR_UE_TimersAndConstants__n310_n20 : + tac->N310_k = 20; + break; + default : + AssertFatal(false, "Invalid N310 %ld\n", sib1->ue_TimersAndConstants->n310); + } + switch (sib1->ue_TimersAndConstants->n311) { + case NR_UE_TimersAndConstants__n311_n1 : + tac->N311_k = 1; + break; + case NR_UE_TimersAndConstants__n311_n2 : + tac->N311_k = 2; + break; + case NR_UE_TimersAndConstants__n311_n3 : + tac->N311_k = 3; + break; + case NR_UE_TimersAndConstants__n311_n4 : + tac->N311_k = 4; + break; + case NR_UE_TimersAndConstants__n311_n5 : + tac->N311_k = 5; + break; + case NR_UE_TimersAndConstants__n311_n6 : + tac->N311_k = 6; + break; + case NR_UE_TimersAndConstants__n311_n8 : + tac->N311_k = 8; + break; + case NR_UE_TimersAndConstants__n311_n10 : + tac->N311_k = 10; + break; + default : + AssertFatal(false, "Invalid N311 %ld\n", sib1->ue_TimersAndConstants->n311); + } + } + else + LOG_E(NR_RRC,"SIB1 should not be NULL and neither UE_Timers_Constants\n"); +} + +void nr_rrc_set_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1) +{ + set_rlf_sib1_timers_and_constants(tac, sib1); + if(sib1 && sib1->ue_TimersAndConstants) { + switch (sib1->ue_TimersAndConstants->t300) { + case NR_UE_TimersAndConstants__t300_ms100 : + tac->T300_k = 100; + break; + case NR_UE_TimersAndConstants__t300_ms200 : + tac->T300_k = 200; + break; + case NR_UE_TimersAndConstants__t300_ms300 : + tac->T300_k = 300; + break; + case NR_UE_TimersAndConstants__t300_ms400 : + tac->T300_k = 400; + break; + case NR_UE_TimersAndConstants__t300_ms600 : + tac->T300_k = 600; + break; + case NR_UE_TimersAndConstants__t300_ms1000 : + tac->T300_k = 1000; + break; + case NR_UE_TimersAndConstants__t300_ms1500 : + tac->T300_k = 1500; + break; + case NR_UE_TimersAndConstants__t300_ms2000 : + tac->T300_k = 2000; + break; + default : + AssertFatal(false, "Invalid T300 %ld\n", sib1->ue_TimersAndConstants->t300); + } + switch (sib1->ue_TimersAndConstants->t319) { + case NR_UE_TimersAndConstants__t319_ms100 : + tac->T319_k = 100; + break; + case NR_UE_TimersAndConstants__t319_ms200 : + tac->T319_k = 200; + break; + case NR_UE_TimersAndConstants__t319_ms300 : + tac->T319_k = 300; + break; + case NR_UE_TimersAndConstants__t319_ms400 : + tac->T319_k = 400; + break; + case NR_UE_TimersAndConstants__t319_ms600 : + tac->T319_k = 600; + break; + case NR_UE_TimersAndConstants__t319_ms1000 : + tac->T319_k = 1000; + break; + case NR_UE_TimersAndConstants__t319_ms1500 : + tac->T319_k = 1500; + break; + case NR_UE_TimersAndConstants__t319_ms2000 : + tac->T319_k = 2000; + break; + default : + AssertFatal(false, "Invalid T319 %ld\n", sib1->ue_TimersAndConstants->t319); + } + } + else + LOG_E(NR_RRC,"SIB1 should not be NULL and neither UE_Timers_Constants\n"); +} + +void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc, + struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants) +{ + if(rlf_TimersAndConstants == NULL) + return; + + NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; + NR_RLF_TimersAndConstants_t *rlf_tac = NULL; + 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); + break; + case NR_SetupRelease_RLF_TimersAndConstants_PR_setup : + rlf_tac = rlf_TimersAndConstants->choice.setup; + if (rlf_tac == NULL) + return; + // (re-)configure the value of timers and constants in accordance with received rlf-TimersAndConstants + switch (rlf_tac->t310) { + case NR_RLF_TimersAndConstants__t310_ms0 : + tac->T310_k = 0; + break; + case NR_RLF_TimersAndConstants__t310_ms50 : + tac->T310_k = 50; + break; + case NR_RLF_TimersAndConstants__t310_ms100 : + tac->T310_k = 100; + break; + case NR_RLF_TimersAndConstants__t310_ms200 : + tac->T310_k = 200; + break; + case NR_RLF_TimersAndConstants__t310_ms500 : + tac->T310_k = 500; + break; + case NR_RLF_TimersAndConstants__t310_ms1000 : + tac->T310_k = 1000; + break; + case NR_RLF_TimersAndConstants__t310_ms2000 : + tac->T310_k = 2000; + break; + case NR_RLF_TimersAndConstants__t310_ms4000 : + tac->T310_k = 4000; + break; + case NR_RLF_TimersAndConstants__t310_ms6000 : + tac->T310_k = 6000; + break; + default : + AssertFatal(false, "Invalid T310 %ld\n", rlf_tac->t310); + } + switch (rlf_tac->n310) { + case NR_RLF_TimersAndConstants__n310_n1 : + tac->N310_k = 1; + break; + case NR_RLF_TimersAndConstants__n310_n2 : + tac->N310_k = 2; + break; + case NR_RLF_TimersAndConstants__n310_n3 : + tac->N310_k = 3; + break; + case NR_RLF_TimersAndConstants__n310_n4 : + tac->N310_k = 4; + break; + case NR_RLF_TimersAndConstants__n310_n6 : + tac->N310_k = 6; + break; + case NR_RLF_TimersAndConstants__n310_n8 : + tac->N310_k = 8; + break; + case NR_RLF_TimersAndConstants__n310_n10 : + tac->N310_k = 10; + break; + case NR_RLF_TimersAndConstants__n310_n20 : + tac->N310_k = 20; + break; + default : + AssertFatal(false, "Invalid N310 %ld\n", rlf_tac->n310); + } + switch (rlf_tac->n311) { + case NR_RLF_TimersAndConstants__n311_n1 : + tac->N311_k = 1; + break; + case NR_RLF_TimersAndConstants__n311_n2 : + tac->N311_k = 2; + break; + case NR_RLF_TimersAndConstants__n311_n3 : + tac->N311_k = 3; + break; + case NR_RLF_TimersAndConstants__n311_n4 : + tac->N311_k = 4; + break; + case NR_RLF_TimersAndConstants__n311_n5 : + tac->N311_k = 5; + break; + case NR_RLF_TimersAndConstants__n311_n6 : + tac->N311_k = 6; + break; + case NR_RLF_TimersAndConstants__n311_n8 : + tac->N311_k = 8; + break; + case NR_RLF_TimersAndConstants__n311_n10 : + tac->N311_k = 10; + break; + default : + AssertFatal(false, "Invalid N311 %ld\n", rlf_tac->n311); + } + if (rlf_tac->ext1) { + switch (rlf_tac->ext1->t311) { + case NR_RLF_TimersAndConstants__ext1__t311_ms1000 : + tac->T311_k = 1000; + break; + case NR_RLF_TimersAndConstants__ext1__t311_ms3000 : + tac->T311_k = 3000; + break; + case NR_RLF_TimersAndConstants__ext1__t311_ms5000 : + tac->T311_k = 5000; + break; + case NR_RLF_TimersAndConstants__ext1__t311_ms10000 : + tac->T311_k = 10000; + break; + case NR_RLF_TimersAndConstants__ext1__t311_ms15000 : + tac->T311_k = 15000; + break; + case NR_RLF_TimersAndConstants__ext1__t311_ms20000 : + tac->T311_k = 20000; + break; + case NR_RLF_TimersAndConstants__ext1__t311_ms30000 : + tac->T311_k = 30000; + break; + default : + AssertFatal(false, "Invalid T311 %ld\n", rlf_tac->ext1->t311); + } + } + reset_rlf_timers_and_constants(tac); + break; + default : + AssertFatal(false, "Invalid rlf_TimersAndConstants\n"); + } +} + +void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac) +{ + // 38.331 9.2.3 Default values timers and constants + tac->T310_k = 1000; + tac->N310_k = 1; + tac->T311_k = 30000; + tac->N311_k = 1; +} + +void reset_rlf_timers_and_constants(NR_UE_Timers_Constants_t *tac) +{ + // stop timer T310 for this cell group, if running + tac->T310_active = false; + tac->T310_cnt = 0; + // reset the counters N310 and N311 + tac->N310_cnt = 0; + tac->N311_cnt = 0; +}