diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index d6f504af1b..a85f0d9b0c 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -102,10 +102,10 @@ Command line parameters for UE in `--sa` mode: - `--band` : NR band number (default value 78) - `--ssb` : SSB start subcarrier (default value 516) -To simplify the configuration for the user testing OAI UE with OAI gNB, the latter prints the following LOG that guides the user to correctly set the UE command line parameters. +To simplify the configuration for the user testing OAI UE with OAI gNB, the latter prints the following LOG that guides the user to correctly set some of the UE command line parameters. ``` -[PHY] Command line parameters for the UE: -C 3319680000 -r 106 --numerology 1 --band 78 --ssb 516 +[PHY] Command line parameters for the UE: -C 3319680000 -r 106 --numerology 1 --ssb 516 ``` You can run this, using USRPs, on two separate machines: diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 6936fc81b1..291e063aa4 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -81,20 +81,18 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB,int frame,int slot, nfapi_nr_ fp->print_ue_help_cmdline_log = false; if (fp->dl_CarrierFreq != fp->ul_CarrierFreq) LOG_A(PHY, - "Command line parameters for the UE: -C %lu --CO %lu -r %d --numerology %d --band %d --ssb %d\n", + "Command line parameters for the UE: -C %lu --CO %lu -r %d --numerology %d --ssb %d\n", fp->dl_CarrierFreq, fp->dl_CarrierFreq - fp->ul_CarrierFreq, fp->N_RB_DL, scs, - fp->nr_band, fp->ssb_start_subcarrier); else LOG_A(PHY, - "Command line parameters for the UE: -C %lu -r %d --numerology %d --band %d --ssb %d\n", + "Command line parameters for the UE: -C %lu -r %d --numerology %d --ssb %d\n", fp->dl_CarrierFreq, fp->N_RB_DL, scs, - fp->nr_band, fp->ssb_start_subcarrier); } LOG_D(PHY, diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 61b0345ab0..0511573be9 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1426,7 +1426,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); switch (cause) { case GO_TO_IDLE: - reset_ra(&mac->ra); + reset_ra(mac, cause); release_mac_configuration(mac, cause); nr_ue_init_mac(mac); nr_ue_mac_default_configs(mac); @@ -1434,14 +1434,16 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, nr_ue_send_synch_request(mac, module_id, 0, -1); break; case DETACH: - reset_ra(&mac->ra); + LOG_A(NR_MAC, "Received detach indication\n"); + reset_ra(mac, cause); reset_mac_inst(mac); nr_ue_reset_sync_state(mac); release_mac_configuration(mac, cause); + mac->state = UE_DETACHING; break; case T300_EXPIRY: + reset_ra(mac, cause); reset_mac_inst(mac); - reset_ra(&mac->ra); mac->state = UE_SYNC; // still in sync but need to restart RA break; case RE_ESTABLISHMENT: diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 55eaf320d4..67e4a0f078 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -169,7 +169,8 @@ typedef enum { UE_NOT_SYNC = 0, UE_SYNC, UE_PERFORMING_RA, - UE_CONNECTED + UE_CONNECTED, + UE_DETACHING } NR_UE_L2_STATE_t; typedef enum { diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 8516ef775b..003d4fc12d 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -100,7 +100,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(int nb_inst); NR_UE_MAC_INST_t *get_mac_inst(module_id_t module_id); void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac); -void reset_ra(RA_config_t *ra); +void reset_ra(NR_UE_MAC_INST_t *nr_mac, NR_UE_MAC_reset_cause_t cause); void release_mac_configuration(NR_UE_MAC_INST_t *mac, NR_UE_MAC_reset_cause_t cause); @@ -304,7 +304,7 @@ void init_RA(NR_UE_MAC_INST_t *mac, NR_RACH_ConfigDedicated_t *rach_ConfigDedicated); int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac); - +void free_rach_structures(NR_UE_MAC_INST_t *nr_mac, int bwp_id); void nr_Msg1_transmitted(NR_UE_MAC_INST_t *mac); void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id); void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max); diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index a5c5abfb13..666506b2fc 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -211,14 +211,6 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac) // release, if any, Temporary C-RNTI nr_mac->ra.t_crnti = 0; - // free RACH structs - for (int i = 0; i < MAX_NUM_BWP_UE; i++) { - free(nr_mac->ssb_list[i].tx_ssb); - for (int j = 0; j < MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD; j++) - for (int k = 0; k < MAX_NB_FRAME_IN_PRACH_CONF_PERIOD; k++) - for (int l = 0; l < MAX_NB_SLOT_IN_FRAME; l++) - free(nr_mac->prach_assoc_pattern[i].prach_conf_period_list[j].prach_occasion_slot_map[k][l].prach_occasion); - } // reset BFI_COUNTER // TODO beam failure procedure not implemented @@ -291,9 +283,26 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment)); } -void reset_ra(RA_config_t *ra) +void free_rach_structures(NR_UE_MAC_INST_t *nr_mac, int bwp_id) { + for (int j = 0; j < MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD; j++) + for (int k = 0; k < MAX_NB_FRAME_IN_PRACH_CONF_PERIOD; k++) + for (int l = 0; l < MAX_NB_SLOT_IN_FRAME; l++) + free(nr_mac->prach_assoc_pattern[bwp_id].prach_conf_period_list[j].prach_occasion_slot_map[k][l].prach_occasion); + + free(nr_mac->ssb_list[bwp_id].tx_ssb); +} + +void reset_ra(NR_UE_MAC_INST_t *nr_mac, NR_UE_MAC_reset_cause_t cause) +{ + RA_config_t *ra = &nr_mac->ra; if(ra->rach_ConfigDedicated) asn1cFreeStruc(asn_DEF_NR_RACH_ConfigDedicated, ra->rach_ConfigDedicated); memset(ra, 0, sizeof(RA_config_t)); + + if (cause == T300_EXPIRY) + return; + + for (int i = 0; i < MAX_NUM_BWP_UE; i++) + free_rach_structures(nr_mac, i); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 480276ef44..5f0bc51e9a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2263,7 +2263,10 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche bool two_transport_blocks = false; int number_of_code_word = 1; - if (current_DL_BWP && current_DL_BWP->pdsch_Config && current_DL_BWP->pdsch_Config->maxNrofCodeWordsScheduledByDCI && current_DL_BWP->pdsch_Config->maxNrofCodeWordsScheduledByDCI[0] == 2) { + if (current_DL_BWP + && current_DL_BWP->pdsch_Config + && current_DL_BWP->pdsch_Config->maxNrofCodeWordsScheduledByDCI + && current_DL_BWP->pdsch_Config->maxNrofCodeWordsScheduledByDCI[0] == 2) { two_transport_blocks = true; number_of_code_word = 2; } @@ -2400,9 +2403,8 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche return false; } - NR_PUCCH_Config_t *pucch_Config = current_UL_BWP->pucch_Config; - if (!pucch_Config || !pucch_Config->resourceSetToAddModList - || pucch_Config->resourceSetToAddModList->list.array[0] == NULL) + NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL; + if (!(pucch_Config && pucch_Config->resourceSetToAddModList && pucch_Config->resourceSetToAddModList->list.array[0])) configure_initial_pucch(pucch, res_ind); else { int resource_set_id = find_pucch_resource_set(pucch_Config, O_ACK); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 49bb3d15f8..8c9062d8ec 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -626,11 +626,11 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, /* Transform precoding */ pusch_config_pdu->transform_precoding = get_transformPrecoding(current_UL_BWP, dci_format, 0); + bool tp_enabled = pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled; /*DCI format-related configuration*/ if (dci_format == NR_UL_DCI_FORMAT_0_0) { - if ((pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) && - pusch_config_pdu->nr_of_symbols < 3) + if (!tp_enabled && pusch_config_pdu->nr_of_symbols < 3) pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; else pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; @@ -653,7 +653,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->scid = 0; pusch_config_pdu->data_scrambling_id = mac->physCellId; - if (pusch_Config->dataScramblingIdentityPUSCH + if (pusch_Config + && pusch_Config->dataScramblingIdentityPUSCH && rnti_type == TYPE_C_RNTI_ && !(dci_format == NR_UL_DCI_FORMAT_0_0 && ss_type == NR_SearchSpace__searchSpaceType_PR_common)) pusch_config_pdu->data_scrambling_id = *pusch_Config->dataScramblingIdentityPUSCH; @@ -663,7 +664,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->scid = dci->dmrs_sequence_initialization.val; /* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/ - if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) { + if (tp_enabled) { uint32_t n_RS_Id = 0; if (NR_DMRS_ulconfig->transformPrecodingEnabled && @@ -712,8 +713,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, } /* FREQ_HOPPING_FLAG */ - if ((pusch_Config != NULL) - && (pusch_Config->frequencyHopping != NULL) + if (pusch_Config + && pusch_Config->frequencyHopping && (pusch_Config->resourceAllocation != NR_PUSCH_Config__resourceAllocation_resourceAllocationType0)) { pusch_config_pdu->frequency_hopping = dci->frequency_hopping_flag.val; } @@ -722,8 +723,9 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->mcs_index = dci->mcs; /* MCS TABLE */ - pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config ? pusch_Config->mcs_TableTransformPrecoder : NULL, - pusch_config_pdu->transform_precoding != NR_PUSCH_Config__transformPrecoder_disabled, + long *mcs_table_config = pusch_Config ? (tp_enabled ? pusch_Config->mcs_TableTransformPrecoder : pusch_Config->mcs_Table) : NULL; + pusch_config_pdu->mcs_table = get_pusch_mcs_table(mcs_table_config, + tp_enabled, dci_format, rnti_type, ss_type, @@ -794,7 +796,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, /* PTRS */ if (pusch_Config && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) { - if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { + if (!tp_enabled) { nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; bool valid_ptrs_setup = set_ul_ptrs_values(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup, @@ -1086,7 +1088,7 @@ void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info dl_config->slot = rx_slot; dl_config->number_pdus = 0; - if (mac->state == UE_NOT_SYNC) + if (mac->state == UE_NOT_SYNC || mac->state == UE_DETACHING) return; ue_dci_configuration(mac, dl_config, rx_frame, rx_slot); @@ -1241,7 +1243,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) uint32_t gNB_index = ul_info->gNB_index; RA_config_t *ra = &mac->ra; - if(mac->state < UE_CONNECTED) { + if(mac->state > UE_NOT_SYNC && mac->state < UE_CONNECTED) { nr_ue_get_rach(mac, cc_id, frame_tx, gNB_index, slot_tx); nr_ue_prach_scheduler(mac, frame_tx, slot_tx); } @@ -1325,35 +1327,32 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) nr_update_sr(mac); // update Bj for all active lcids before LCP procedure - LOG_D(NR_MAC, "====================[Frame %d][Slot %d]Logical Channel Prioritization===========\n", frame_tx, slot_tx); - for (int i = 0; i < mac->lc_ordered_list.count; i++) { - nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; - int lcid = lc_info->lcid; - // max amount of data that can be buffered/accumulated in a logical channel buffer - uint32_t bucketSize_max = lc_info->bucket_size; - - /* - measure Bj - increment the value of Bj by product PBR * T - */ - NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid); - int32_t bj = sched_info->Bj; - if (lc_info->pbr < UINT_MAX) { - uint32_t slots_elapsed = nr_timer_elapsed_time(sched_info->Bj_timer); // slots elapsed since Bj was last incremented - // it is safe to divide by 1k since pbr in lc_info is computed multiplying by 1000 the RRC value to convert kB/s to B/s - uint32_t pbr_ms = lc_info->pbr / 1000; - bj += ((pbr_ms * slots_elapsed) >> mac->current_UL_BWP->scs); // each slot length is 1/scs ms + if (mac->current_UL_BWP) { + LOG_D(NR_MAC, "%4d.%2d Logical Channel Prioritization\n", frame_tx, slot_tx); + for (int i = 0; i < mac->lc_ordered_list.count; i++) { + nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; + int lcid = lc_info->lcid; + // max amount of data that can be buffered/accumulated in a logical channel buffer + uint32_t bucketSize_max = lc_info->bucket_size; + // measure Bj increment the value of Bj by product PBR * T + NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid); + int32_t bj = sched_info->Bj; + if (lc_info->pbr < UINT_MAX) { + uint32_t slots_elapsed = nr_timer_elapsed_time(sched_info->Bj_timer); // slots elapsed since Bj was last incremented + // it is safe to divide by 1k since pbr in lc_info is computed multiplying by 1000 the RRC value to convert kB/s to B/s + uint32_t pbr_ms = lc_info->pbr / 1000; + bj += ((pbr_ms * slots_elapsed) >> mac->current_UL_BWP->scs); // each slot length is 1/scs ms + } + else + bj = INT_MAX; + // bj > max bucket size, set bj to max bucket size, as in ts38.321 5.4.3.1 Logical Channel Prioritization + sched_info->Bj = min(bj, bucketSize_max); + // reset bj timer + nr_timer_start(&sched_info->Bj_timer); } - else - bj = INT_MAX; - - // bj > max bucket size, set bj to max bucket size, as in ts38.321 5.4.3.1 Logical Channel Prioritization - sched_info->Bj = min(bj, bucketSize_max); - // reset bj timer - nr_timer_start(&sched_info->Bj_timer); } - if(mac->state >= UE_PERFORMING_RA) + if(mac->state >= UE_PERFORMING_RA && mac->state < UE_DETACHING) nr_ue_pucch_scheduler(mac, frame_tx, slot_tx, ul_info->phy_data); } @@ -1952,6 +1951,7 @@ void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) { // Clear all the lists and maps const int bwp_id = mac->current_UL_BWP->bwp_id; + free_rach_structures(mac, bwp_id); memset(&mac->ssb_list[bwp_id], 0, sizeof(ssb_list_info_t)); memset(&mac->prach_assoc_pattern[bwp_id], 0, sizeof(prach_association_pattern_t)); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 6db1582072..6442594eef 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -311,6 +311,7 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst) rrc->dl_bwp_id = 0; rrc->ul_bwp_id = 0; rrc->as_security_activated = false; + rrc->detach_after_release = false; FILE *f = NULL; if (uecap_file) @@ -1628,6 +1629,8 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, LOG_I(NR_RRC, "[UE %ld] Received RRC Release (gNB %d)\n", rrc->ue_id, gNB_indexP); // TODO properly implement procedures in 5.3.8.3 of 38.331 NR_Release_Cause_t cause = OTHER; + if (rrc->detach_after_release) + rrc->nrRrcState = RRC_STATE_DETACH_NR; nr_rrc_going_to_IDLE(rrc, cause, dl_dcch_msg->message.choice.c1->choice.rrcRelease); break; @@ -1786,7 +1789,9 @@ void *rrc_nrue(void *notUsed) break; case NAS_DETACH_REQ: - if (!NAS_DETACH_REQ(msg_p).wait_release) { + if (NAS_DETACH_REQ(msg_p).wait_release) + rrc->detach_after_release = true; + else { rrc->nrRrcState = RRC_STATE_DETACH_NR; NR_Release_Cause_t release_cause = OTHER; nr_rrc_going_to_IDLE(rrc, release_cause, NULL); diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 621eec6443..533b3870f5 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -216,6 +216,7 @@ typedef struct NR_UE_RRC_INST_s { e_NR_IntegrityProtAlgorithm integrityProtAlgorithm; long keyToUse; bool as_security_activated; + bool detach_after_release; long selected_plmn_identity; Rrc_State_NR_t nrRrcState;