From c54a1ff8576b9415e85c652fce5143cbf377a47c Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 1 Feb 2024 16:46:42 +0100 Subject: [PATCH 01/35] remove unused phy_config_ind queue --- executables/nr-ue.c | 1 - openair1/PHY/defs_nr_UE.h | 2 +- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 1ceb49e0d7..a4f688c765 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -789,7 +789,6 @@ void *UE_thread(void *arg) bool syncRunning=false; const int nb_slot_frame = UE->frame_parms.slots_per_frame; int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0; - initNotifiedFIFO(&UE->phy_config_ind); int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME]; int num_ind_fifo = nb_slot_frame; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 834163d8ed..9988d05196 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -610,7 +610,7 @@ typedef struct PHY_VARS_NR_UE_s { void *phy_sim_pdsch_dl_ch_estimates; void *phy_sim_pdsch_dl_ch_estimates_ext; uint8_t *phy_sim_dlsch_b; - notifiedFIFO_t phy_config_ind; + notifiedFIFO_t tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME]; } PHY_VARS_NR_UE; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index fbe04ffb84..81a057fd14 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -538,7 +538,6 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config) fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config; if(phy_config != NULL) { memcpy(nrUE_config, &phy_config->config_req, sizeof(fapi_nr_config_request_t)); - pushNotifiedFIFO(&PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->phy_config_ind, newNotifiedFIFO_elt(1,0,NULL,NULL)); } return 0; } From ab07b080ddc0181b06541229eea3d2d5a4376dc6 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 7 Feb 2024 17:03:04 +0100 Subject: [PATCH 02/35] move ASN macros to a more global file to be available also at RRC --- common/utils/oai_asn1.h | 105 ++++++++++++ openair2/LAYER2/NR_MAC_UE/config_ue.c | 236 +++++++++++++------------- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 105 ------------ 3 files changed, 223 insertions(+), 223 deletions(-) diff --git a/common/utils/oai_asn1.h b/common/utils/oai_asn1.h index f55150d17f..91d354ddbd 100644 --- a/common/utils/oai_asn1.h +++ b/common/utils/oai_asn1.h @@ -27,6 +27,111 @@ //-----------------------begin func ------------------- +// Macro updates DESTINATION with configuration from ORIGIN by swapping pointers +// Old configuration is freed after completing configuration +#define UPDATE_IE(DESTINATION, ORIGIN, TYPE) \ + do { \ + TYPE *tmp = ORIGIN; \ + ORIGIN = DESTINATION; \ + DESTINATION = tmp; \ + } while(0); \ + +// Same as above but swapping ASN1 elements that are not pointers +#define UPDATE_NP_IE(DESTINATION, ORIGIN, TYPE) \ + do { \ + TYPE tmp = ORIGIN; \ + ORIGIN = DESTINATION; \ + DESTINATION = tmp; \ + } while(0); \ + +// Macro handles reception of SetupRelease element ORIGIN (see NR_SetupRelease.h) +// If release (NR_SetupRelease_xxx_PR_release equivalent to 1), removing structure from DESTINATION +// If setup (NR_SetupRelease_xxx_PR_setup equivalent to 2), add or modify structure in DESTINATION +// Destination is not a SetupRelease structure +#define HANDLE_SETUPRELEASE_DIRECT(DESTINATION, ORIGIN, TYPE, ASN_DEF) \ + do { \ + if (ORIGIN->present == 1) { \ + asn1cFreeStruc(ASN_DEF, DESTINATION); \ + } \ + if (ORIGIN->present == 2) \ + UPDATE_IE(DESTINATION, ORIGIN->choice.setup, TYPE); \ + } while(0); \ + +// Macro handles reception of SetupRelease element ORIGIN (see NR_SetupRelease.h) +// If release (NR_SetupRelease_xxx_PR_release equivalent to 1), removing structure from DESTINATION +// If setup (NR_SetupRelease_xxx_PR_setup equivalent to 2), add or modify structure in DESTINATION +// Destination is a SetupRelease structure +#define HANDLE_SETUPRELEASE_IE(DESTINATION, ORIGIN, TYPE, ASN_DEF) \ + do { \ + if (ORIGIN->present == 1) { \ + asn1cFreeStruc(ASN_DEF, DESTINATION); \ + } \ + if (ORIGIN->present == 2) { \ + if (!DESTINATION) \ + DESTINATION = calloc(1, sizeof(*DESTINATION)); \ + DESTINATION->present = ORIGIN->present; \ + UPDATE_IE(DESTINATION->choice.setup, ORIGIN->choice.setup, TYPE); \ + } \ + } while(0); \ + +// Macro releases entries in list TARGET if the corresponding ID is found in list SOURCE. +// Prints an error if ID not found in list. +#define RELEASE_IE_FROMLIST(SOURCE, TARGET, FIELD) \ + do { \ + for (int iI = 0; iI < SOURCE->list.count; iI++) { \ + long eL = *SOURCE->list.array[iI]; \ + int iJ; \ + for (iJ = 0; iJ < TARGET->list.count; iJ++) { \ + if (eL == TARGET->list.array[iJ]->FIELD) \ + break; \ + } \ + if (iJ == TARGET->list.count) \ + asn_sequence_del(&TARGET->list, iJ, 1); \ + else \ + LOG_E(NR_MAC, "Element not present in the list, impossible to release\n"); \ + } \ + } while (0) \ + +// Macro adds or modifies entries of type TYPE in list TARGET with elements received in list SOURCE +#define ADDMOD_IE_FROMLIST(SOURCE, TARGET, FIELD, TYPE) \ + do { \ + for (int iI = 0; iI < SOURCE->list.count; iI++) { \ + long eL = SOURCE->list.array[iI]->FIELD; \ + int iJ; \ + for (iJ = 0; iJ < TARGET->list.count; iJ++) { \ + if (eL == TARGET->list.array[iJ]->FIELD) \ + break; \ + } \ + if (iJ == TARGET->list.count) { \ + TYPE *nEW = calloc(1, sizeof(*nEW)); \ + ASN_SEQUENCE_ADD(&TARGET->list, nEW); \ + } \ + UPDATE_IE(TARGET->list.array[iJ], \ + SOURCE->list.array[iI], \ + TYPE); \ + } \ + } while (0) \ + +// Macro adds or modifies entries of type TYPE in list TARGET with elements received in list SOURCE +// Action performed by function FUNC +#define ADDMOD_IE_FROMLIST_WFUNCTION(SOURCE, TARGET, FIELD, TYPE, FUNC) \ + do { \ + for (int iI = 0; iI < SOURCE->list.count; iI++) { \ + long eL = SOURCE->list.array[iI]->FIELD; \ + int iJ; \ + for (iJ = 0; iJ < TARGET->list.count; iJ++) { \ + if (eL == TARGET->list.array[iJ]->FIELD) \ + break; \ + } \ + if (iJ == TARGET->list.count) { \ + TYPE *nEW = calloc(1, sizeof(*nEW)); \ + ASN_SEQUENCE_ADD(&TARGET->list, nEW); \ + } \ + FUNC(TARGET->list.array[iJ], \ + SOURCE->list.array[iI]); \ + } \ + } while (0) + /*! \fn uint8_t BIT_STRING_to_uint8(BIT_STRING_t *) *\brief This function extract at most a 8 bits value from a BIT_STRING_t object, the exact bits number depend on the BIT_STRING_t contents. *\param[in] pointer to the BIT_STRING_t object. diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 876d308889..733c9a9960 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -427,18 +427,18 @@ static void modlist_ss(NR_SearchSpace_t *source, NR_SearchSpace_t *target) { target->searchSpaceId = source->searchSpaceId; if (source->controlResourceSetId) - UPDATE_MAC_IE(target->controlResourceSetId, source->controlResourceSetId, NR_ControlResourceSetId_t); + UPDATE_IE(target->controlResourceSetId, source->controlResourceSetId, NR_ControlResourceSetId_t); if (source->monitoringSlotPeriodicityAndOffset) - UPDATE_MAC_IE(target->monitoringSlotPeriodicityAndOffset, - source->monitoringSlotPeriodicityAndOffset, - struct NR_SearchSpace__monitoringSlotPeriodicityAndOffset); - UPDATE_MAC_IE(target->duration, source->duration, long); + UPDATE_IE(target->monitoringSlotPeriodicityAndOffset, + source->monitoringSlotPeriodicityAndOffset, + struct NR_SearchSpace__monitoringSlotPeriodicityAndOffset); + UPDATE_IE(target->duration, source->duration, long); if (source->monitoringSymbolsWithinSlot) - UPDATE_MAC_IE(target->monitoringSymbolsWithinSlot, source->monitoringSymbolsWithinSlot, BIT_STRING_t); + UPDATE_IE(target->monitoringSymbolsWithinSlot, source->monitoringSymbolsWithinSlot, BIT_STRING_t); if (source->nrofCandidates) - UPDATE_MAC_IE(target->nrofCandidates, source->nrofCandidates, struct NR_SearchSpace__nrofCandidates); + UPDATE_IE(target->nrofCandidates, source->nrofCandidates, struct NR_SearchSpace__nrofCandidates); if (source->searchSpaceType) - UPDATE_MAC_IE(target->searchSpaceType, source->searchSpaceType, struct NR_SearchSpace__searchSpaceType); + UPDATE_IE(target->searchSpaceType, source->searchSpaceType, struct NR_SearchSpace__searchSpaceType); } static NR_SearchSpace_t *get_common_search_space(const NR_UE_MAC_INST_t *mac, @@ -493,7 +493,7 @@ static void configure_common_ss_coreset(const NR_UE_MAC_INST_t *mac, get_common_search_space(mac, pdcch_ConfigCommon->commonSearchSpaceList, pdcch, *pdcch_ConfigCommon->pagingSearchSpace); } - UPDATE_MAC_IE(pdcch->commonControlResourceSet, pdcch_ConfigCommon->commonControlResourceSet, NR_ControlResourceSet_t); + UPDATE_IE(pdcch->commonControlResourceSet, pdcch_ConfigCommon->commonControlResourceSet, NR_ControlResourceSet_t); } } @@ -516,15 +516,15 @@ static void modlist_coreset(NR_ControlResourceSet_t *source, NR_ControlResourceS target->cce_REG_MappingType.choice.interleaved->reg_BundleSize = source->cce_REG_MappingType.choice.interleaved->reg_BundleSize; target->cce_REG_MappingType.choice.interleaved->interleaverSize = source->cce_REG_MappingType.choice.interleaved->interleaverSize; - UPDATE_MAC_IE(target->cce_REG_MappingType.choice.interleaved->shiftIndex, - source->cce_REG_MappingType.choice.interleaved->shiftIndex, - long); + UPDATE_IE(target->cce_REG_MappingType.choice.interleaved->shiftIndex, + source->cce_REG_MappingType.choice.interleaved->shiftIndex, + long); } else { free(shiftIndex); target->cce_REG_MappingType = source->cce_REG_MappingType; } - UPDATE_MAC_IE(target->tci_PresentInDCI, source->tci_PresentInDCI, long); - UPDATE_MAC_IE(target->pdcch_DMRS_ScramblingID, source->pdcch_DMRS_ScramblingID, long); + UPDATE_IE(target->tci_PresentInDCI, source->tci_PresentInDCI, long); + UPDATE_IE(target->pdcch_DMRS_ScramblingID, source->pdcch_DMRS_ScramblingID, long); // TCI States if (source->tci_StatesPDCCH_ToReleaseList) { for (int i = 0; i < source->tci_StatesPDCCH_ToReleaseList->list.count; i++) { @@ -553,9 +553,9 @@ static void modlist_coreset(NR_ControlResourceSet_t *source, NR_ControlResourceS ASN_SEQUENCE_ADD(&target->tci_StatesPDCCH_ToAddList->list, source->tci_StatesPDCCH_ToAddList->list.array[i]); } } else - UPDATE_MAC_IE(target->tci_StatesPDCCH_ToAddList, - source->tci_StatesPDCCH_ToAddList, - struct NR_ControlResourceSet__tci_StatesPDCCH_ToAddList); + UPDATE_IE(target->tci_StatesPDCCH_ToAddList, + source->tci_StatesPDCCH_ToAddList, + struct NR_ControlResourceSet__tci_StatesPDCCH_ToAddList); } // end TCI States } @@ -812,14 +812,14 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_PowerControl_t *target) { - UPDATE_MAC_IE(target->tpc_Accumulation, source->tpc_Accumulation, long); - UPDATE_MAC_IE(target->msg3_Alpha, source->msg3_Alpha, NR_Alpha_t); + UPDATE_IE(target->tpc_Accumulation, source->tpc_Accumulation, long); + UPDATE_IE(target->msg3_Alpha, source->msg3_Alpha, NR_Alpha_t); if (source->p0_NominalWithoutGrant) - UPDATE_MAC_IE(target->p0_NominalWithoutGrant, source->p0_NominalWithoutGrant, long); + UPDATE_IE(target->p0_NominalWithoutGrant, source->p0_NominalWithoutGrant, long); if (source->p0_AlphaSets) - UPDATE_MAC_IE(target->p0_AlphaSets, source->p0_AlphaSets, struct NR_PUSCH_PowerControl__p0_AlphaSets); - UPDATE_MAC_IE(target->twoPUSCH_PC_AdjustmentStates, source->twoPUSCH_PC_AdjustmentStates, long); - UPDATE_MAC_IE(target->deltaMCS, source->deltaMCS, long); + UPDATE_IE(target->p0_AlphaSets, source->p0_AlphaSets, struct NR_PUSCH_PowerControl__p0_AlphaSets); + UPDATE_IE(target->twoPUSCH_PC_AdjustmentStates, source->twoPUSCH_PC_AdjustmentStates, long); + UPDATE_IE(target->deltaMCS, source->deltaMCS, long); if (source->pathlossReferenceRSToReleaseList) { RELEASE_IE_FROMLIST(source->pathlossReferenceRSToReleaseList, target->pathlossReferenceRSToAddModList, @@ -850,8 +850,8 @@ static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_Po static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *target) { - UPDATE_MAC_IE(target->dataScramblingIdentityPUSCH, source->dataScramblingIdentityPUSCH, long); - UPDATE_MAC_IE(target->txConfig, source->txConfig, long); + UPDATE_IE(target->dataScramblingIdentityPUSCH, source->dataScramblingIdentityPUSCH, long); + UPDATE_IE(target->txConfig, source->txConfig, long); if (source->dmrs_UplinkForPUSCH_MappingTypeA) HANDLE_SETUPRELEASE_IE(target->dmrs_UplinkForPUSCH_MappingTypeA, source->dmrs_UplinkForPUSCH_MappingTypeA, @@ -867,25 +867,25 @@ static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *targ target->pusch_PowerControl = calloc(1, sizeof(*target->pusch_PowerControl)); setup_puschpowercontrol(source->pusch_PowerControl, target->pusch_PowerControl); } - UPDATE_MAC_IE(target->frequencyHopping, source->frequencyHopping, long); + UPDATE_IE(target->frequencyHopping, source->frequencyHopping, long); if (source->frequencyHoppingOffsetLists) - UPDATE_MAC_IE(target->frequencyHoppingOffsetLists, - source->frequencyHoppingOffsetLists, - struct NR_PUSCH_Config__frequencyHoppingOffsetLists); + UPDATE_IE(target->frequencyHoppingOffsetLists, + source->frequencyHoppingOffsetLists, + struct NR_PUSCH_Config__frequencyHoppingOffsetLists); target->resourceAllocation = source->resourceAllocation; if (source->pusch_TimeDomainAllocationList) HANDLE_SETUPRELEASE_IE(target->pusch_TimeDomainAllocationList, source->pusch_TimeDomainAllocationList, NR_PUSCH_TimeDomainResourceAllocationList_t, asn_DEF_NR_SetupRelease_PUSCH_TimeDomainResourceAllocationList); - UPDATE_MAC_IE(target->pusch_AggregationFactor, source->pusch_AggregationFactor, long); - UPDATE_MAC_IE(target->mcs_Table, source->mcs_Table, long); - UPDATE_MAC_IE(target->mcs_TableTransformPrecoder, source->mcs_TableTransformPrecoder, long); - UPDATE_MAC_IE(target->transformPrecoder, source->transformPrecoder, long); - UPDATE_MAC_IE(target->codebookSubset, source->codebookSubset, long); - UPDATE_MAC_IE(target->maxRank, source->maxRank, long); - UPDATE_MAC_IE(target->rbg_Size, source->rbg_Size, long); - UPDATE_MAC_IE(target->tp_pi2BPSK, source->tp_pi2BPSK, long); + UPDATE_IE(target->pusch_AggregationFactor, source->pusch_AggregationFactor, long); + UPDATE_IE(target->mcs_Table, source->mcs_Table, long); + UPDATE_IE(target->mcs_TableTransformPrecoder, source->mcs_TableTransformPrecoder, long); + UPDATE_IE(target->transformPrecoder, source->transformPrecoder, long); + UPDATE_IE(target->codebookSubset, source->codebookSubset, long); + UPDATE_IE(target->maxRank, source->maxRank, long); + UPDATE_IE(target->rbg_Size, source->rbg_Size, long); + UPDATE_IE(target->tp_pi2BPSK, source->tp_pi2BPSK, long); if (source->uci_OnPUSCH) { if (source->uci_OnPUSCH->present == NR_SetupRelease_UCI_OnPUSCH_PR_release) asn1cFreeStruc(asn_DEF_NR_UCI_OnPUSCH, target->uci_OnPUSCH); @@ -893,9 +893,9 @@ static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *targ if (target->uci_OnPUSCH) { target->uci_OnPUSCH->choice.setup->scaling = source->uci_OnPUSCH->choice.setup->scaling; if (source->uci_OnPUSCH->choice.setup->betaOffsets) - UPDATE_MAC_IE(target->uci_OnPUSCH->choice.setup->betaOffsets, - source->uci_OnPUSCH->choice.setup->betaOffsets, - struct NR_UCI_OnPUSCH__betaOffsets); + UPDATE_IE(target->uci_OnPUSCH->choice.setup->betaOffsets, + source->uci_OnPUSCH->choice.setup->betaOffsets, + struct NR_UCI_OnPUSCH__betaOffsets); } } } @@ -903,7 +903,7 @@ static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *targ static void setup_pdschconfig(NR_PDSCH_Config_t *source, NR_PDSCH_Config_t *target) { - UPDATE_MAC_IE(target->dataScramblingIdentityPDSCH, source->dataScramblingIdentityPDSCH, long); + UPDATE_IE(target->dataScramblingIdentityPDSCH, source->dataScramblingIdentityPDSCH, long); if (source->dmrs_DownlinkForPDSCH_MappingTypeA) HANDLE_SETUPRELEASE_IE(target->dmrs_DownlinkForPDSCH_MappingTypeA, source->dmrs_DownlinkForPDSCH_MappingTypeA, @@ -929,14 +929,14 @@ static void setup_pdschconfig(NR_PDSCH_Config_t *source, NR_PDSCH_Config_t *targ NR_TCI_State_t); } // end TCI States - UPDATE_MAC_IE(target->vrb_ToPRB_Interleaver, source->vrb_ToPRB_Interleaver, long); + UPDATE_IE(target->vrb_ToPRB_Interleaver, source->vrb_ToPRB_Interleaver, long); target->resourceAllocation = source->resourceAllocation; if (source->pdsch_TimeDomainAllocationList) HANDLE_SETUPRELEASE_IE(target->pdsch_TimeDomainAllocationList, source->pdsch_TimeDomainAllocationList, NR_PDSCH_TimeDomainResourceAllocationList_t, asn_DEF_NR_SetupRelease_PDSCH_TimeDomainResourceAllocationList); - UPDATE_MAC_IE(target->pdsch_AggregationFactor, source->pdsch_AggregationFactor, long); + UPDATE_IE(target->pdsch_AggregationFactor, source->pdsch_AggregationFactor, long); // rateMatchPattern if (source->rateMatchPatternToReleaseList) { RELEASE_IE_FROMLIST(source->rateMatchPatternToReleaseList, @@ -952,12 +952,12 @@ static void setup_pdschconfig(NR_PDSCH_Config_t *source, NR_PDSCH_Config_t *targ NR_RateMatchPattern_t); } // end rateMatchPattern - UPDATE_MAC_IE(target->rateMatchPatternGroup1, source->rateMatchPatternGroup1, NR_RateMatchPatternGroup_t); - UPDATE_MAC_IE(target->rateMatchPatternGroup2, source->rateMatchPatternGroup2, NR_RateMatchPatternGroup_t); + UPDATE_IE(target->rateMatchPatternGroup1, source->rateMatchPatternGroup1, NR_RateMatchPatternGroup_t); + UPDATE_IE(target->rateMatchPatternGroup2, source->rateMatchPatternGroup2, NR_RateMatchPatternGroup_t); target->rbg_Size = source->rbg_Size; - UPDATE_MAC_IE(target->mcs_Table, source->mcs_Table, long); - UPDATE_MAC_IE(target->maxNrofCodeWordsScheduledByDCI, source->maxNrofCodeWordsScheduledByDCI, long); - UPDATE_MAC_NP_IE(target->prb_BundlingType, source->prb_BundlingType, struct NR_PDSCH_Config__prb_BundlingType); + UPDATE_IE(target->mcs_Table, source->mcs_Table, long); + UPDATE_IE(target->maxNrofCodeWordsScheduledByDCI, source->maxNrofCodeWordsScheduledByDCI, long); + UPDATE_NP_IE(target->prb_BundlingType, source->prb_BundlingType, struct NR_PDSCH_Config__prb_BundlingType); AssertFatal(source->zp_CSI_RS_ResourceToAddModList == NULL, "Not handled\n"); AssertFatal(source->aperiodic_ZP_CSI_RS_ResourceSetsToAddModList == NULL, "Not handled\n"); AssertFatal(source->sp_ZP_CSI_RS_ResourceSetsToAddModList == NULL, "Not handled\n"); @@ -968,11 +968,11 @@ static void setup_sr_resource(NR_SchedulingRequestResourceConfig_t *target, NR_S target->schedulingRequestResourceId = source->schedulingRequestResourceId; target->schedulingRequestID = source->schedulingRequestID; if (source->periodicityAndOffset) - UPDATE_MAC_IE(target->periodicityAndOffset, - source->periodicityAndOffset, - struct NR_SchedulingRequestResourceConfig__periodicityAndOffset); + UPDATE_IE(target->periodicityAndOffset, + source->periodicityAndOffset, + struct NR_SchedulingRequestResourceConfig__periodicityAndOffset); if (source->resource) - UPDATE_MAC_IE(target->resource, source->resource, NR_PUCCH_ResourceId_t); + UPDATE_IE(target->resource, source->resource, NR_PUCCH_ResourceId_t); } static void setup_pucchconfig(NR_PUCCH_Config_t *source, NR_PUCCH_Config_t *target) @@ -1043,11 +1043,11 @@ static void setup_pucchconfig(NR_PUCCH_Config_t *source, NR_PUCCH_Config_t *targ } if (source->multi_CSI_PUCCH_ResourceList) - UPDATE_MAC_IE(target->multi_CSI_PUCCH_ResourceList, - source->multi_CSI_PUCCH_ResourceList, - struct NR_PUCCH_Config__multi_CSI_PUCCH_ResourceList); + UPDATE_IE(target->multi_CSI_PUCCH_ResourceList, + source->multi_CSI_PUCCH_ResourceList, + struct NR_PUCCH_Config__multi_CSI_PUCCH_ResourceList); if (source->dl_DataToUL_ACK) - UPDATE_MAC_IE(target->dl_DataToUL_ACK, source->dl_DataToUL_ACK, struct NR_PUCCH_Config__dl_DataToUL_ACK); + UPDATE_IE(target->dl_DataToUL_ACK, source->dl_DataToUL_ACK, struct NR_PUCCH_Config__dl_DataToUL_ACK); // PUCCH-SpatialRelationInfo if (source->spatialRelationInfoToAddModList) { if (!target->spatialRelationInfoToAddModList) @@ -1066,20 +1066,20 @@ static void setup_pucchconfig(NR_PUCCH_Config_t *source, NR_PUCCH_Config_t *targ if (source->pucch_PowerControl) { if (!target->pucch_PowerControl) target->pucch_PowerControl = calloc(1, sizeof(*target->pucch_PowerControl)); - UPDATE_MAC_IE(target->pucch_PowerControl->deltaF_PUCCH_f0, source->pucch_PowerControl->deltaF_PUCCH_f0, long); - UPDATE_MAC_IE(target->pucch_PowerControl->deltaF_PUCCH_f1, source->pucch_PowerControl->deltaF_PUCCH_f1, long); - UPDATE_MAC_IE(target->pucch_PowerControl->deltaF_PUCCH_f2, source->pucch_PowerControl->deltaF_PUCCH_f2, long); - UPDATE_MAC_IE(target->pucch_PowerControl->deltaF_PUCCH_f3, source->pucch_PowerControl->deltaF_PUCCH_f3, long); - UPDATE_MAC_IE(target->pucch_PowerControl->deltaF_PUCCH_f4, source->pucch_PowerControl->deltaF_PUCCH_f4, long); + UPDATE_IE(target->pucch_PowerControl->deltaF_PUCCH_f0, source->pucch_PowerControl->deltaF_PUCCH_f0, long); + UPDATE_IE(target->pucch_PowerControl->deltaF_PUCCH_f1, source->pucch_PowerControl->deltaF_PUCCH_f1, long); + UPDATE_IE(target->pucch_PowerControl->deltaF_PUCCH_f2, source->pucch_PowerControl->deltaF_PUCCH_f2, long); + UPDATE_IE(target->pucch_PowerControl->deltaF_PUCCH_f3, source->pucch_PowerControl->deltaF_PUCCH_f3, long); + UPDATE_IE(target->pucch_PowerControl->deltaF_PUCCH_f4, source->pucch_PowerControl->deltaF_PUCCH_f4, long); if (source->pucch_PowerControl->p0_Set) - UPDATE_MAC_IE(target->pucch_PowerControl->p0_Set, source->pucch_PowerControl->p0_Set, struct NR_PUCCH_PowerControl__p0_Set); + UPDATE_IE(target->pucch_PowerControl->p0_Set, source->pucch_PowerControl->p0_Set, struct NR_PUCCH_PowerControl__p0_Set); if (source->pucch_PowerControl->pathlossReferenceRSs) - UPDATE_MAC_IE(target->pucch_PowerControl->pathlossReferenceRSs, - source->pucch_PowerControl->pathlossReferenceRSs, - struct NR_PUCCH_PowerControl__pathlossReferenceRSs); - UPDATE_MAC_IE(target->pucch_PowerControl->twoPUCCH_PC_AdjustmentStates, - source->pucch_PowerControl->twoPUCCH_PC_AdjustmentStates, - long); + UPDATE_IE(target->pucch_PowerControl->pathlossReferenceRSs, + source->pucch_PowerControl->pathlossReferenceRSs, + struct NR_PUCCH_PowerControl__pathlossReferenceRSs); + UPDATE_IE(target->pucch_PowerControl->twoPUCCH_PC_AdjustmentStates, + source->pucch_PowerControl->twoPUCCH_PC_AdjustmentStates, + long); } } @@ -1088,22 +1088,22 @@ static void handle_aperiodic_srs_type(struct NR_SRS_ResourceSet__resourceType__a { target->aperiodicSRS_ResourceTrigger = source->aperiodicSRS_ResourceTrigger; if (source->csi_RS) - UPDATE_MAC_IE(target->csi_RS, source->csi_RS, NR_NZP_CSI_RS_ResourceId_t); - UPDATE_MAC_IE(target->slotOffset, source->slotOffset, long); + UPDATE_IE(target->csi_RS, source->csi_RS, NR_NZP_CSI_RS_ResourceId_t); + UPDATE_IE(target->slotOffset, source->slotOffset, long); if (source->ext1 && source->ext1->aperiodicSRS_ResourceTriggerList) - UPDATE_MAC_IE(target->ext1->aperiodicSRS_ResourceTriggerList, - source->ext1->aperiodicSRS_ResourceTriggerList, - struct NR_SRS_ResourceSet__resourceType__aperiodic__ext1__aperiodicSRS_ResourceTriggerList); + UPDATE_IE(target->ext1->aperiodicSRS_ResourceTriggerList, + source->ext1->aperiodicSRS_ResourceTriggerList, + struct NR_SRS_ResourceSet__resourceType__aperiodic__ext1__aperiodicSRS_ResourceTriggerList); } static void setup_srsresourceset(NR_SRS_ResourceSet_t *target, NR_SRS_ResourceSet_t *source) { target->srs_ResourceSetId = source->srs_ResourceSetId; if (source->srs_ResourceIdList) - UPDATE_MAC_IE(target->srs_ResourceIdList, source->srs_ResourceIdList, struct NR_SRS_ResourceSet__srs_ResourceIdList); + UPDATE_IE(target->srs_ResourceIdList, source->srs_ResourceIdList, struct NR_SRS_ResourceSet__srs_ResourceIdList); if (target->resourceType.present != source->resourceType.present) { - UPDATE_MAC_NP_IE(target->resourceType, source->resourceType, struct NR_SRS_ResourceSet__resourceType); + UPDATE_NP_IE(target->resourceType, source->resourceType, struct NR_SRS_ResourceSet__resourceType); } else { switch (source->resourceType.present) { @@ -1112,32 +1112,32 @@ static void setup_srsresourceset(NR_SRS_ResourceSet_t *target, NR_SRS_ResourceSe break; case NR_SRS_ResourceSet__resourceType_PR_periodic: if (source->resourceType.choice.periodic->associatedCSI_RS) - UPDATE_MAC_IE(target->resourceType.choice.periodic->associatedCSI_RS, - source->resourceType.choice.periodic->associatedCSI_RS, - NR_NZP_CSI_RS_ResourceId_t); + UPDATE_IE(target->resourceType.choice.periodic->associatedCSI_RS, + source->resourceType.choice.periodic->associatedCSI_RS, + NR_NZP_CSI_RS_ResourceId_t); break; case NR_SRS_ResourceSet__resourceType_PR_semi_persistent: if (source->resourceType.choice.semi_persistent->associatedCSI_RS) - UPDATE_MAC_IE(target->resourceType.choice.semi_persistent->associatedCSI_RS, - source->resourceType.choice.semi_persistent->associatedCSI_RS, - NR_NZP_CSI_RS_ResourceId_t); + UPDATE_IE(target->resourceType.choice.semi_persistent->associatedCSI_RS, + source->resourceType.choice.semi_persistent->associatedCSI_RS, + NR_NZP_CSI_RS_ResourceId_t); break; default: break; } } target->usage = source->usage; - UPDATE_MAC_IE(target->alpha, source->alpha, NR_Alpha_t); + UPDATE_IE(target->alpha, source->alpha, NR_Alpha_t); if (source->p0) - UPDATE_MAC_IE(target->p0, source->p0, long); + UPDATE_IE(target->p0, source->p0, long); if (source->pathlossReferenceRS) - UPDATE_MAC_IE(target->pathlossReferenceRS, source->pathlossReferenceRS, struct NR_PathlossReferenceRS_Config); - UPDATE_MAC_IE(target->srs_PowerControlAdjustmentStates, source->srs_PowerControlAdjustmentStates, long); + UPDATE_IE(target->pathlossReferenceRS, source->pathlossReferenceRS, struct NR_PathlossReferenceRS_Config); + UPDATE_IE(target->srs_PowerControlAdjustmentStates, source->srs_PowerControlAdjustmentStates, long); } static void setup_srsconfig(NR_SRS_Config_t *source, NR_SRS_Config_t *target) { - UPDATE_MAC_IE(target->tpc_Accumulation, source->tpc_Accumulation, long); + UPDATE_IE(target->tpc_Accumulation, source->tpc_Accumulation, long); // SRS-Resource if (source->srs_ResourceToAddModList) { if (!target->srs_ResourceToAddModList) @@ -1297,9 +1297,9 @@ static void configure_common_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Do } if (dl_common->pdsch_ConfigCommon) { if (dl_common->pdsch_ConfigCommon->present == NR_SetupRelease_PDSCH_ConfigCommon_PR_setup) - UPDATE_MAC_IE(bwp->tdaList_Common, - dl_common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList, - NR_PDSCH_TimeDomainResourceAllocationList_t); + UPDATE_IE(bwp->tdaList_Common, + dl_common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList, + NR_PDSCH_TimeDomainResourceAllocationList_t); if (dl_common->pdsch_ConfigCommon->present == NR_SetupRelease_PDSCH_ConfigCommon_PR_release) asn1cFreeStruc(asn_DEF_NR_PDSCH_TimeDomainResourceAllocationList, bwp->tdaList_Common); } @@ -1340,10 +1340,10 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up asn_DEF_NR_PUCCH_ConfigCommon); if (ul_common->pusch_ConfigCommon) { if (ul_common->pusch_ConfigCommon->present == NR_SetupRelease_PUSCH_ConfigCommon_PR_setup) { - UPDATE_MAC_IE(bwp->tdaList_Common, - ul_common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList, - NR_PUSCH_TimeDomainResourceAllocationList_t); - UPDATE_MAC_IE(bwp->msg3_DeltaPreamble, ul_common->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble, long); + UPDATE_IE(bwp->tdaList_Common, + ul_common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList, + NR_PUSCH_TimeDomainResourceAllocationList_t); + UPDATE_IE(bwp->msg3_DeltaPreamble, ul_common->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble, long); } if (ul_common->pusch_ConfigCommon->present == NR_SetupRelease_PUSCH_ConfigCommon_PR_release) { asn1cFreeStruc(asn_DEF_NR_PUSCH_TimeDomainResourceAllocationList, bwp->tdaList_Common); @@ -1381,8 +1381,8 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); AssertFatal(scc, "SIB1 SCC should not be NULL\n"); - UPDATE_MAC_IE(mac->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon, NR_TDD_UL_DL_ConfigCommon_t); - UPDATE_MAC_IE(mac->si_SchedulingInfo, si_SchedulingInfo, NR_SI_SchedulingInfo_t); + UPDATE_IE(mac->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon, NR_TDD_UL_DL_ConfigCommon_t); + UPDATE_IE(mac->si_SchedulingInfo, si_SchedulingInfo, NR_SI_SchedulingInfo_t); config_common_ue_sa(mac, scc, cc_idP); configure_common_BWP_dl(mac, @@ -1421,7 +1421,7 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, AssertFatal( reconfigurationWithSync->rach_ConfigDedicated->present == NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink, "RACH on supplementaryUplink not supported\n"); - UPDATE_MAC_IE(ra->rach_ConfigDedicated, reconfigurationWithSync->rach_ConfigDedicated->choice.uplink, NR_RACH_ConfigDedicated_t); + UPDATE_IE(ra->rach_ConfigDedicated, reconfigurationWithSync->rach_ConfigDedicated->choice.uplink, NR_RACH_ConfigDedicated_t); } if (reconfigurationWithSync->spCellConfigCommon) { @@ -1429,7 +1429,7 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, if (scc->physCellId) mac->physCellId = *scc->physCellId; mac->dmrs_TypeA_Position = scc->dmrs_TypeA_Position; - UPDATE_MAC_IE(mac->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon, NR_TDD_UL_DL_ConfigCommon_t); + UPDATE_IE(mac->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon, NR_TDD_UL_DL_ConfigCommon_t); config_common_ue(mac, scc, cc_idP); if (scc->downlinkConfigCommon) configure_common_BWP_dl(mac, @@ -1530,9 +1530,9 @@ static void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroup static void configure_csi_resourcemapping(NR_CSI_RS_ResourceMapping_t *target, NR_CSI_RS_ResourceMapping_t *source) { if (target->frequencyDomainAllocation.present != source->frequencyDomainAllocation.present) { - UPDATE_MAC_NP_IE(target->frequencyDomainAllocation, - source->frequencyDomainAllocation, - struct NR_CSI_RS_ResourceMapping__frequencyDomainAllocation); + UPDATE_NP_IE(target->frequencyDomainAllocation, + source->frequencyDomainAllocation, + struct NR_CSI_RS_ResourceMapping__frequencyDomainAllocation); } else { switch (source->frequencyDomainAllocation.present) { @@ -1578,7 +1578,7 @@ static void configure_csi_resourcemapping(NR_CSI_RS_ResourceMapping_t *target, N } target->nrofPorts = source->nrofPorts; target->firstOFDMSymbolInTimeDomain = source->firstOFDMSymbolInTimeDomain; - UPDATE_MAC_IE(target->firstOFDMSymbolInTimeDomain2, source->firstOFDMSymbolInTimeDomain2, long); + UPDATE_IE(target->firstOFDMSymbolInTimeDomain2, source->firstOFDMSymbolInTimeDomain2, long); target->cdm_Type = source->cdm_Type; target->density = source->density; target->freqBand = source->freqBand; @@ -1588,24 +1588,24 @@ static void configure_csirs_resource(NR_NZP_CSI_RS_Resource_t *target, NR_NZP_CS { configure_csi_resourcemapping(&target->resourceMapping, &source->resourceMapping); target->powerControlOffset = source->powerControlOffset; - UPDATE_MAC_IE(target->powerControlOffsetSS, source->powerControlOffsetSS, long); + UPDATE_IE(target->powerControlOffsetSS, source->powerControlOffsetSS, long); target->scramblingID = source->scramblingID; if (source->periodicityAndOffset) - UPDATE_MAC_IE(target->periodicityAndOffset, source->periodicityAndOffset, NR_CSI_ResourcePeriodicityAndOffset_t); + UPDATE_IE(target->periodicityAndOffset, source->periodicityAndOffset, NR_CSI_ResourcePeriodicityAndOffset_t); if (source->qcl_InfoPeriodicCSI_RS) - UPDATE_MAC_IE(target->qcl_InfoPeriodicCSI_RS, source->qcl_InfoPeriodicCSI_RS, NR_TCI_StateId_t); + UPDATE_IE(target->qcl_InfoPeriodicCSI_RS, source->qcl_InfoPeriodicCSI_RS, NR_TCI_StateId_t); } static void configure_csiim_resource(NR_CSI_IM_Resource_t *target, NR_CSI_IM_Resource_t *source) { if (source->csi_IM_ResourceElementPattern) - UPDATE_MAC_IE(target->csi_IM_ResourceElementPattern, - source->csi_IM_ResourceElementPattern, - struct NR_CSI_IM_Resource__csi_IM_ResourceElementPattern); + UPDATE_IE(target->csi_IM_ResourceElementPattern, + source->csi_IM_ResourceElementPattern, + struct NR_CSI_IM_Resource__csi_IM_ResourceElementPattern); if (source->freqBand) - UPDATE_MAC_IE(target->freqBand, source->freqBand, NR_CSI_FrequencyOccupation_t); + UPDATE_IE(target->freqBand, source->freqBand, NR_CSI_FrequencyOccupation_t); if (source->periodicityAndOffset) - UPDATE_MAC_IE(target->periodicityAndOffset, source->periodicityAndOffset, NR_CSI_ResourcePeriodicityAndOffset_t); + UPDATE_IE(target->periodicityAndOffset, source->periodicityAndOffset, NR_CSI_ResourcePeriodicityAndOffset_t); } static void configure_csiconfig(NR_UE_ServingCell_Info_t *sc_info, struct NR_SetupRelease_CSI_MeasConfig *csi_MeasConfig_sr) @@ -1618,12 +1618,12 @@ static void configure_csiconfig(NR_UE_ServingCell_Info_t *sc_info, struct NR_Set break; case NR_SetupRelease_CSI_MeasConfig_PR_setup: if (!sc_info->csi_MeasConfig) { // setup - UPDATE_MAC_IE(sc_info->csi_MeasConfig, csi_MeasConfig_sr->choice.setup, NR_CSI_MeasConfig_t); + UPDATE_IE(sc_info->csi_MeasConfig, csi_MeasConfig_sr->choice.setup, NR_CSI_MeasConfig_t); } else { // modification NR_CSI_MeasConfig_t *target = sc_info->csi_MeasConfig; NR_CSI_MeasConfig_t *csi_MeasConfig = csi_MeasConfig_sr->choice.setup; if (csi_MeasConfig->reportTriggerSize) - UPDATE_MAC_IE(target->reportTriggerSize, csi_MeasConfig->reportTriggerSize, long); + UPDATE_IE(target->reportTriggerSize, csi_MeasConfig->reportTriggerSize, long); if (csi_MeasConfig->aperiodicTriggerStateList) HANDLE_SETUPRELEASE_DIRECT(sc_info->aperiodicTriggerStateList, csi_MeasConfig->aperiodicTriggerStateList, @@ -1747,9 +1747,9 @@ static void configure_servingcell_info(NR_UE_ServingCell_Info_t *sc_info, NR_Ser configure_csiconfig(sc_info, scd->csi_MeasConfig); if (scd->supplementaryUplink) - UPDATE_MAC_IE(sc_info->supplementaryUplink, scd->supplementaryUplink, NR_UplinkConfig_t); + UPDATE_IE(sc_info->supplementaryUplink, scd->supplementaryUplink, NR_UplinkConfig_t); if (scd->crossCarrierSchedulingConfig) - UPDATE_MAC_IE(sc_info->crossCarrierSchedulingConfig, scd->crossCarrierSchedulingConfig, NR_CrossCarrierSchedulingConfig_t); + UPDATE_IE(sc_info->crossCarrierSchedulingConfig, scd->crossCarrierSchedulingConfig, NR_CrossCarrierSchedulingConfig_t); if (scd->pdsch_ServingCellConfig) { switch (scd->pdsch_ServingCellConfig->present) { case NR_SetupRelease_PDSCH_ServingCellConfig_PR_NOTHING: @@ -1774,9 +1774,9 @@ static void configure_servingcell_info(NR_UE_ServingCell_Info_t *sc_info, NR_Ser pdsch_servingcellconfig->codeBlockGroupTransmission, NR_PDSCH_CodeBlockGroupTransmission_t, asn_DEF_NR_PDSCH_CodeBlockGroupTransmission); - UPDATE_MAC_IE(sc_info->xOverhead_PDSCH, pdsch_servingcellconfig->xOverhead, long); + UPDATE_IE(sc_info->xOverhead_PDSCH, pdsch_servingcellconfig->xOverhead, long); if (pdsch_servingcellconfig->ext1 && pdsch_servingcellconfig->ext1->maxMIMO_Layers) - UPDATE_MAC_IE(sc_info->maxMIMO_Layers_PDSCH, pdsch_servingcellconfig->ext1->maxMIMO_Layers, long); + UPDATE_IE(sc_info->maxMIMO_Layers_PDSCH, pdsch_servingcellconfig->ext1->maxMIMO_Layers, long); break; } default: @@ -1806,10 +1806,10 @@ static void configure_servingcell_info(NR_UE_ServingCell_Info_t *sc_info, NR_Ser break; case NR_SetupRelease_PUSCH_ServingCellConfig_PR_setup: { NR_PUSCH_ServingCellConfig_t *pusch_servingcellconfig = scd->uplinkConfig->pusch_ServingCellConfig->choice.setup; - UPDATE_MAC_IE(sc_info->rateMatching_PUSCH, pusch_servingcellconfig->rateMatching, long); - UPDATE_MAC_IE(sc_info->xOverhead_PUSCH, pusch_servingcellconfig->xOverhead, long); + UPDATE_IE(sc_info->rateMatching_PUSCH, pusch_servingcellconfig->rateMatching, long); + UPDATE_IE(sc_info->xOverhead_PUSCH, pusch_servingcellconfig->xOverhead, long); if (pusch_servingcellconfig->ext1 && pusch_servingcellconfig->ext1->maxMIMO_Layers) - UPDATE_MAC_IE(sc_info->maxMIMO_Layers_PUSCH, pusch_servingcellconfig->ext1->maxMIMO_Layers, long); + UPDATE_IE(sc_info->maxMIMO_Layers_PUSCH, pusch_servingcellconfig->ext1->maxMIMO_Layers, long); if (pusch_servingcellconfig->codeBlockGroupTransmission) HANDLE_SETUPRELEASE_DIRECT(sc_info->pusch_CGB_Transmission, pusch_servingcellconfig->codeBlockGroupTransmission, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 57883839d5..e354e338b4 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -40,111 +40,6 @@ #define NR_DL_MAX_DAI (4) /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */ #define NR_DL_MAX_NB_CW (2) /* number of downlink code word */ -// Macro updates DESTINATION with configuration from ORIGIN by swapping pointers -// Old configuration is freed after completing configuration -#define UPDATE_MAC_IE(DESTINATION, ORIGIN, TYPE) \ - do { \ - TYPE *tmp = ORIGIN; \ - ORIGIN = DESTINATION; \ - DESTINATION = tmp; \ - } while(0); \ - -// Same as above but swapping ASN1 elements that are not pointers -#define UPDATE_MAC_NP_IE(DESTINATION, ORIGIN, TYPE) \ - do { \ - TYPE tmp = ORIGIN; \ - ORIGIN = DESTINATION; \ - DESTINATION = tmp; \ - } while(0); \ - -// Macro handles reception of SetupRelease element ORIGIN (see NR_SetupRelease.h) -// If release (NR_SetupRelease_xxx_PR_release equivalent to 1), removing structure from DESTINATION -// If setup (NR_SetupRelease_xxx_PR_setup equivalent to 2), add or modify structure in DESTINATION -// Destination is not a SetupRelease structure -#define HANDLE_SETUPRELEASE_DIRECT(DESTINATION, ORIGIN, TYPE, ASN_DEF) \ - do { \ - if (ORIGIN->present == 1) { \ - asn1cFreeStruc(ASN_DEF, DESTINATION); \ - } \ - if (ORIGIN->present == 2) \ - UPDATE_MAC_IE(DESTINATION, ORIGIN->choice.setup, TYPE); \ - } while(0); \ - -// Macro handles reception of SetupRelease element ORIGIN (see NR_SetupRelease.h) -// If release (NR_SetupRelease_xxx_PR_release equivalent to 1), removing structure from DESTINATION -// If setup (NR_SetupRelease_xxx_PR_setup equivalent to 2), add or modify structure in DESTINATION -// Destination is a SetupRelease structure -#define HANDLE_SETUPRELEASE_IE(DESTINATION, ORIGIN, TYPE, ASN_DEF) \ - do { \ - if (ORIGIN->present == 1) { \ - asn1cFreeStruc(ASN_DEF, DESTINATION); \ - } \ - if (ORIGIN->present == 2) { \ - if (!DESTINATION) \ - DESTINATION = calloc(1, sizeof(*DESTINATION)); \ - DESTINATION->present = ORIGIN->present; \ - UPDATE_MAC_IE(DESTINATION->choice.setup, ORIGIN->choice.setup, TYPE); \ - } \ - } while(0); \ - -// Macro releases entries in list TARGET if the corresponding ID is found in list SOURCE. -// Prints an error if ID not found in list. -#define RELEASE_IE_FROMLIST(SOURCE, TARGET, FIELD) \ - do { \ - for (int iI = 0; iI < SOURCE->list.count; iI++) { \ - long eL = *SOURCE->list.array[iI]; \ - int iJ; \ - for (iJ = 0; iJ < TARGET->list.count; iJ++) { \ - if (eL == TARGET->list.array[iJ]->FIELD) \ - break; \ - } \ - if (iJ == TARGET->list.count) \ - asn_sequence_del(&TARGET->list, iJ, 1); \ - else \ - LOG_E(NR_MAC, "Element not present in the list, impossible to release\n"); \ - } \ - } while (0) \ - -// Macro adds or modifies entries of type TYPE in list TARGET with elements received in list SOURCE -#define ADDMOD_IE_FROMLIST(SOURCE, TARGET, FIELD, TYPE) \ - do { \ - for (int iI = 0; iI < SOURCE->list.count; iI++) { \ - long eL = SOURCE->list.array[iI]->FIELD; \ - int iJ; \ - for (iJ = 0; iJ < TARGET->list.count; iJ++) { \ - if (eL == TARGET->list.array[iJ]->FIELD) \ - break; \ - } \ - if (iJ == TARGET->list.count) { \ - TYPE *nEW = calloc(1, sizeof(*nEW)); \ - ASN_SEQUENCE_ADD(&TARGET->list, nEW); \ - } \ - UPDATE_MAC_IE(TARGET->list.array[iJ], \ - SOURCE->list.array[iI], \ - TYPE); \ - } \ - } while (0) \ - -// Macro adds or modifies entries of type TYPE in list TARGET with elements received in list SOURCE -// Action performed by function FUNC -#define ADDMOD_IE_FROMLIST_WFUNCTION(SOURCE, TARGET, FIELD, TYPE, FUNC) \ - do { \ - for (int iI = 0; iI < SOURCE->list.count; iI++) { \ - long eL = SOURCE->list.array[iI]->FIELD; \ - int iJ; \ - for (iJ = 0; iJ < TARGET->list.count; iJ++) { \ - if (eL == TARGET->list.array[iJ]->FIELD) \ - break; \ - } \ - if (iJ == TARGET->list.count) { \ - TYPE *nEW = calloc(1, sizeof(*nEW)); \ - ASN_SEQUENCE_ADD(&TARGET->list, nEW); \ - } \ - FUNC(TARGET->list.array[iJ], \ - SOURCE->list.array[iI]); \ - } \ - } while (0) - /**\brief initialize the field in nr_mac instance \param mac MAC pointer */ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac); From 801ebbbb5fa34e9dad1df39f7e57b036ad56c92a Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 8 Feb 2024 13:19:00 +0100 Subject: [PATCH 03/35] improvements in handling measObject addition, modification and removal --- openair2/RRC/NR_UE/rrc_UE.c | 146 ++++++++++++++++++++++++++++-------- 1 file changed, 113 insertions(+), 33 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 8385236ff1..1f3c30dc0e 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -149,7 +149,7 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, OCTET_STRING_t *masterCellGroup, long *fullConfig); -void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig); +static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig); static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_index, @@ -1045,43 +1045,123 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, securityModeCommand->criticalExtensions.present); } - //----------------------------------------------------------------------------- -void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig) -//----------------------------------------------------------------------------- +static void handle_measobj_remove(rrcPerNB_t *rrc, struct NR_MeasObjectToRemoveList *remove_list) { - 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; + // section 5.5.2.4 in 38.331 + for (int i = 0; i < remove_list->list.count; i++) { + // for each measObjectId included in the received measObjectToRemoveList + // that is part of measObjectList in the configuration + NR_MeasObjectId_t id = *remove_list->list.array[i]; + if (rrc->MeasObj[id - 1]) { + // remove the entry with the matching measObjectId from the measObjectList + asn1cFreeStruc(asn_DEF_NR_MeasObjectToAddMod, rrc->MeasObj[id - 1]); + // remove all measId associated with this measObjectId from the measIdList + for (int j = 0; j < MAX_MEAS_ID; j++) { + if (rrc->MeasId[j] && rrc->MeasId[j]->measObjectId == id) { + NR_ReportConfigId_t report_id = rrc->MeasId[j]->reportConfigId; + asn1cFreeStruc(asn_DEF_NR_MeasIdToAddMod, rrc->MeasId[j]); + // remove the measurement reporting entry for this measId if included + // TODO verify this is correct + asn1cFreeStruc(asn_DEF_NR_ReportConfigToAddMod, rrc->ReportConfig[report_id]); + // TODO stop the periodical reporting timer or timer T321, whichever is running, + // and reset the associated information (e.g. timeToTrigger) for this measId } } } - - LOG_I(NR_RRC, "call rrc_mac_config_req \n"); - // rrc_mac_config_req_ue } +} + +static void update_ssb_configmob(NR_SSB_ConfigMobility_t *source, NR_SSB_ConfigMobility_t *target) +{ + if (source->ssb_ToMeasure) + HANDLE_SETUPRELEASE_IE(target->ssb_ToMeasure, source->ssb_ToMeasure, NR_SSB_ToMeasure_t, asn_DEF_NR_SSB_ToMeasure); + target->deriveSSB_IndexFromCell = source->deriveSSB_IndexFromCell; + if (source->ss_RSSI_Measurement) + UPDATE_IE(target->ss_RSSI_Measurement, source->ss_RSSI_Measurement, NR_SS_RSSI_Measurement_t); +} + +static void update_nr_measobj(NR_MeasObjectNR_t *source, NR_MeasObjectNR_t *target) +{ + UPDATE_IE(target->ssbFrequency, source->ssbFrequency, NR_ARFCN_ValueNR_t); + UPDATE_IE(target->ssbSubcarrierSpacing, source->ssbSubcarrierSpacing, NR_SubcarrierSpacing_t); + UPDATE_IE(target->smtc1, source->smtc1, NR_SSB_MTC_t); + if (source->smtc2) { + target->smtc2->periodicity = source->smtc2->periodicity; + if (source->smtc2->pci_List) + UPDATE_IE(target->smtc2->pci_List, source->smtc2->pci_List, struct NR_SSB_MTC2__pci_List); + } + else + asn1cFreeStruc(asn_DEF_NR_SSB_MTC2, target->smtc2); + UPDATE_IE(target->refFreqCSI_RS, source->refFreqCSI_RS, NR_ARFCN_ValueNR_t); + if (source->referenceSignalConfig.ssb_ConfigMobility) + update_ssb_configmob(source->referenceSignalConfig.ssb_ConfigMobility, target->referenceSignalConfig.ssb_ConfigMobility); + UPDATE_IE(target->absThreshSS_BlocksConsolidation, source->absThreshSS_BlocksConsolidation, NR_ThresholdNR_t); + UPDATE_IE(target->absThreshCSI_RS_Consolidation, source->absThreshCSI_RS_Consolidation, NR_ThresholdNR_t); + UPDATE_IE(target->nrofSS_BlocksToAverage, source->nrofSS_BlocksToAverage, long); + UPDATE_IE(target->nrofCSI_RS_ResourcesToAverage, source->nrofCSI_RS_ResourcesToAverage, long); + target->quantityConfigIndex = source->quantityConfigIndex; + target->offsetMO = source->offsetMO; + if (source->cellsToRemoveList) { + RELEASE_IE_FROMLIST(source->cellsToRemoveList, target->cellsToAddModList, physCellId); + } + if (source->cellsToAddModList) { + if (!target->cellsToAddModList) + target->cellsToAddModList = calloc(1, sizeof(*target->cellsToAddModList)); + ADDMOD_IE_FROMLIST(source->cellsToAddModList, target->cellsToAddModList, physCellId, NR_CellsToAddMod_t); + } + if (source->excludedCellsToRemoveList) { + RELEASE_IE_FROMLIST(source->excludedCellsToRemoveList, target->excludedCellsToAddModList, pci_RangeIndex); + } + if (source->excludedCellsToAddModList) { + if (!target->excludedCellsToAddModList) + target->excludedCellsToAddModList = calloc(1, sizeof(*target->excludedCellsToAddModList)); + ADDMOD_IE_FROMLIST(source->excludedCellsToAddModList, target->excludedCellsToAddModList, pci_RangeIndex, NR_PCI_RangeElement_t); + } + if (source->allowedCellsToRemoveList) { + RELEASE_IE_FROMLIST(source->allowedCellsToRemoveList, target->allowedCellsToAddModList, pci_RangeIndex); + } + if (source->allowedCellsToAddModList) { + if (!target->allowedCellsToAddModList) + target->allowedCellsToAddModList = calloc(1, sizeof(*target->allowedCellsToAddModList)); + ADDMOD_IE_FROMLIST(source->allowedCellsToAddModList, target->allowedCellsToAddModList, pci_RangeIndex, NR_PCI_RangeElement_t); + } + if (source->ext1) { + UPDATE_IE(target->ext1->freqBandIndicatorNR, source->ext1->freqBandIndicatorNR, NR_FreqBandIndicatorNR_t); + UPDATE_IE(target->ext1->measCycleSCell, source->ext1->measCycleSCell, long); + } +} + +static void handle_measobj_addmod(rrcPerNB_t *rrc, struct NR_MeasObjectToAddModList *addmod_list) +{ + // section 5.5.2.5 in 38.331 + for (int i = 0; i < addmod_list->list.count; i++) { + NR_MeasObjectToAddMod_t *measObj = addmod_list->list.array[i]; + if (measObj->measObject.present != NR_MeasObjectToAddMod__measObject_PR_measObjectNR) { + LOG_E(NR_RRC, "Cannot handle MeasObjt other than NR\n"); + continue; + } + NR_MeasObjectId_t id = measObj->measObjectId; + if (rrc->MeasObj[id]) { + update_nr_measobj(measObj->measObject.choice.measObjectNR, rrc->MeasObj[id]->measObject.choice.measObjectNR); + } + else { + // add a new entry for the received measObject to the measObjectList + UPDATE_IE(rrc->MeasObj[id], addmod_list->list.array[i], NR_MeasObjectToAddMod_t); + } + } +} + +static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig) +{ + int i; + long ind; + NR_ReportConfigToAddMod_t *reportConfig = NULL; + + if (measConfig->measObjectToRemoveList) + handle_measobj_remove(rrc, measConfig->measObjectToRemoveList); + + if (measConfig->measObjectToAddModList) + handle_measobj_addmod(rrc, measConfig->measObjectToAddModList); if (measConfig->reportConfigToRemoveList != NULL) { for (i = 0; i < measConfig->reportConfigToRemoveList->list.count; i++) { From 0ab88e390bf77dce30df5feccc4627574b345d8f Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 9 Feb 2024 14:00:49 +0100 Subject: [PATCH 04/35] improvements in handling reportConfig addition, modification and removal --- openair2/RRC/NR_UE/rrc_UE.c | 77 ++++++++++++++++++++++------------- openair2/RRC/NR_UE/rrc_defs.h | 3 ++ 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 1f3c30dc0e..32f8a7dfbe 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1058,11 +1058,9 @@ static void handle_measobj_remove(rrcPerNB_t *rrc, struct NR_MeasObjectToRemoveL // remove all measId associated with this measObjectId from the measIdList for (int j = 0; j < MAX_MEAS_ID; j++) { if (rrc->MeasId[j] && rrc->MeasId[j]->measObjectId == id) { - NR_ReportConfigId_t report_id = rrc->MeasId[j]->reportConfigId; asn1cFreeStruc(asn_DEF_NR_MeasIdToAddMod, rrc->MeasId[j]); // remove the measurement reporting entry for this measId if included - // TODO verify this is correct - asn1cFreeStruc(asn_DEF_NR_ReportConfigToAddMod, rrc->ReportConfig[report_id]); + asn1cFreeStruc(asn_DEF_NR_VarMeasReport, rrc->MeasReport[j]); // TODO stop the periodical reporting timer or timer T321, whichever is running, // and reset the associated information (e.g. timeToTrigger) for this measId } @@ -1151,11 +1149,53 @@ static void handle_measobj_addmod(rrcPerNB_t *rrc, struct NR_MeasObjectToAddModL } } +static void handle_reportconfig_remove(rrcPerNB_t *rrc, struct NR_ReportConfigToRemoveList *remove_list) +{ + for (int i = 0; i < remove_list->list.count; i++) { + NR_ReportConfigId_t id = *remove_list->list.array[i]; + // remove the entry with the matching reportConfigId from the reportConfigList + asn1cFreeStruc(asn_DEF_NR_ReportConfigToAddMod, rrc->ReportConfig[id]); + for (int j = 0; j < MAX_MEAS_ID; j++) { + if (rrc->MeasId[j] && rrc->MeasId[j]->reportConfigId == id) { + // remove all measId associated with the reportConfigId from the measIdList + asn1cFreeStruc(asn_DEF_NR_MeasIdToAddMod, rrc->MeasId[j]); + // remove the measurement reporting entry for this measId if included + asn1cFreeStruc(asn_DEF_NR_VarMeasReport, rrc->MeasReport[j]); + // TODO stop the periodical reporting timer or timer T321, whichever one is running + // and reset the associated information (e.g. timeToTrigger) for this measId + } + } + } +} + +static void handle_reportconfig_addmod(rrcPerNB_t *rrc, struct NR_ReportConfigToAddModList *addmod_list) +{ + for (int i = 0; i < addmod_list->list.count; i++) { + NR_ReportConfigToAddMod_t *rep = addmod_list->list.array[i]; + if (rep->reportConfig.present != NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR) { + LOG_E(NR_RRC, "Cannot handle reportConfig type other than NR\n"); + continue; + } + NR_ReportConfigId_t id = rep->reportConfigId; + if (rrc->ReportConfig[id]) { + for (int j = 0; j < MAX_MEAS_ID; j++) { + // for each measId associated with this reportConfigId included in the measIdList + if (rrc->MeasId[j] && rrc->MeasId[j]->reportConfigId == id) { + // remove the measurement reporting entry for this measId if included + asn1cFreeStruc(asn_DEF_NR_VarMeasReport, rrc->MeasReport[j]); + // TODO stop the periodical reporting timer or timer T321, whichever one is running + // and reset the associated information (e.g. timeToTrigger) for this measId + } + } + } + UPDATE_IE(rrc->ReportConfig[id], addmod_list->list.array[i], NR_ReportConfigToAddMod_t); + } +} + static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig) { int i; long ind; - NR_ReportConfigToAddMod_t *reportConfig = NULL; if (measConfig->measObjectToRemoveList) handle_measobj_remove(rrc, measConfig->measObjectToRemoveList); @@ -1163,32 +1203,11 @@ static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const if (measConfig->measObjectToAddModList) handle_measobj_addmod(rrc, measConfig->measObjectToAddModList); - 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->reportConfigToRemoveList) + handle_reportconfig_remove(rrc, measConfig->reportConfigToRemoveList); - 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->reportConfigToAddModList) + handle_reportconfig_addmod(rrc, measConfig->reportConfigToAddModList); if (measConfig->measIdToRemoveList != NULL) { for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) { diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 4ce65ef036..874bd76635 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -56,6 +56,8 @@ #include "NR_UE-NR-Capability.h" #include "NR_SL-PreconfigurationNR-r16.h" #include "NR_MasterInformationBlockSidelink.h" +#include "NR_MeasurementReport.h" +#include "NR_VarMeasReport.h" #include "RRC/NR/nr_rrc_common.h" #include "as_message.h" @@ -177,6 +179,7 @@ typedef struct rrcPerNB { NR_ReportConfigToAddMod_t *ReportConfig[MAX_MEAS_CONFIG]; NR_QuantityConfig_t *QuantityConfig; NR_MeasIdToAddMod_t *MeasId[MAX_MEAS_ID]; + NR_VarMeasReport_t *MeasReport[MAX_MEAS_ID]; NR_MeasGapConfig_t *measGapConfig; NR_UE_RRC_SI_INFO SInfo; NR_RSRP_Range_t s_measure; From e4b7d9fd58cda4221f9258624e6a33a0e91d0721 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 9 Feb 2024 15:09:12 +0100 Subject: [PATCH 05/35] improvements in handling quantityConfig --- openair2/RRC/NR_UE/rrc_UE.c | 36 +++++++++++++++++++++++++---------- openair2/RRC/NR_UE/rrc_defs.h | 3 ++- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 32f8a7dfbe..d88f95a594 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1192,6 +1192,29 @@ static void handle_reportconfig_addmod(rrcPerNB_t *rrc, struct NR_ReportConfigTo } } +static void handle_quantityconfig(rrcPerNB_t *rrc, NR_QuantityConfig_t *quantityConfig) +{ + if (quantityConfig->quantityConfigNR_List) { + for (int i = 0; i < quantityConfig->quantityConfigNR_List->list.count; i++) { + NR_QuantityConfigNR_t *quantityNR = quantityConfig->quantityConfigNR_List->list.array[i]; + if (!rrc->QuantityConfig[i]) + rrc->QuantityConfig[i] = calloc(1, sizeof(*rrc->QuantityConfig[i])); + rrc->QuantityConfig[i]->quantityConfigCell = quantityNR->quantityConfigCell; + if (quantityNR->quantityConfigRS_Index) + UPDATE_IE(rrc->QuantityConfig[i]->quantityConfigRS_Index, quantityNR->quantityConfigRS_Index, struct NR_QuantityConfigRS); + } + } + for (int j = 0; j < MAX_MEAS_ID; j++) { + // for each measId included in the measIdList + if (rrc->MeasId[j]) { + // remove the measurement reporting entry for this measId if included + asn1cFreeStruc(asn_DEF_NR_VarMeasReport, rrc->MeasReport[j]); + // TODO stop the periodical reporting timer or timer T321, whichever one is running + // and reset the associated information (e.g. timeToTrigger) for this measId + } + } +} + static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig) { int i; @@ -1209,6 +1232,9 @@ static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const if (measConfig->reportConfigToAddModList) handle_reportconfig_addmod(rrc, measConfig->reportConfigToAddModList); + if (measConfig->quantityConfig) + handle_quantityconfig(rrc, measConfig->quantityConfig); + if (measConfig->measIdToRemoveList != NULL) { for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) { ind = *measConfig->measIdToRemoveList->list.array[i]; @@ -1230,16 +1256,6 @@ static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const } } - 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)); diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 874bd76635..4e444bc800 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -67,6 +67,7 @@ #define MAX_MEAS_OBJ 7 #define MAX_MEAS_CONFIG 7 #define MAX_MEAS_ID 7 +#define MAX_QUANTITY_CONFIG 2 typedef uint32_t channel_t; @@ -177,7 +178,7 @@ typedef enum { RB_NOT_PRESENT, RB_ESTABLISHED, RB_SUSPENDED } NR_RB_status_t; typedef struct rrcPerNB { NR_MeasObjectToAddMod_t *MeasObj[MAX_MEAS_OBJ]; NR_ReportConfigToAddMod_t *ReportConfig[MAX_MEAS_CONFIG]; - NR_QuantityConfig_t *QuantityConfig; + NR_QuantityConfigNR_t *QuantityConfig[MAX_QUANTITY_CONFIG]; NR_MeasIdToAddMod_t *MeasId[MAX_MEAS_ID]; NR_VarMeasReport_t *MeasReport[MAX_MEAS_ID]; NR_MeasGapConfig_t *measGapConfig; From 23f65d8ab67c6518abb496258690c0835831bc5c Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 12 Feb 2024 00:39:45 +0100 Subject: [PATCH 06/35] improvements in handling measurememt identity addition, modification and removal --- openair2/RRC/NR_UE/rrc_UE.c | 133 +++++++++++++++++++++------------- openair2/RRC/NR_UE/rrc_defs.h | 1 + 2 files changed, 82 insertions(+), 52 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index d88f95a594..751c837296 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -149,7 +149,7 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, OCTET_STRING_t *masterCellGroup, long *fullConfig); -static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig); +static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig, NR_UE_Timers_Constants_t *timers); static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_index, @@ -217,8 +217,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, } if (ie->measConfig != NULL) { LOG_I(NR_RRC, "Measurement Configuration is present\n"); - // if some element need to be updated - nr_rrc_ue_process_measConfig(rrcNB, ie->measConfig); + nr_rrc_ue_process_measConfig(rrcNB, ie->measConfig, &rrc->timers_and_constants); } if (ie->lateNonCriticalExtension != NULL) { // unuse now @@ -1045,7 +1044,16 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, securityModeCommand->criticalExtensions.present); } -static void handle_measobj_remove(rrcPerNB_t *rrc, struct NR_MeasObjectToRemoveList *remove_list) +static void handle_meas_reporting_remove(rrcPerNB_t *rrc, int id, NR_UE_Timers_Constants_t *timers) +{ + // remove the measurement reporting entry for this measId if included + asn1cFreeStruc(asn_DEF_NR_VarMeasReport, rrc->MeasReport[id]); + // TODO stop the periodical reporting timer or timer T321, whichever is running, + // and reset the associated information (e.g. timeToTrigger) for this measId + nr_timer_stop(&timers->T321); +} + +static void handle_measobj_remove(rrcPerNB_t *rrc, struct NR_MeasObjectToRemoveList *remove_list, NR_UE_Timers_Constants_t *timers) { // section 5.5.2.4 in 38.331 for (int i = 0; i < remove_list->list.count; i++) { @@ -1059,10 +1067,7 @@ static void handle_measobj_remove(rrcPerNB_t *rrc, struct NR_MeasObjectToRemoveL for (int j = 0; j < MAX_MEAS_ID; j++) { if (rrc->MeasId[j] && rrc->MeasId[j]->measObjectId == id) { asn1cFreeStruc(asn_DEF_NR_MeasIdToAddMod, rrc->MeasId[j]); - // remove the measurement reporting entry for this measId if included - asn1cFreeStruc(asn_DEF_NR_VarMeasReport, rrc->MeasReport[j]); - // TODO stop the periodical reporting timer or timer T321, whichever is running, - // and reset the associated information (e.g. timeToTrigger) for this measId + handle_meas_reporting_remove(rrc, j, timers); } } } @@ -1149,7 +1154,9 @@ static void handle_measobj_addmod(rrcPerNB_t *rrc, struct NR_MeasObjectToAddModL } } -static void handle_reportconfig_remove(rrcPerNB_t *rrc, struct NR_ReportConfigToRemoveList *remove_list) +static void handle_reportconfig_remove(rrcPerNB_t *rrc, + struct NR_ReportConfigToRemoveList *remove_list, + NR_UE_Timers_Constants_t *timers) { for (int i = 0; i < remove_list->list.count; i++) { NR_ReportConfigId_t id = *remove_list->list.array[i]; @@ -1159,16 +1166,15 @@ static void handle_reportconfig_remove(rrcPerNB_t *rrc, struct NR_ReportConfigTo if (rrc->MeasId[j] && rrc->MeasId[j]->reportConfigId == id) { // remove all measId associated with the reportConfigId from the measIdList asn1cFreeStruc(asn_DEF_NR_MeasIdToAddMod, rrc->MeasId[j]); - // remove the measurement reporting entry for this measId if included - asn1cFreeStruc(asn_DEF_NR_VarMeasReport, rrc->MeasReport[j]); - // TODO stop the periodical reporting timer or timer T321, whichever one is running - // and reset the associated information (e.g. timeToTrigger) for this measId + handle_meas_reporting_remove(rrc, j, timers); } } } } -static void handle_reportconfig_addmod(rrcPerNB_t *rrc, struct NR_ReportConfigToAddModList *addmod_list) +static void handle_reportconfig_addmod(rrcPerNB_t *rrc, + struct NR_ReportConfigToAddModList *addmod_list, + NR_UE_Timers_Constants_t *timers) { for (int i = 0; i < addmod_list->list.count; i++) { NR_ReportConfigToAddMod_t *rep = addmod_list->list.array[i]; @@ -1180,19 +1186,15 @@ static void handle_reportconfig_addmod(rrcPerNB_t *rrc, struct NR_ReportConfigTo if (rrc->ReportConfig[id]) { for (int j = 0; j < MAX_MEAS_ID; j++) { // for each measId associated with this reportConfigId included in the measIdList - if (rrc->MeasId[j] && rrc->MeasId[j]->reportConfigId == id) { - // remove the measurement reporting entry for this measId if included - asn1cFreeStruc(asn_DEF_NR_VarMeasReport, rrc->MeasReport[j]); - // TODO stop the periodical reporting timer or timer T321, whichever one is running - // and reset the associated information (e.g. timeToTrigger) for this measId - } + if (rrc->MeasId[j] && rrc->MeasId[j]->reportConfigId == id) + handle_meas_reporting_remove(rrc, j, timers); } } UPDATE_IE(rrc->ReportConfig[id], addmod_list->list.array[i], NR_ReportConfigToAddMod_t); } } -static void handle_quantityconfig(rrcPerNB_t *rrc, NR_QuantityConfig_t *quantityConfig) +static void handle_quantityconfig(rrcPerNB_t *rrc, NR_QuantityConfig_t *quantityConfig, NR_UE_Timers_Constants_t *timers) { if (quantityConfig->quantityConfigNR_List) { for (int i = 0; i < quantityConfig->quantityConfigNR_List->list.count; i++) { @@ -1206,55 +1208,82 @@ static void handle_quantityconfig(rrcPerNB_t *rrc, NR_QuantityConfig_t *quantity } for (int j = 0; j < MAX_MEAS_ID; j++) { // for each measId included in the measIdList - if (rrc->MeasId[j]) { - // remove the measurement reporting entry for this measId if included - asn1cFreeStruc(asn_DEF_NR_VarMeasReport, rrc->MeasReport[j]); - // TODO stop the periodical reporting timer or timer T321, whichever one is running - // and reset the associated information (e.g. timeToTrigger) for this measId + if (rrc->MeasId[j]) + handle_meas_reporting_remove(rrc, j, timers); + } +} + +static void handle_measid_remove(rrcPerNB_t *rrc, struct NR_MeasIdToRemoveList *remove_list, NR_UE_Timers_Constants_t *timers) +{ + for (int i = 0; i < remove_list->list.count; i++) { + NR_MeasId_t id = *remove_list->list.array[i]; + if (rrc->MeasId[id]) { + asn1cFreeStruc(asn_DEF_NR_MeasIdToAddMod, rrc->MeasId[id]); + handle_meas_reporting_remove(rrc, id, timers); } } } -static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig) +static void handle_measid_addmod(rrcPerNB_t *rrc, struct NR_MeasIdToAddModList *addmod_list, NR_UE_Timers_Constants_t *timers) { - int i; - long ind; + for (int i = 0; i < addmod_list->list.count; i++) { + NR_MeasId_t id = addmod_list->list.array[i]->measId; + NR_ReportConfigId_t reportId = addmod_list->list.array[i]->reportConfigId; + NR_MeasObjectId_t measObjectId = addmod_list->list.array[i]->measObjectId; + UPDATE_IE(rrc->MeasId[id], addmod_list->list.array[i], NR_MeasIdToAddMod_t); + handle_meas_reporting_remove(rrc, id, timers); + if (rrc->ReportConfig[reportId]) { + NR_ReportConfigToAddMod_t *report = rrc->ReportConfig[reportId]; + AssertFatal(report->reportConfig.present == NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR, + "Only NR config report is supported\n"); + NR_ReportConfigNR_t *reportNR = report->reportConfig.choice.reportConfigNR; + // if the reportType is set to reportCGI in the reportConfig associated with this measId + if (reportNR->reportType.present == NR_ReportConfigNR__reportType_PR_reportCGI) { + if (rrc->MeasObj[measObjectId]) { + if (rrc->MeasObj[measObjectId]->measObject.present == NR_MeasObjectToAddMod__measObject_PR_measObjectNR) { + NR_MeasObjectNR_t *obj_nr = rrc->MeasObj[measObjectId]->measObject.choice.measObjectNR; + NR_ARFCN_ValueNR_t freq = 0; + if (obj_nr->ssbFrequency) + freq = *obj_nr->ssbFrequency; + else if (obj_nr->refFreqCSI_RS) + freq = *obj_nr->refFreqCSI_RS; + AssertFatal(freq > 0, "Invalid ARFCN frequency for this measurement object\n"); + if (freq > 2016666) + nr_timer_setup(&timers->T321, 16000, 10); // 16 seconds for FR2 + else + nr_timer_setup(&timers->T321, 2000, 10); // 2 seconds for FR1 + } + else // EUTRA + nr_timer_setup(&timers->T321, 1000, 10); // 1 second for EUTRA + nr_timer_start(&timers->T321); + } + } + } + } +} +static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig, NR_UE_Timers_Constants_t *timers) +{ if (measConfig->measObjectToRemoveList) - handle_measobj_remove(rrc, measConfig->measObjectToRemoveList); + handle_measobj_remove(rrc, measConfig->measObjectToRemoveList, timers); if (measConfig->measObjectToAddModList) handle_measobj_addmod(rrc, measConfig->measObjectToAddModList); if (measConfig->reportConfigToRemoveList) - handle_reportconfig_remove(rrc, measConfig->reportConfigToRemoveList); + handle_reportconfig_remove(rrc, measConfig->reportConfigToRemoveList, timers); if (measConfig->reportConfigToAddModList) - handle_reportconfig_addmod(rrc, measConfig->reportConfigToAddModList); + handle_reportconfig_addmod(rrc, measConfig->reportConfigToAddModList, timers); if (measConfig->quantityConfig) - handle_quantityconfig(rrc, measConfig->quantityConfig); + handle_quantityconfig(rrc, measConfig->quantityConfig, timers); - 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->measIdToRemoveList) + handle_measid_remove(rrc, measConfig->measIdToRemoveList, timers); - 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->measIdToAddModList) + handle_measid_addmod(rrc, measConfig->measIdToAddModList, timers); if (measConfig->measGapConfig != NULL) { if (rrc->measGapConfig) { diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 4e444bc800..fe1ff6147c 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -158,6 +158,7 @@ typedef struct NR_UE_Timers_Constants_s { NR_timer_t T311; NR_timer_t T319; NR_timer_t T320; + NR_timer_t T321; NR_timer_t T325; NR_timer_t T390; // counters From a0224e8faf064e45f06ae5a32c8b35bde5f3ca08 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 12 Feb 2024 00:51:11 +0100 Subject: [PATCH 07/35] assert on measurement gaps --- openair2/RRC/NR_UE/rrc_UE.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 751c837296..68d5ba3791 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1285,13 +1285,8 @@ static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const if (measConfig->measIdToAddModList) handle_measid_addmod(rrc, measConfig->measIdToAddModList, timers); - if (measConfig->measGapConfig != NULL) { - if (rrc->measGapConfig) { - memcpy(rrc->measGapConfig, (char *)measConfig->measGapConfig, sizeof(NR_MeasGapConfig_t)); - } else { - rrc->measGapConfig = measConfig->measGapConfig; - } - } + AssertFatal(!measConfig->measGapConfig, "Measurement gaps not yet supported\n"); + AssertFatal(!measConfig->measGapSharingConfig, "Measurement gaps not yet supported\n"); if (measConfig->s_MeasureConfig) { if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_ssb_RSRP) { From 77d749ba8790bc7ce992e03e96c32e6b89524e05 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 21 Feb 2024 11:47:02 +0100 Subject: [PATCH 08/35] improve function that map ro to ssb in the UE: make dynamic smaller memory allocation than array[max][max][.... Saves about 100MB of memory and avoid real time glitch of milli seconds of memset(110MB) --- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 2 +- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 6 +- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 14 +- .../NR_MAC_UE/nr_ue_dci_configuration.c | 12 +- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 400 +++++++----------- 5 files changed, 171 insertions(+), 263 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index dbdc437af8..b131b726da 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -430,7 +430,7 @@ typedef struct prach_occasion_info { // PRACH occasion slot details // A PRACH occasion slot is a series of PRACH occasions in time (symbols) and frequency typedef struct prach_occasion_slot { - prach_occasion_info_t prach_occasion[MAX_TDM][MAX_FDM]; // Starting symbol of each PRACH occasions in a slot + prach_occasion_info_t *prach_occasion; // Starting symbol of each PRACH occasions in a slot uint8_t nb_of_prach_occasion_in_time; uint8_t nb_of_prach_occasion_in_freq; } prach_occasion_slot_t; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index e811948bc2..f3c66f980b 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -423,15 +423,15 @@ typedef struct prach_association_pattern { // SSB details typedef struct ssb_info { - bool transmitted; // True if the SSB index is transmitted according to the SSB positions map configuration prach_occasion_info_t *mapped_ro[MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN]; // List of mapped RACH Occasions to this SSB index uint32_t nb_mapped_ro; // Total number of mapped ROs to this SSB index } ssb_info_t; // List of all the possible SSBs and their details typedef struct ssb_list_info { - ssb_info_t tx_ssb[MAX_NB_SSB]; - uint8_t nb_tx_ssb; + ssb_info_t *tx_ssb; + int nb_tx_ssb; + int nb_ssb_per_index[MAX_NB_SSB]; } ssb_list_info_t; typedef struct nr_lcordered_info_s { diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index c7e43e50f8..84a2fbdd7d 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -72,10 +72,8 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements)); memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment)); - for (int i = 0; i < MAX_NUM_BWP_UE; i++) { - memset(&mac->ssb_list[i], 0, sizeof(mac->ssb_list[i])); - memset(&mac->prach_assoc_pattern[i], 0, sizeof(mac->prach_assoc_pattern[i])); - } + memset(mac->ssb_list, 0, sizeof(mac->ssb_list)); + memset(mac->prach_assoc_pattern, 0, sizeof(mac->prach_assoc_pattern)); for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) { mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value @@ -189,6 +187,14 @@ 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 diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 991328b18c..3744e2fa39 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -444,18 +444,12 @@ bool monitior_dci_for_other_SI(NR_UE_MAC_INST_t *mac, for (int i = 0; i < duration; i++) { if (((frame * slots_per_frame + slot - offset - i) % period) == 0) { int N = mac->ssb_list[bwp_id].nb_tx_ssb; - int K = 0; // k_th transmitted SSB - for (int i = 0; i < mac->mib_ssb; i++) { - if(mac->ssb_list[bwp_id].tx_ssb[i].transmitted) - K++; - } + int K = mac->ssb_list->nb_ssb_per_index[mac->mib_ssb]; + // numbering current frame and slot in terms of monitoring occasions in window int current_monitor_occasion = ((abs_slot - mac->si_window_start) % period) + (duration * (abs_slot - mac->si_window_start) / period); - if (current_monitor_occasion % N == K) - return true; - else - return false; + return current_monitor_occasion % N == K; } } } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 02b4d38453..3b1f2ee876 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1697,19 +1697,19 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) prach_occasion_slot_t *slot_map = &prach_conf_period_list->prach_occasion_slot_map[frame_idx][slot]; slot_map->nb_of_prach_occasion_in_time = N_t_slot; slot_map->nb_of_prach_occasion_in_freq = nb_fdm; - + slot_map->prach_occasion = malloc(N_t_slot * nb_fdm * sizeof(*slot_map->prach_occasion)); + AssertFatal(slot_map->prach_occasion, "no memory available\n"); for (int n_prach_occ_in_time = 0; n_prach_occ_in_time < N_t_slot; n_prach_occ_in_time++) { uint8_t start_symbol = prach_conf_start_symbol + n_prach_occ_in_time * N_dur; LOG_D(NR_MAC,"PRACH Occ in time %d\n", n_prach_occ_in_time); for (int n_prach_occ_in_freq = 0; n_prach_occ_in_freq < nb_fdm; n_prach_occ_in_freq++) { - prach_occasion_info_t *prach_occasion_p = &slot_map->prach_occasion[n_prach_occ_in_time][n_prach_occ_in_freq]; - - prach_occasion_p->start_symbol = start_symbol; - prach_occasion_p->fdm = n_prach_occ_in_freq; - prach_occasion_p->frame = frame; - prach_occasion_p->slot = slot; - prach_occasion_p->format = format; + slot_map->prach_occasion[n_prach_occ_in_time * nb_fdm + n_prach_occ_in_freq] = + (prach_occasion_info_t){.start_symbol = start_symbol, + .fdm = n_prach_occ_in_freq, + .frame = frame, + .slot = slot, + .format = format}; prach_assoc_pattern->prach_conf_period_list[period_idx].nb_of_prach_occasion++; LOG_D(NR_MAC,"Adding a PRACH occasion: frame %u, slot-symbol %d-%d, occ_in_time-occ_in-freq %d-%d, nb ROs in conf period %d, for this slot: RO# in time %d, RO# in freq %d\n", @@ -1734,17 +1734,15 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac) fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; ssb_list->nb_tx_ssb = 0; - for(int ssb_index = 0; ssb_index < 64; ssb_index++) { + for (int ssb_index = 0; ssb_index < MAX_NB_SSB; ssb_index++) { uint32_t curr_mask = cfg->ssb_table.ssb_mask_list[ssb_index / 32].ssb_mask; // check if if current SSB is transmitted if ((curr_mask >> (31 - (ssb_index % 32))) & 0x01) { ssb_list->nb_tx_ssb++; - ssb_list->tx_ssb[ssb_index].transmitted = true; - LOG_D(NR_MAC,"SSB idx %d transmitted\n", ssb_index); + ssb_list->nb_ssb_per_index[ssb_index]=ssb_list->nb_tx_ssb; } - else - ssb_list->tx_ssb[ssb_index].transmitted = false; } + ssb_list->tx_ssb = calloc(ssb_list->nb_tx_ssb, sizeof(*ssb_list->tx_ssb)); } // Map the transmitted SSBs to the ROs and create the association pattern according to the config @@ -1755,49 +1753,18 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; - bool multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB - uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB - uint16_t required_nb_of_prach_occasion; // Nb of RACH occasions required to map all the SSBs - uint8_t required_nb_of_prach_conf_period; // Nb of PRACH configuration periods required to map all the SSBs + const struct { + // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB + bool multiple_ssb_per_ro; + // Nb of SSBs per RACH or RACHs per SSB + int ssb_rach_ratio; + } config[] = {{false, 0}, {false, 8}, {false, 4}, {false, 2}, {true, 1}, {true, 2}, {true, 4}, {true, 8}, {true, 16}}; + AssertFatal(ssb_perRACH_config <= NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen, + "Unsupported ssb_perRACH_config %d\n", + ssb_perRACH_config); + const bool multiple_ssb_per_ro = config[ssb_perRACH_config].multiple_ssb_per_ro; + const int ssb_rach_ratio = config[ssb_perRACH_config].ssb_rach_ratio; - // Determine the SSB to RACH mapping ratio - switch (ssb_perRACH_config){ - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: - multiple_ssb_per_ro = false; - ssb_rach_ratio = 8; - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth: - multiple_ssb_per_ro = false; - ssb_rach_ratio = 4; - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf: - multiple_ssb_per_ro = false; - ssb_rach_ratio = 2; - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one: - multiple_ssb_per_ro = true; - ssb_rach_ratio = 1; - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two: - multiple_ssb_per_ro = true; - ssb_rach_ratio = 2; - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four: - multiple_ssb_per_ro = true; - ssb_rach_ratio = 4; - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight: - multiple_ssb_per_ro = true; - ssb_rach_ratio = 8; - break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen: - multiple_ssb_per_ro = true; - ssb_rach_ratio = 16; - break; - default: - AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config); - break; - } LOG_D(NR_MAC,"SSB rach ratio %d, Multiple SSB per RO %d\n", ssb_rach_ratio, multiple_ssb_per_ro); const int bwp_id = mac->current_UL_BWP->bwp_id; @@ -1809,230 +1776,171 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) // (No PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule) // There is only one possible association period which can contain up to 16 PRACH configuration periods LOG_D(NR_MAC,"Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period\n"); - if (true == multiple_ssb_per_ro) { - required_nb_of_prach_occasion = ((ssb_list->nb_tx_ssb - 1) + ssb_rach_ratio) / ssb_rach_ratio; - } - else { - required_nb_of_prach_occasion = ssb_list->nb_tx_ssb * ssb_rach_ratio; - } + const int required_nb_of_prach_occasion = + multiple_ssb_per_ro ? ((ssb_list->nb_tx_ssb - 1) + ssb_rach_ratio) / ssb_rach_ratio : ssb_list->nb_tx_ssb * ssb_rach_ratio; prach_association_pattern_t *prach_assoc_pattern = &mac->prach_assoc_pattern[bwp_id]; - prach_association_period_t *prach_association_period_list = &prach_assoc_pattern->prach_association_period_list[0]; - AssertFatal(prach_assoc_pattern->prach_conf_period_list[0].nb_of_prach_occasion > 0, - "prach_assoc_pattern.prach_conf_period_list[0].nb_of_prach_occasion shouldn't be 0 (nb_tx_ssb %d, ssb_rach_ratio %d)\n", - ssb_list->nb_tx_ssb, ssb_rach_ratio); - required_nb_of_prach_conf_period = - ((required_nb_of_prach_occasion - 1) + prach_assoc_pattern->prach_conf_period_list[0].nb_of_prach_occasion) - / prach_assoc_pattern->prach_conf_period_list[0].nb_of_prach_occasion; + const prach_conf_period_t *prach_conf_period = &prach_assoc_pattern->prach_conf_period_list[0]; + AssertFatal(prach_conf_period->nb_of_prach_occasion > 0, + "prach_conf_period->nb_of_prach_occasion shouldn't be 0 (nb_tx_ssb %d, ssb_rach_ratio %d)\n", + ssb_list->nb_tx_ssb, + ssb_rach_ratio); + prach_association_period_t *prach_association_period = &prach_assoc_pattern->prach_association_period_list[0]; + const int required_nb_of_prach_conf_period = + ((required_nb_of_prach_occasion - 1) + prach_conf_period->nb_of_prach_occasion) / prach_conf_period->nb_of_prach_occasion; if (required_nb_of_prach_conf_period == 1) { - prach_association_period_list->nb_of_prach_conf_period = 1; + prach_association_period->nb_of_prach_conf_period = 1; } else if (required_nb_of_prach_conf_period == 2) { - prach_association_period_list->nb_of_prach_conf_period = 2; + prach_association_period->nb_of_prach_conf_period = 2; } else if (required_nb_of_prach_conf_period <= 4) { - prach_association_period_list->nb_of_prach_conf_period = 4; + prach_association_period->nb_of_prach_conf_period = 4; } else if (required_nb_of_prach_conf_period <= 8) { - prach_association_period_list->nb_of_prach_conf_period = 8; + prach_association_period->nb_of_prach_conf_period = 8; } else if (required_nb_of_prach_conf_period <= 16) { - prach_association_period_list->nb_of_prach_conf_period = 16; + prach_association_period->nb_of_prach_conf_period = 16; } else { AssertFatal(1 == 0, "Invalid number of PRACH config periods within an association period %d\n", required_nb_of_prach_conf_period); } prach_assoc_pattern->nb_of_assoc_period = 1; // WIP: only one possible association period - prach_association_period_list->nb_of_frame = prach_association_period_list->nb_of_prach_conf_period * prach_assoc_pattern->prach_conf_period_list[0].nb_of_frame;; - prach_assoc_pattern->nb_of_frame = prach_association_period_list->nb_of_frame; + prach_association_period->nb_of_frame = prach_association_period->nb_of_prach_conf_period * prach_conf_period->nb_of_frame; + prach_assoc_pattern->nb_of_frame = prach_association_period->nb_of_frame; - LOG_D(NR_MAC,"Assoc period %d, Nb of frames in assoc period %d\n", - prach_association_period_list->nb_of_prach_conf_period, - prach_association_period_list->nb_of_frame); + LOG_D(NR_MAC, + "Assoc period %d, Nb of frames in assoc period %d\n", + prach_association_period->nb_of_prach_conf_period, + prach_association_period->nb_of_frame); - // Proceed to the SSB to RO mapping - uint8_t ssb_idx = 0; - uint8_t prach_configuration_period_idx; // PRACH Configuration period index within the association pattern - prach_conf_period_t *prach_conf_period_p; + // Set the starting PRACH Configuration period index in the association_pattern map for this particular association period + int prach_configuration_period_idx = + 0; // WIP: only one possible association period so the starting PRACH configuration period is automatically 0 // Map all the association periods within the association pattern period LOG_D(NR_MAC,"Proceed to the SSB to RO mapping\n"); - for (int association_period_idx = 0; association_period_idx < prach_assoc_pattern->nb_of_assoc_period; association_period_idx++) { - uint8_t frame=0; - uint8_t slot=0; - uint8_t ro_in_time=0; - uint8_t ro_in_freq=0; - - // Set the starting PRACH Configuration period index in the association_pattern map for this particular association period - prach_configuration_period_idx = 0; // WIP: only one possible association period so the starting PRACH configuration period is automatically 0 - - // Check if we need to map multiple SSBs per RO or multiple ROs per SSB - if (true == multiple_ssb_per_ro) { - // -------------------- - // -------------------- - // Multiple SSBs per RO - // -------------------- - // -------------------- - + // Check if we need to map multiple SSBs per RO or multiple ROs per SSB + if (multiple_ssb_per_ro) { + const prach_association_period_t *end = + prach_assoc_pattern->prach_association_period_list + prach_assoc_pattern->nb_of_assoc_period; + for (prach_association_period_t *prach_period = prach_assoc_pattern->prach_association_period_list; prach_period < end; + prach_period++) { + // Set the starting PRACH Configuration period index in the association_pattern map for this particular association period + // WIP: only one possible association period so the starting PRACH configuration period is automatically 0 // WIP: For the moment, only map each SSB idx once per association period if configuration is multiple SSBs per RO // this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule - ssb_idx = 0; - - // Go through the list of PRACH config periods within this association period - prach_association_period_list = &prach_assoc_pattern->prach_association_period_list[association_period_idx]; - for (int n_prach_conf=0; n_prach_conf < prach_association_period_list->nb_of_prach_conf_period; n_prach_conf++, prach_configuration_period_idx++) { + int ssb_idx = 0; + bool done = false; + for (int i = 0; i < prach_period->nb_of_prach_conf_period && !done; i++, prach_configuration_period_idx++) { + prach_period->prach_conf_period_list[i] = &prach_assoc_pattern->prach_conf_period_list[prach_configuration_period_idx]; + prach_conf_period_t *prach_conf = prach_period->prach_conf_period_list[i]; // Build the association period with its association PRACH Configuration indexes - prach_conf_period_p = &prach_assoc_pattern->prach_conf_period_list[prach_configuration_period_idx]; - prach_association_period_list->prach_conf_period_list[n_prach_conf] = prach_conf_period_p; - // Go through all the ROs within the PRACH config period - for (frame=0; framenb_of_frame; frame++) { - for (slot=0; slotnb_of_slot; slot++) { - for (ro_in_time=0; ro_in_timeprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_time; ro_in_time++) { - for (ro_in_freq=0; ro_in_freqprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq; ro_in_freq++) { - prach_occasion_info_t *ro_p = &prach_conf_period_p->prach_occasion_slot_map[frame][slot].prach_occasion[ro_in_time][ro_in_freq]; - + for (int frame = 0; frame < prach_conf->nb_of_frame && !done; frame++) { + for (int slot = 0; slot < prach_conf->nb_of_slot && !done; slot++) { + prach_occasion_slot_t *slot_map = &prach_conf->prach_occasion_slot_map[frame][slot]; + for (int ro_in_time = 0; ro_in_time < slot_map->nb_of_prach_occasion_in_time && !done; ro_in_time++) { + for (int ro_in_freq = 0; ro_in_freq < slot_map->nb_of_prach_occasion_in_freq && !done; ro_in_freq++) { + prach_occasion_info_t *ro_p = + slot_map->prach_occasion + ro_in_time * slot_map->nb_of_prach_occasion_in_freq + ro_in_freq; // Go through the list of transmitted SSBs and map the required amount of SSBs to this RO // WIP: For the moment, only map each SSB idx once per association period if configuration is multiple SSBs per RO // this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule - for (; ssb_idxnb_tx_ssb; ssb_idx++) { + ssb_info_t *tx_ssb = ssb_list->tx_ssb + ssb_idx; // Map only the transmitted ssb_idx - if (true == ssb_list->tx_ssb[ssb_idx].transmitted) { - ro_p->mapped_ssb_idx[ro_p->nb_mapped_ssb] = ssb_idx; - ro_p->nb_mapped_ssb++; - ssb_list->tx_ssb[ssb_idx].mapped_ro[ssb_list->tx_ssb[ssb_idx].nb_mapped_ro] = ro_p; - ssb_list->tx_ssb[ssb_idx].nb_mapped_ro++; - AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > ssb_list->tx_ssb[ssb_idx].nb_mapped_ro, - "Too many mapped ROs (%d) to a single SSB\n", - ssb_list->tx_ssb[ssb_idx].nb_mapped_ro); - - LOG_D(NR_MAC, "Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", - ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, - prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq); - LOG_D(NR_MAC, "Nb mapped ROs for this ssb idx: in the association period only %u\n", - ssb_list->tx_ssb[ssb_idx].nb_mapped_ro); - - // If all the required SSBs are mapped to this RO, exit the loop of SSBs - if (ro_p->nb_mapped_ssb == ssb_rach_ratio) { + ro_p->mapped_ssb_idx[ro_p->nb_mapped_ssb] = ssb_idx; + ro_p->nb_mapped_ssb++; + AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > tx_ssb->nb_mapped_ro + 1, + "Too many mapped ROs (%d) to a single SSB\n", + tx_ssb->nb_mapped_ro); + tx_ssb->mapped_ro[tx_ssb->nb_mapped_ro] = ro_p; + tx_ssb->nb_mapped_ro++; + LOG_D(NR_MAC, + "Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n" + "Nb mapped ROs for this ssb idx: in the association period only %u\n", + ssb_idx, + ro_p->slot, + ro_p->start_symbol, + slot, + ro_in_time, + ro_in_freq, + slot_map->nb_of_prach_occasion_in_freq, + tx_ssb->nb_mapped_ro); + // If all the required SSBs are mapped to this RO, exit the loop of SSBs + if (ro_p->nb_mapped_ssb == ssb_rach_ratio) { ssb_idx++; break; } - } // if ssb_idx is transmitted - } // for ssb_idx - - // Exit the loop of ROs if there is no more SSB to map - if (MAX_NB_SSB == ssb_idx) break; - } // for ro_in_freq - - // Exit the loop of ROs if there is no more SSB to map - if (MAX_NB_SSB == ssb_idx) break; - } // for ro_in_time - - // Exit the loop of slots if there is no more SSB to map - if (MAX_NB_SSB == ssb_idx) break; - } // for slot - - // Exit the loop frames if there is no more SSB to map - if (MAX_NB_SSB == ssb_idx) break; - } // for frame - - // Exit the loop of PRACH configurations if there is no more SSB to map - if (MAX_NB_SSB == ssb_idx) break; - } // for n_prach_conf - - // WIP: note that there is no re-mapping of the SSBs within the association period since there is no invalid ROs in the PRACH config periods that would create this situation - - } // if multiple_ssbs_per_ro - - else { - // -------------------- - // -------------------- - // Multiple ROs per SSB - // -------------------- - // -------------------- - + } + done = MAX_NB_SSB == ssb_idx; + } + } + } + } + } + } + } else { + prach_association_period_t *end = prach_assoc_pattern->prach_association_period_list + prach_assoc_pattern->nb_of_assoc_period; + for (prach_association_period_t *prach_period = prach_assoc_pattern->prach_association_period_list; prach_period < end; + prach_period++) { // Go through the list of transmitted SSBs - for (ssb_idx=0; ssb_idxnb_tx_ssb; ssb_idx++) { + ssb_info_t *tx_ssb = ssb_list->tx_ssb + ssb_idx; uint8_t nb_mapped_ro_in_association_period=0; // Reset the nb of mapped ROs for the new SSB index - LOG_D(NR_MAC,"Checking ssb_idx %d => %d\n", - ssb_idx, ssb_list->tx_ssb[ssb_idx].transmitted); + bool done = false; + // Map all the required ROs to this SSB + // Go through the list of PRACH config periods within this association period + for (int i = 0; i < prach_period->nb_of_prach_conf_period && !done; i++, prach_configuration_period_idx++) { + // Build the association period with its association PRACH Configuration indexes + prach_period->prach_conf_period_list[i] = &prach_assoc_pattern->prach_conf_period_list[prach_configuration_period_idx]; + prach_conf_period_t *prach_conf = prach_period->prach_conf_period_list[i]; + for (int frame = 0; frame < prach_conf->nb_of_frame && !done; frame++) { + for (int slot = 0; slot < prach_conf->nb_of_slot && !done; slot++) { + prach_occasion_slot_t *slot_map = &prach_conf->prach_occasion_slot_map[frame][slot]; + for (int ro_in_time = 0; ro_in_time < slot_map->nb_of_prach_occasion_in_time && !done; ro_in_time++) { + for (int ro_in_freq = 0; ro_in_freq < slot_map->nb_of_prach_occasion_in_freq && !done; ro_in_freq++) { + prach_occasion_info_t *ro_p = + slot_map->prach_occasion + ro_in_time * slot_map->nb_of_prach_occasion_in_freq + ro_in_freq; + ro_p->mapped_ssb_idx[0] = ssb_idx; + ro_p->nb_mapped_ssb = 1; + AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > tx_ssb->nb_mapped_ro + 1, + "Too many mapped ROs (%d) to a single SSB\n", + tx_ssb->nb_mapped_ro); + tx_ssb->mapped_ro[tx_ssb->nb_mapped_ro] = ro_p; + tx_ssb->nb_mapped_ro++; + nb_mapped_ro_in_association_period++; + done = nb_mapped_ro_in_association_period == ssb_rach_ratio; - // Map only the transmitted ssb_idx - if (true == ssb_list->tx_ssb[ssb_idx].transmitted) { - - // Map all the required ROs to this SSB - // Go through the list of PRACH config periods within this association period - for (int n_prach_conf = 0; n_prach_confprach_association_period_list[association_period_idx].nb_of_prach_conf_period; n_prach_conf++, prach_configuration_period_idx++) { - - // Build the association period with its association PRACH Configuration indexes - prach_conf_period_p = &prach_assoc_pattern->prach_conf_period_list[prach_configuration_period_idx]; - prach_assoc_pattern->prach_association_period_list[association_period_idx].prach_conf_period_list[n_prach_conf] = prach_conf_period_p; - - for (; framenb_of_frame; frame++) { - for (; slotnb_of_slot; slot++) { - for (; ro_in_timeprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_time; ro_in_time++) { - for (; ro_in_freqprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq; ro_in_freq++) { - prach_occasion_info_t *ro_p = &prach_conf_period_p->prach_occasion_slot_map[frame][slot].prach_occasion[ro_in_time][ro_in_freq]; - - ro_p->mapped_ssb_idx[0] = ssb_idx; - ro_p->nb_mapped_ssb = 1; - ssb_list->tx_ssb[ssb_idx].mapped_ro[ssb_list->tx_ssb[ssb_idx].nb_mapped_ro] = ro_p; - ssb_list->tx_ssb[ssb_idx].nb_mapped_ro++; - AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > ssb_list->tx_ssb[ssb_idx].nb_mapped_ro, - "Too many mapped ROs (%d) to a single SSB\n", - ssb_list->tx_ssb[ssb_idx].nb_mapped_ro); - nb_mapped_ro_in_association_period++; - - LOG_D(NR_MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", - ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, - prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq); - LOG_D(NR_MAC, "Nb mapped ROs for this ssb idx: in the association period only %u / total %u\n", - ssb_list->tx_ssb[ssb_idx].nb_mapped_ro, nb_mapped_ro_in_association_period); - - // Exit the loop if this SSB has been mapped to all the required ROs - // WIP: Assuming that ssb_rach_ratio equals the maximum nb of times a given ssb_idx is mapped within an association period: - // this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule - if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { - ro_in_freq++; - break; - } - } // for ro_in_freq + LOG_D(NR_MAC, + "Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n" + "Nb mapped ROs for this ssb idx: in the association period only %u / total %u\n", + ssb_idx, + ro_p->slot, + ro_p->start_symbol, + slot, + ro_in_time, + ro_in_freq, + slot_map->nb_of_prach_occasion_in_freq, + tx_ssb->nb_mapped_ro, + nb_mapped_ro_in_association_period); // Exit the loop if this SSB has been mapped to all the required ROs - if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { - break; - } - else ro_in_freq = 0; // else go to the next time symbol in that slot and reset the freq index - } // for ro_in_time - - // Exit the loop if this SSB has been mapped to all the required ROs - if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { - break; + // WIP: Assuming that ssb_rach_ratio equals the maximum nb of times a given ssb_idx is mapped within an + // association period: + // this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule } - else ro_in_time = 0; // else go to the next slot in that PRACH config period and reset the symbol index - } // for slot - - // Exit the loop if this SSB has been mapped to all the required ROs - if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { - break; } - else slot = 0; // else go to the next frame in that PRACH config period and reset the slot index - } // for frame - - // Exit the loop if this SSB has been mapped to all the required ROs - if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { - break; } - else frame = 0; // else go to the next PRACH config period in that association period and reset the frame index - } // for n_prach_conf - - } // if ssb_idx is transmitted - } // for ssb_idx - } // else if multiple_ssbs_per_ro - - } // for association_period_index + } + } + } + } + } } // Returns a RACH occasion if any matches the SSB idx, the frame and the slot @@ -2076,10 +1984,10 @@ static int get_nr_prach_info_from_ssb_index(prach_association_pattern_t *prach_a for (int ro_in_time=0; ro_in_time < prach_occasion_slot_p->nb_of_prach_occasion_in_time; ro_in_time++) { for (int ro_in_freq=0; ro_in_freq < prach_occasion_slot_p->nb_of_prach_occasion_in_freq; ro_in_freq++) { - prach_occasion_info_t *prach_occasion_info_p = &prach_occasion_slot_p->prach_occasion[ro_in_time][ro_in_freq]; - - for (uint8_t ssb_nb=0; ssb_nbnb_mapped_ssb; ssb_nb++) { - if (prach_occasion_info_p->mapped_ssb_idx[ssb_nb] == ssb_idx) { + prach_occasion_info_t *ro_p = + prach_occasion_slot_p->prach_occasion + ro_in_time * prach_occasion_slot_p->nb_of_prach_occasion_in_freq + ro_in_freq; + for (uint8_t ssb_nb = 0; ssb_nb < ro_p->nb_mapped_ssb; ssb_nb++) { + if (ro_p->mapped_ssb_idx[ssb_nb] == ssb_idx) { nb_mapped_ssb++; } } @@ -2095,12 +2003,12 @@ static int get_nr_prach_info_from_ssb_index(prach_association_pattern_t *prach_a nb_mapped_ssb=0; for (int ro_in_time=0; ro_in_time < prach_occasion_slot_p->nb_of_prach_occasion_in_time; ro_in_time++) { for (int ro_in_freq=0; ro_in_freq < prach_occasion_slot_p->nb_of_prach_occasion_in_freq; ro_in_freq++) { - prach_occasion_info_t *prach_occasion_info_p = &prach_occasion_slot_p->prach_occasion[ro_in_time][ro_in_freq]; - - for (uint8_t ssb_nb=0; ssb_nbnb_mapped_ssb; ssb_nb++) { - if (prach_occasion_info_p->mapped_ssb_idx[ssb_nb] == ssb_idx) { + prach_occasion_info_t *ro_p = + prach_occasion_slot_p->prach_occasion + ro_in_time * prach_occasion_slot_p->nb_of_prach_occasion_in_freq + ro_in_freq; + for (uint8_t ssb_nb = 0; ssb_nb < ro_p->nb_mapped_ssb; ssb_nb++) { + if (ro_p->mapped_ssb_idx[ssb_nb] == ssb_idx) { if (nb_mapped_ssb == random_ssb_nb) { - *prach_occasion_info_pp = prach_occasion_info_p; + *prach_occasion_info_pp = ro_p; return 1; } else { From 499bd4945011fe66e0ac42b9bc677db5db40f81b Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 10 Mar 2024 17:13:59 +0100 Subject: [PATCH 09/35] fix SIB other than 1 --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 2 +- openair2/RRC/NR_UE/rrc_UE.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 3b1f2ee876..a76f5237c4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1738,8 +1738,8 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac) uint32_t curr_mask = cfg->ssb_table.ssb_mask_list[ssb_index / 32].ssb_mask; // check if if current SSB is transmitted if ((curr_mask >> (31 - (ssb_index % 32))) & 0x01) { - ssb_list->nb_tx_ssb++; ssb_list->nb_ssb_per_index[ssb_index]=ssb_list->nb_tx_ssb; + ssb_list->nb_tx_ssb++; } } ssb_list->tx_ssb = calloc(ssb_list->nb_tx_ssb, sizeof(*ssb_list->tx_ssb)); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index e6d017b878..c397de4346 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -348,42 +348,55 @@ bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type) case NR_SIB_TypeInfo__type_sibType2: if (!SI_info->sib2) return false; + break; case NR_SIB_TypeInfo__type_sibType3: if (!SI_info->sib3) return false; + break; case NR_SIB_TypeInfo__type_sibType4: if (!SI_info->sib4) return false; + break; case NR_SIB_TypeInfo__type_sibType5: if (!SI_info->sib5) return false; + break; case NR_SIB_TypeInfo__type_sibType6: if (!SI_info->sib6) return false; + break; case NR_SIB_TypeInfo__type_sibType7: if (!SI_info->sib7) return false; + break; case NR_SIB_TypeInfo__type_sibType8: if (!SI_info->sib8) return false; + break; case NR_SIB_TypeInfo__type_sibType9: if (!SI_info->sib9) return false; + break; case NR_SIB_TypeInfo__type_sibType10_v1610: if (!SI_info->sib10) return false; + break; case NR_SIB_TypeInfo__type_sibType11_v1610: if (!SI_info->sib11) return false; + break; case NR_SIB_TypeInfo__type_sibType12_v1610: if (!SI_info->sib12) return false; + break; case NR_SIB_TypeInfo__type_sibType13_v1610: if (!SI_info->sib13) return false; + break; case NR_SIB_TypeInfo__type_sibType14_v1610: if (!SI_info->sib14) return false; + break; default : AssertFatal(false, "Invalid SIB type %d\n", si_type); } From 456009cb1f7c5e9b2906fe9bfdd7d3ccd8395b34 Mon Sep 17 00:00:00 2001 From: mir Date: Thu, 16 Nov 2023 17:30:41 +0100 Subject: [PATCH 10/35] Add a sequence container in OAI Add a sequence container in OAI. Includes for_each algorithm, doxygen odcumentation, and test using ctest. --- common/utils/CMakeLists.txt | 1 + common/utils/alg/CMakeLists.txt | 6 + common/utils/alg/find.c | 49 +++++++ common/utils/alg/find.h | 58 ++++++++ common/utils/alg/foreach.c | 40 ++++++ common/utils/alg/foreach.h | 38 +++++ common/utils/ds/CMakeLists.txt | 5 + common/utils/ds/seq_arr.c | 190 +++++++++++++++++++++++++ common/utils/ds/seq_arr.h | 144 +++++++++++++++++++ common/utils/ds/tests/CMakeLists.txt | 4 + common/utils/ds/tests/test_seq_array.c | 90 ++++++++++++ 11 files changed, 625 insertions(+) create mode 100644 common/utils/alg/CMakeLists.txt create mode 100644 common/utils/alg/find.c create mode 100644 common/utils/alg/find.h create mode 100644 common/utils/alg/foreach.c create mode 100644 common/utils/alg/foreach.h create mode 100644 common/utils/ds/seq_arr.c create mode 100644 common/utils/ds/seq_arr.h create mode 100644 common/utils/ds/tests/CMakeLists.txt create mode 100644 common/utils/ds/tests/test_seq_array.c diff --git a/common/utils/CMakeLists.txt b/common/utils/CMakeLists.txt index 8d5989be38..094ca6b10d 100644 --- a/common/utils/CMakeLists.txt +++ b/common/utils/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(alg) add_subdirectory(ds) add_boolean_option(ENABLE_TELNETSRV OFF "Whether to build telnet support in modems" OFF) if(ENABLE_TELNETSRV) diff --git a/common/utils/alg/CMakeLists.txt b/common/utils/alg/CMakeLists.txt new file mode 100644 index 0000000000..0c9f9ce25c --- /dev/null +++ b/common/utils/alg/CMakeLists.txt @@ -0,0 +1,6 @@ +add_library(alg OBJECT + find.c + foreach.c +) + +target_include_directories(alg PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/common/utils/alg/find.c b/common/utils/alg/find.c new file mode 100644 index 0000000000..1aea32ab88 --- /dev/null +++ b/common/utils/alg/find.c @@ -0,0 +1,49 @@ +/* +MIT License + +Copyright (c) 2022 Mikel Irazabal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "find.h" +#include +#include +#include + +elm_arr_t find_if_arr_it(seq_arr_t* arr, void* start_it, void* end_it, void* value, bool (*f)(const void*, const void*)) +{ + assert(arr != NULL); + + while (start_it != end_it) { + if (f(value, start_it)) + return (elm_arr_t){.found = true, .it = start_it}; + start_it = seq_arr_next(arr, start_it); + } + // If I trusted the average developer I should return it=start_it, but I don't. + return (elm_arr_t){.found = false, .it = NULL}; +} + +elm_arr_t find_if_arr(seq_arr_t* arr, void* value, bool (*f)(const void*, const void*)) +{ + assert(arr != NULL); + void* start_it = seq_arr_front(arr); + void* end_it = seq_arr_end(arr); + return find_if_arr_it(arr, start_it, end_it, value, f); +} diff --git a/common/utils/alg/find.h b/common/utils/alg/find.h new file mode 100644 index 0000000000..a8acde169d --- /dev/null +++ b/common/utils/alg/find.h @@ -0,0 +1,58 @@ +/* +MIT License + +Copyright (c) 2022 Mikel Irazabal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef FIND_ALGORITHM +#define FIND_ALGORITHM + +#include +#include "../ds/seq_arr.h" + +typedef struct { + void* it; + bool found; +} elm_arr_t; + +// Sequencial containers + +/** + * @brief Find elements in an array if the predicate is true + * @param arr The sequence container + * @param value Pointer to the value that will be used by the predicate + * @param f Function representing the predicate + * @return Whether the predicate was fullfilled and the iterator to the element if true + */ +elm_arr_t find_if_arr(seq_arr_t* arr, void* value, bool (*f)(const void* value, const void* it)); + +/** + * @brief Find elements in an array in the semi-open range [start_it, end_it) + * @param arr The sequence container + * @param start_it Iterator to the first element + * @param end_it Iterator to the one past last element + * @param value Pointer to the value usied in the predicate + * @param f Function representing the predicate + * @return Whether the predicate was fullfilled and the iterator to the element if true + */ +elm_arr_t find_if_arr_it(seq_arr_t* arr, void* start_it, void* end_it, void* value, bool (*f)(const void* value, const void* it)); + +#endif diff --git a/common/utils/alg/foreach.c b/common/utils/alg/foreach.c new file mode 100644 index 0000000000..a520a47736 --- /dev/null +++ b/common/utils/alg/foreach.c @@ -0,0 +1,40 @@ +/* +MIT License + +Copyright (c) 2022 Mikel Irazabal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "foreach.h" + +#include +#include + +void for_each(seq_arr_t* arr, void* value, void (*f)(void* value, void* it)) +{ + assert(arr != NULL); + + void* it = seq_arr_front(arr); + void* end = seq_arr_end(arr); + while (it != end) { + f(value, it); + it = seq_arr_next(arr, it); + } +} diff --git a/common/utils/alg/foreach.h b/common/utils/alg/foreach.h new file mode 100644 index 0000000000..6bcf67b606 --- /dev/null +++ b/common/utils/alg/foreach.h @@ -0,0 +1,38 @@ +/* +MIT License + +Copyright (c) 2022 Mikel Irazabal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef FOR_EACH_ALGORITHM +#define FOR_EACH_ALGORITHM + +#include "../ds/seq_arr.h" + +/** + * @brief Apply function to each element in the sequence container + * @param arr The sequence container + * @param value Pointer to the value that will be used by the function applied + * @param fn_apply Function called by every element in the sequence container + */ +void for_each(seq_arr_t* arr, void* value, void (*fn_apply)(void* value, void* it)); + +#endif diff --git a/common/utils/ds/CMakeLists.txt b/common/utils/ds/CMakeLists.txt index 400d34ad06..a5ae86c52f 100644 --- a/common/utils/ds/CMakeLists.txt +++ b/common/utils/ds/CMakeLists.txt @@ -1,5 +1,10 @@ add_library(ds OBJECT byte_array.c + seq_arr.c ) target_include_directories(ds PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +if(ENABLE_TESTS) + add_subdirectory(tests) +endif() diff --git a/common/utils/ds/seq_arr.c b/common/utils/ds/seq_arr.c new file mode 100644 index 0000000000..708552a24e --- /dev/null +++ b/common/utils/ds/seq_arr.c @@ -0,0 +1,190 @@ +/* +MIT License + +Copyright (c) 2022 Mikel Irazabal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "seq_arr.h" + +#include +#include +#include +#include + +static const size_t MIN_SIZE = 8; + +static void maybe_expand(seq_arr_t* arr) +{ + if (arr->size + 1 == arr->cap) { + arr->data = realloc(arr->data, 2 * arr->cap * arr->elt_size); + assert(arr->data != NULL && "realloc failed to allocate memory"); + arr->cap *= 2; + } +} + +static void maybe_shrink(seq_arr_t* arr) +{ + const float occ = (float)arr->size / (float)arr->cap; + if (arr->size > MIN_SIZE && occ < 0.25) { + assert(arr->cap > MIN_SIZE); + seq_arr_t tmp = {.data = NULL, .size = arr->size, .elt_size = arr->elt_size, .cap = arr->cap / 2}; + tmp.data = calloc(tmp.cap, tmp.cap); + assert(tmp.data != NULL && "Memory exhausted"); + assert(arr->size <= tmp.cap); + memcpy(tmp.data, arr->data, arr->size * arr->elt_size); + free(arr->data); + memcpy(arr, &tmp, sizeof(seq_arr_t)); + } +} + +void seq_arr_init(seq_arr_t* arr, size_t elt_size) //__attribute__(malloc) +{ + assert(arr != NULL); + seq_arr_t tmp = {.data = NULL, .size = 0, .elt_size = elt_size, .cap = MIN_SIZE}; + memcpy(arr, &tmp, sizeof(seq_arr_t)); + arr->data = calloc(arr->cap, elt_size); + assert(arr->data != NULL); +} + +void seq_arr_free(seq_arr_t* arr, void (*free_func)(void*)) +{ + assert(arr != NULL); + assert(arr->data != NULL); + + if (free_func != NULL) { + void* start_it = seq_arr_front(arr); + void* end_it = seq_arr_end(arr); + while (start_it != end_it) { + free_func(start_it); + start_it = seq_arr_next(arr, start_it); + } + } + + free(arr->data); +} + +void seq_arr_push_back(seq_arr_t* arr, void* data, size_t len) +{ + assert(arr != NULL); + assert(arr->data != NULL); + // assert(data != NULL); + assert(len == arr->elt_size); + + maybe_expand(arr); + + const size_t offset = arr->size * arr->elt_size; + memcpy(&arr->data[offset], data, arr->elt_size); + arr->size += 1; +} + +void seq_arr_erase(seq_arr_t* arr, void* start_it) +{ + // start_it must be in the range of arr->data + assert(arr != NULL); + assert(start_it != NULL); + return seq_arr_erase_deep(arr, start_it, NULL); +} + +void seq_arr_erase_deep(seq_arr_t* arr, void* start_it, void (*free_func)(void* it)) +{ + // start_it must be in the range of arr->data + assert(arr != NULL); + assert(start_it != NULL); + return seq_arr_erase_it(arr, start_it, seq_arr_next(arr, start_it), free_func); +} + +void seq_arr_erase_it(seq_arr_t* arr, void* start_it, void* end_it, void (*free_func)(void* it)) +{ + // start_it && end_it must be in the range of arr->data + assert(arr != NULL); + assert(start_it != NULL); + assert(end_it != NULL); + assert(end_it >= start_it); + + if (start_it == end_it) + return; + + if (free_func != NULL) { + void* start_it = seq_arr_front(arr); + void* end_it = seq_arr_end(arr); + while (start_it != end_it) { + free_func(start_it); + start_it = seq_arr_next(arr, start_it); + } + } + + const int num_bytes_move = seq_arr_end(arr) - end_it; + assert(num_bytes_move > -1); + memmove(start_it, end_it, num_bytes_move); + + const int num_bytes_erase = end_it - start_it; + const int32_t num_elm_erase = num_bytes_erase / arr->elt_size; + assert(num_elm_erase > 0); + arr->size -= num_elm_erase; + + memset(seq_arr_end(arr), 0, num_bytes_erase); + + maybe_shrink(arr); +} + +size_t seq_arr_size(seq_arr_t const* arr) +{ + assert(arr != NULL); + return arr->size; +} + +void* seq_arr_front(seq_arr_t const* arr) +{ + assert(arr != NULL); + return arr->data; +} + +void* seq_arr_next(seq_arr_t const* arr, void const* it) +{ + assert(arr != NULL); + assert(it != NULL); + return (uint8_t*)it + arr->elt_size; +} + +void* seq_arr_end(seq_arr_t const* arr) +{ + assert(arr != NULL); + assert(arr->data != NULL); + return &arr->data[arr->size * arr->elt_size]; +} + +void* seq_arr_at(seq_arr_t const* arr, uint32_t pos) +{ + assert(arr != NULL); + assert(arr->data != NULL); + assert(pos < arr->size); + return arr->data + pos * arr->elt_size; +} + +ptrdiff_t seq_arr_dist(seq_arr_t const* arr, void const* first, void const* last) +{ + assert(arr != NULL); + assert(first != NULL); + assert(last != NULL); + const ptrdiff_t pos = (last - first) / arr->elt_size; + assert(pos > -1); + return pos; +} diff --git a/common/utils/ds/seq_arr.h b/common/utils/ds/seq_arr.h new file mode 100644 index 0000000000..2fd049fa34 --- /dev/null +++ b/common/utils/ds/seq_arr.h @@ -0,0 +1,144 @@ +/* +MIT License + +Copyright (c) 2022 Mikel Irazabal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SEQ_CONTAINER_ARRAY +#define SEQ_CONTAINER_ARRAY + +/* + * Basic sequence container with a similar API and behaviour to C++ std::vector + */ + +#include +#include +#include +#include + +typedef struct seq_arr_s { + uint8_t* data; + size_t size; + const size_t elt_size; + size_t cap; +} seq_arr_t; + +/** + * Init a sequence container, similar to a constructor + * @brief Constructor. + * @param arr The sequence container + * @param elm_sz value returned by the sizeof operator of the type that the container will hold e.g., sizeof(int). + */ +void seq_arr_init(seq_arr_t* arr, size_t elm_sz); + +/** + * Free a sequence container, similar to a destructor + * @brief Destructor. + * @param arr The sequence container + * @param free_func Function called for every element while destructing e.g., useful to free memory of deep objects. + */ +void seq_arr_free(seq_arr_t* arr, void (*free_func)(void* it)); + +/** + * @brief Push back elements into the sequence container. Value semantic. i.e., the void* data will be shallowly copied in the + * array. + * @param arr The sequence container + * @param data Pointer to the data to be copied + * @param elm_sz Size of the element to be copied e.g., sizeof(int) + */ +void seq_arr_push_back(seq_arr_t* arr, void* data, size_t elm_sz); + +/** + * @brief Erase the element pointed by it + * @param arr The sequence container + * @param it Iterator to the element to erase + */ +void seq_arr_erase(seq_arr_t*, void* it); + +/** + * @brief Erase the element pointed by it and call the f function. Useful to free deep copies + * @param arr The sequence container + * @param it Iterator to the element to erase + * @param free_func Function to call while erasing element + */ +void seq_arr_erase_deep(seq_arr_t* arr, void* it, void (*free_func)(void* it)); + +/** + * @brief Erase the elements in the semi-open range [first,last) + * @param arr The sequence container + * @param first Iterator to the first element to erase + * @param last Iterator to the last element. Note that this element will NOT be erased + * @param f Function that will be called by every element while erasing. Useful for deep copies. Pass NULL if shallow + * erased required + */ +void seq_arr_erase_it(seq_arr_t* arr, void* first, void* last, void (*free_func)(void* it)); + +/** + * @brief Elements in the array + * @param arr The sequence container + * @return The number of elements in the sequence container + */ +size_t seq_arr_size(seq_arr_t const* arr); + +///// +// Iterators +///// + +/** + * @brief First iterator + * @param arr The sequence container + * @return The iterator to the first element in the sequence container + */ +void* seq_arr_front(seq_arr_t const* arr); + +/** + * @brief Next iterator + * @param arr The sequence container + * @param it Iterator to a valid element + * @return The iterator to the next element in the sequence container + */ +void* seq_arr_next(seq_arr_t const* arr, void const* it); + +/** + * @brief End iterator + * @param arr The sequence container + * @return The iterator to one past the last element in the sequence container + */ +void* seq_arr_end(seq_arr_t const* arr); + +/** + * @brief Returns iterator in positions pos + * @param arr The sequence container + * @param pos The position of the element in the sequence container + * @return The iterator to the element + */ +void* seq_arr_at(seq_arr_t const* arr, uint32_t pos); + +/** + * @brief Distance between iterators + * @param arr The sequence container + * @param first Iterator to first element + * @param last Iterator to last element + * @return The distance among iterators + */ +ptrdiff_t seq_arr_dist(seq_arr_t const* arr, void const* first, void const* last); + +#endif diff --git a/common/utils/ds/tests/CMakeLists.txt b/common/utils/ds/tests/CMakeLists.txt new file mode 100644 index 0000000000..a3ef512f09 --- /dev/null +++ b/common/utils/ds/tests/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable(test_seq_arr test_seq_array.c) +target_link_libraries(test_seq_arr ds alg) +add_dependencies(tests test_seq_arr) +add_test(NAME test_seq_arr COMMAND test_seq_arr) # no options required diff --git a/common/utils/ds/tests/test_seq_array.c b/common/utils/ds/tests/test_seq_array.c new file mode 100644 index 0000000000..c642c883c7 --- /dev/null +++ b/common/utils/ds/tests/test_seq_array.c @@ -0,0 +1,90 @@ +#include "../seq_arr.h" +#include "../../alg/find.h" +#include "../../alg/foreach.h" +#include + +/* + Example to show seq_arr_t capabilities and usage + To compile: gcc test_seq_array.c ../seq_arr.c ../../alg/find.c ../../alg/foreach.c +*/ + +static bool eq_int(const void* value, const void* it) +{ + const int* v = (const int*)value; + const int* i = (const int*)it; + return *v == *i; +} + +static void sum_elm(void* value, void* it) +{ + int* sum = (int*)value; + int* elm = (int*)it; + *sum += *elm; +} + +static int compar(const void* m0, const void* m1) +{ + int* a = (int*)m0; + int* b = (int*)m1; + + if (*a < *b) + return -1; + + if (*a == *b) + return 0; + + return 1; +} + +int main() +{ + seq_arr_t arr = {0}; + seq_arr_init(&arr, sizeof(int)); + + // Insert data and expand + for (int i = 0; i < 100; ++i) + seq_arr_push_back(&arr, &i, sizeof(int)); + + // Check inserted data + assert(seq_arr_size(&arr) == 100); + assert(*(int*)seq_arr_front(&arr) == 0); + assert(*(int*)seq_arr_at(&arr, 25) == 25); + + // Find element in the array + int value = 50; + elm_arr_t elm = find_if_arr(&arr, &value, eq_int); + assert(elm.found == true); + // Check + assert(*(int*)elm.it == 50); + assert(seq_arr_dist(&arr, seq_arr_front(&arr), elm.it) == 50); + + // Apply predicate to all the elements + int sum = 0; + for_each(&arr, &sum, sum_elm); + assert(sum == 4950); // N*(N+1)/2 -> 99*100/2 + + // Erase found element in the array + seq_arr_erase(&arr, elm.it); + // Check + assert(seq_arr_size(&arr) == 99); + assert(*(int*)seq_arr_at(&arr, 50) == 51); + + // Erase range and force shrink + seq_arr_erase_it(&arr, seq_arr_front(&arr), seq_arr_at(&arr, 90), NULL); + assert(seq_arr_size(&arr) == 9); + assert(*(int*)seq_arr_front(&arr) == 91); + + // Recall that C functions qsort and bsearch, also work + int key = 95; + void* base = seq_arr_front(&arr); + size_t nmemb = seq_arr_size(&arr); + size_t size = sizeof(int); + + void* it = bsearch(&key, base, nmemb, size, compar); + assert(seq_arr_dist(&arr, seq_arr_front(&arr), it) == 4); + + // Free data structure + seq_arr_free(&arr, NULL); + + return EXIT_SUCCESS; +} From 707c707c86cc6dbece6b069367b768685cbc43db Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 12 Mar 2024 19:09:15 +0100 Subject: [PATCH 11/35] Add MIT as License exception allowed in OAI MIT is compatible with OAI public v1.1, so it can be added. --- ci-scripts/checkCodingFormattingRules.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh index ffe978d30d..bd6b93ab84 100755 --- a/ci-scripts/checkCodingFormattingRules.sh +++ b/ci-scripts/checkCodingFormattingRules.sh @@ -74,8 +74,9 @@ then IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true` IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE || true` IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence|License-Identifier: BSD-2-Clause" $FILE || true` + IS_MIT_LICENCE_PRESENT=`egrep -c "MIT License" $FILE || true` IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h|openair1/PHY/CODING/crc.h|openair1/PHY/CODING/crcext.h|openair1/PHY/CODING/types.h|openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c|openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_offload.h" || true` - if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] + if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] && [ $IS_MIT_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] then @@ -184,8 +185,9 @@ do IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true` IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE || true` IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence|License-Identifier: BSD-2-Clause" $FULLFILE || true` + IS_MIT_LICENCE_PRESENT=`egrep -c "MIT License" $FULLFILE || true` IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h|openair1/PHY/CODING/crc.h|openair1/PHY/CODING/crcext.h|openair1/PHY/CODING/types.h|openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c|openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_offload.h" || true` - if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] + if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] && [ $IS_MIT_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] then From f89876778a8a84d68c049297effddc70f8e221de Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Sat, 9 Mar 2024 02:06:34 +0000 Subject: [PATCH 12/35] RRC: Remove check for UE with random ID in RRC Setup Request From the spec, it does not seem to be mandated to check that the random identity needs to be unique within a cell. Also, from experience we see that this only happens when the same UE "comes back"; so since one UE can only have one connection, the other RRC UE contexts (with the same identity) should be removed at some point, anyway, leaving only one with the same identity. --- openair2/RRC/NR/rrc_gNB.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index f0df5996a3..3b73bae843 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1160,14 +1160,6 @@ static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, rrcSetupRequest->ue_Identity.choice.randomValue.buf, rrcSetupRequest->ue_Identity.choice.randomValue.size); - /* if there is already a registered UE (with another RNTI) with this random_value, - * the current one must be removed from MAC/PHY (zombie UE) - */ - if ((ue_context_p = rrc_gNB_ue_context_random_exist(rrc, random_value))) { - LOG_W(NR_RRC, "new UE rnti (coming with random value) is already there, removing UE %x from MAC/PHY\n", msg->crnti); - AssertFatal(false, "not implemented\n"); - } - ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ From f03601ed8e62eb1e17da9eb051c645596c147726 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 28 Feb 2024 13:22:41 +0100 Subject: [PATCH 13/35] implement functions to handle DRB status at RRC UE --- openair2/RRC/NR_UE/rrc_UE.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index e6d017b878..941eda1352 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -152,6 +152,18 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig); +static NR_RB_status_t get_DRB_status(const NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id) +{ + AssertFatal(drb_id > 0 && drb_id < 33, "Invalid DRB ID %ld\n", drb_id); + return rrc->status_DRBs[drb_id - 1]; +} + +static void set_DRB_status(NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id, NR_RB_status_t status) +{ + AssertFatal(drb_id > 0 && drb_id < 33, "Invalid DRB ID %ld\n", drb_id); + rrc->status_DRBs[drb_id - 1] = status; +} + static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_index, NR_RRCReconfiguration_t *rrcReconfiguration) @@ -323,8 +335,8 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst) for (int j = 0; j < NR_NUM_SRB; j++) rrc->Srb[j] = RB_NOT_PRESENT; - for (int j = 0; j < MAX_DRBS_PER_UE; j++) - rrc->status_DRBs[j] = RB_NOT_PRESENT; + for (int j = 1; j <= MAX_DRBS_PER_UE; j++) + set_DRB_status(rrc, j, RB_NOT_PRESENT); // SRB0 activated by default rrc->Srb[0] = RB_ESTABLISHED; for (int j = 0; j < NR_MAX_NUM_LCID; j++) @@ -767,9 +779,9 @@ void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t if (rrc->Srb[i] == RB_SUSPENDED) rrc->Srb[i] = RB_ESTABLISHED; } - for (int i = 0; i < MAX_DRBS_PER_UE; i++) { - if (rrc->status_DRBs[i] == RB_SUSPENDED) - rrc->status_DRBs[i] = RB_ESTABLISHED; + for (int i = 1; i <= MAX_DRBS_PER_UE; i++) { + if (get_DRB_status(rrc, i) == RB_SUSPENDED) + set_DRB_status(rrc, i, RB_ESTABLISHED); } // TODO reset MAC } @@ -1230,7 +1242,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, struct NR_DRB_ToAddMod *drb = radioBearerConfig->drb_ToAddModList->list.array[cnt]; int DRB_id = drb->drb_Identity; /* DRB is already established and configured */ - if (ue_rrc->status_DRBs[DRB_id] == RB_ESTABLISHED) { + if (get_DRB_status(ue_rrc, DRB_id) == RB_ESTABLISHED) { AssertFatal(drb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n"); AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n"); /* sdap-Config is included (SA mode) */ @@ -1242,7 +1254,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, if (sdap_Config) nr_reconfigure_sdap_entity(sdap_Config, ue_rrc->ue_id, sdap_Config->pdu_Session, DRB_id); } else { - ue_rrc->status_DRBs[DRB_id] = RB_ESTABLISHED; + set_DRB_status(ue_rrc ,DRB_id, RB_ESTABLISHED); add_drb(false, ue_rrc->ue_id, radioBearerConfig->drb_ToAddModList->list.array[cnt], @@ -1839,9 +1851,9 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, // release all radio resources, including release of the RLC entity, // the MAC configuration and the associated PDCP entity // and SDAP for all established RBs - for (int i = 0; i < MAX_DRBS_PER_UE; i++) { - if (rrc->status_DRBs[i] != RB_NOT_PRESENT) { - rrc->status_DRBs[i] = RB_NOT_PRESENT; + for (int i = 1; i <= MAX_DRBS_PER_UE; i++) { + if (get_DRB_status(rrc, i) != RB_NOT_PRESENT) { + set_DRB_status(rrc, i, RB_NOT_PRESENT); nr_pdcp_release_drb(rrc->ue_id, i); } } From 8c2dc1947022f8cae96a3dafc0f448da9b28fb56 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 4 Oct 2023 14:46:18 +0200 Subject: [PATCH 14/35] reestablishment initiation --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 43 ++++++--- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 6 +- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 128 ++++++++++++++++--------- openair2/RRC/NR_UE/rrc_UE.c | 39 ++++++++ openair2/RRC/NR_UE/rrc_defs.h | 3 +- openair2/RRC/NR_UE/rrc_proto.h | 1 + 6 files changed, 158 insertions(+), 62 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 26ee87bacf..f2527e1e8c 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1355,21 +1355,40 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up } void nr_rrc_mac_config_req_reset(module_id_t module_id, - NR_UE_MAC_reset_cause_t reset_cause) + NR_UE_MAC_reset_cause_t cause) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - reset_mac_inst(mac); - reset_ra(&mac->ra); - release_mac_configuration(mac); - nr_ue_init_mac(mac); - // Sending to PHY a request to resync - // with no target cell ID - if (reset_cause != DETACH) { - mac->synch_request.Mod_id = module_id; - mac->synch_request.CC_id = 0; - mac->synch_request.synch_req.target_Nid_cell = -1; - mac->if_module->synch_request(&mac->synch_request); + switch (cause) { + case GO_TO_IDLE: + reset_ra(&mac->ra); + release_mac_configuration(mac, cause); + nr_ue_init_mac(mac); + nr_ue_mac_default_configs(mac); + // new sync but no target cell id -> -1 + nr_ue_send_synch_request(mac, module_id, 0, -1); + break; + case DETACH: + reset_ra(&mac->ra); + reset_mac_inst(mac); + nr_ue_reset_sync_state(mac); + release_mac_configuration(mac, cause); + break; + case T300_EXPIRY: + reset_mac_inst(mac); + reset_ra(&mac->ra); + mac->state = UE_SYNC; // still in sync but need to restart RA + break; + case RE_ESTABLISHMENT: + reset_mac_inst(mac); + nr_ue_mac_default_configs(mac); + nr_ue_reset_sync_state(mac); + release_mac_configuration(mac, cause); + // new sync with old cell ID (re-establishment on the same cell) + nr_ue_send_synch_request(mac, module_id, 0, mac->physCellId); + break; + default: + AssertFatal(false, "Invalid MAC reset cause %d\n", cause); } } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 86ce0c348a..ec3a0d608f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -205,7 +205,8 @@ 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 release_mac_configuration(NR_UE_MAC_INST_t *mac); +void release_mac_configuration(NR_UE_MAC_INST_t *mac, + NR_UE_MAC_reset_cause_t cause); /**\brief called at each slot, slot length based on numerology. now use u=0, scs=15kHz, slot=1ms performs BSR/SR/PHR procedures, random access procedure handler and DLSCH/ULSCH procedures. @@ -450,6 +451,9 @@ void nr_get_prach_resources(NR_UE_MAC_INST_t *mac, void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack); void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind); +void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac); +void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, int cell_id); + void init_RA(NR_UE_MAC_INST_t *mac, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index c7e43e50f8..968f948631 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -56,12 +56,11 @@ void send_srb0_rrc(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) { LOG_I(NR_MAC, "[UE%d] Initializing MAC\n", mac->ue_id); - mac->first_sync_frame = -1; + nr_ue_reset_sync_state(mac); mac->get_sib1 = false; mac->get_otherSI = false; mac->phy_config_request_sent = false; memset(&mac->phy_config, 0, sizeof(mac->phy_config)); - mac->state = UE_NOT_SYNC; mac->si_window_start = -1; mac->servCellIndex = 0; mac->harq_ACK_SpatialBundlingPUCCH = false; @@ -69,6 +68,9 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) mac->uecap_maxMIMO_PDSCH_layers = 0; mac->uecap_maxMIMO_PUSCH_layers_cb = 0; mac->uecap_maxMIMO_PUSCH_layers_nocb = 0; + mac->p_Max = INT_MIN; + mac->p_Max_alt = INT_MIN; + reset_mac_inst(mac); memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements)); memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment)); @@ -76,35 +78,32 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) memset(&mac->ssb_list[i], 0, sizeof(mac->ssb_list[i])); memset(&mac->prach_assoc_pattern[i], 0, sizeof(mac->prach_assoc_pattern[i])); } - for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) { - mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value - mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value - } } void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac) { // default values as defined in 38.331 sec 9.2.2 - mac->scheduling_info.retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf10240; - mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_infinity; - mac->scheduling_info.SR_COUNTER = 0; - mac->scheduling_info.SR_pending = 0; - mac->scheduling_info.sr_ProhibitTimer = 0; - mac->scheduling_info.sr_ProhibitTimer_Running = 0; - mac->scheduling_info.sr_id = -1; // invalid init value + mac->scheduling_info.retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf80; + mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; + mac->scheduling_info.periodicPHR_Timer = NR_PHR_Config__phr_PeriodicTimer_sf10; + mac->scheduling_info.prohibitPHR_Timer = NR_PHR_Config__phr_ProhibitTimer_sf10; +} - // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value - // configured by the NW. - mac->scheduling_info.periodicBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING; - mac->scheduling_info.retxBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING; - mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE; +void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, int cell_id) +{ + // Sending to PHY a request to resync + mac->synch_request.Mod_id = module_id; + mac->synch_request.CC_id = cc_id; + mac->synch_request.synch_req.target_Nid_cell = cell_id; + mac->if_module->synch_request(&mac->synch_request); +} - for (int i = 0; i < NR_MAX_NUM_LCID; i++) { - LOG_D(NR_MAC, "Applying default logical channel config for LCGID %d\n", i); - mac->scheduling_info.lc_sched_info[i].LCID_buffer_with_data = false; - mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0; - mac->scheduling_info.lc_sched_info[i].Bj = 0; - } +void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac) +{ + // reset synchornization status + mac->first_sync_frame = -1; + mac->state = UE_NOT_SYNC; + mac->ra.ra_state = RA_UE_IDLE; } NR_UE_MAC_INST_t *nr_l2_init_ue(int nb_inst) @@ -144,14 +143,16 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac) { // MAC reset according to 38.321 Section 5.12 - nr_ue_mac_default_configs(nr_mac); - // initialize Bj for each logical channel to zero - for (int i = 0; i < NR_MAX_NUM_LCID; i++) + // TODO reset also other status variables of LC, is this ok? + for (int i = 0; i < NR_MAX_NUM_LCID; i++) { nr_mac->scheduling_info.lc_sched_info[i].Bj = 0; + nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_with_data = false; + nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0; + } - // stop all running timers - // TODO + // TODO stop all running timers + nr_timer_stop(&nr_mac->ra.contention_resolution_timer); // consider all timeAlignmentTimers as expired and perform the corresponding actions in clause 5.2 // TODO @@ -171,10 +172,16 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac) free_and_zero(nr_mac->ra.Msg3_buffer); // cancel any triggered Scheduling Request procedure - // Done in default config + nr_mac->scheduling_info.SR_COUNTER = 0; + nr_mac->scheduling_info.SR_pending = 0; + nr_mac->scheduling_info.sr_ProhibitTimer = 0; + nr_mac->scheduling_info.sr_ProhibitTimer_Running = 0; + nr_mac->scheduling_info.sr_id = -1; // invalid init value // cancel any triggered Buffer Status Reporting procedure - // Done in default config + nr_mac->scheduling_info.periodicBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING; + nr_mac->scheduling_info.retxBSR_SF = NR_MAC_UE_BSR_TIMER_NOT_RUNNING; + nr_mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE; // cancel any triggered Power Headroom Reporting procedure // TODO PHR not implemented yet @@ -194,12 +201,24 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac) // TODO beam failure procedure not implemented } -void release_mac_configuration(NR_UE_MAC_INST_t *mac) +void release_mac_configuration(NR_UE_MAC_INST_t *mac, + NR_UE_MAC_reset_cause_t cause) { - asn1cFreeStruc(asn_DEF_NR_MIB, mac->mib); - asn1cFreeStruc(asn_DEF_NR_SI_SchedulingInfo, mac->si_SchedulingInfo); - asn1cFreeStruc(asn_DEF_NR_TDD_UL_DL_ConfigCommon, mac->tdd_UL_DL_ConfigurationCommon); NR_UE_ServingCell_Info_t *sc = &mac->sc_info; + // if cause is Re-establishment, release spCellConfig only + if (cause == GO_TO_IDLE) { + asn1cFreeStruc(asn_DEF_NR_MIB, mac->mib); + asn1cFreeStruc(asn_DEF_NR_SearchSpace, mac->search_space_zero); + asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, mac->coreset0); + asn1cFreeStruc(asn_DEF_NR_SI_SchedulingInfo, mac->si_SchedulingInfo); + asn1cFreeStruc(asn_DEF_NR_TDD_UL_DL_ConfigCommon, mac->tdd_UL_DL_ConfigurationCommon); + for (int i = 0; i < mac->lc_ordered_list.count; i++) { + nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; + asn_sequence_del(&mac->lc_ordered_list, i, 0); + free(lc_info); + } + } + asn1cFreeStruc(asn_DEF_NR_CrossCarrierSchedulingConfig, sc->crossCarrierSchedulingConfig); asn1cFreeStruc(asn_DEF_NR_SRS_CarrierSwitching, sc->carrierSwitching); asn1cFreeStruc(asn_DEF_NR_UplinkConfig, sc->supplementaryUplink); @@ -218,20 +237,35 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac) mac->current_DL_BWP = NULL; mac->current_UL_BWP = NULL; - for (int i = 0; i < mac->dl_BWPs.count; i++) - release_dl_BWP(mac, i); - for (int i = 0; i < mac->ul_BWPs.count; i++) - release_ul_BWP(mac, i); - - asn1cFreeStruc(asn_DEF_NR_SearchSpace, mac->search_space_zero); - asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, mac->coreset0); - - for (int i = 0; i < mac->lc_ordered_list.count; i++) { - nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; - asn_sequence_del(&mac->lc_ordered_list, i, 0); - free(lc_info); + // in case of re-establishment we don't need to release initial BWP config common + int first_bwp_rel = 0; // first BWP to release + if (cause == RE_ESTABLISHMENT) { + first_bwp_rel = 1; + // release dedicated BWP0 config + NR_UE_DL_BWP_t *bwp = mac->dl_BWPs.array[0]; + NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[0]; + for (int i = 0; pdcch->list_Coreset.count; i++) + asn_sequence_del(&pdcch->list_Coreset, i, 1); + for (int i = 0; pdcch->list_SS.count; i++) + asn_sequence_del(&pdcch->list_SS, i, 1); + asn1cFreeStruc(asn_DEF_NR_PDSCH_Config, bwp->pdsch_Config); + NR_UE_UL_BWP_t *ubwp = mac->ul_BWPs.array[0]; + asn1cFreeStruc(asn_DEF_NR_PUCCH_Config, ubwp->pucch_Config); + asn1cFreeStruc(asn_DEF_NR_SRS_Config, ubwp->srs_Config); + asn1cFreeStruc(asn_DEF_NR_PUSCH_Config, ubwp->pusch_Config); + mac->current_DL_BWP = bwp; + mac->current_UL_BWP = ubwp; + mac->sc_info.initial_dl_BWPSize = bwp->BWPSize; + mac->sc_info.initial_dl_BWPStart = bwp->BWPStart; + mac->sc_info.initial_ul_BWPSize = ubwp->BWPSize; + mac->sc_info.initial_ul_BWPStart = ubwp->BWPStart; } + for (int i = first_bwp_rel; i < mac->dl_BWPs.count; i++) + release_dl_BWP(mac, i); + for (int i = first_bwp_rel; i < mac->ul_BWPs.count; i++) + release_ul_BWP(mac, i); + memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements)); memset(&mac->csirs_measurements, 0, sizeof(mac->csirs_measurements)); memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment)); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 941eda1352..75f7e40fce 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1601,6 +1601,45 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa } } +void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, + const int gnb_id) +{ + NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; + rrcPerNB_t *rrcNB = rrc->perNB + gnb_id; + + // reset timers to SIB1 as part of release of spCellConfig + // it needs to be done before handling timers + set_rlf_sib1_timers_and_constants(timers, rrcNB->SInfo.sib1); + + // stop timer T310, if running + nr_timer_stop(&timers->T310); + // stop timer T304, if running + nr_timer_stop(&timers->T304); + // start timer T311 + nr_timer_start(&timers->T311); + // suspend all RBs, except SRB0 + for (int i = 1; i < 4; i++) { + if (rrc->Srb[i] == RB_ESTABLISHED) { + rrc->Srb[i] = RB_SUSPENDED; + nr_pdcp_suspend_srb(rrc->ue_id, i); + } + } + for (int i = 1; i <= MAX_DRBS_PER_UE; i++) { + if (get_DRB_status(rrc, i) == RB_ESTABLISHED) { + set_DRB_status(rrc, i, RB_SUSPENDED); + nr_pdcp_suspend_drb(rrc->ue_id, i); + } + } + // release the MCG SCell(s), if configured + // no SCell configured in our implementation + rrc->nrRrcState = RRC_STATE_REESTABLISHMENT; + + // reset MAC + // release spCellConfig, if configured + // perform cell selection in accordance with the cell selection process + nr_rrc_mac_config_req_reset(rrc->ue_id, RE_ESTABLISHMENT); +} + static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment) { uint8_t buffer[RRC_BUFFER_SIZE] = {0}; diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 4ce65ef036..448978a7d0 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -85,8 +85,7 @@ typedef enum Rrc_State_NR_e { RRC_STATE_INACTIVE_NR, RRC_STATE_CONNECTED_NR, RRC_STATE_DETACH_NR, - RRC_STATE_FIRST_NR = RRC_STATE_IDLE_NR, - RRC_STATE_LAST_NR = RRC_STATE_CONNECTED_NR, + RRC_STATE_REESTABLISHMENT } Rrc_State_NR_t; typedef enum requested_SI_List_e { diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 1bb3fda06f..9ce17336d2 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -87,6 +87,7 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, 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, const int rnti); +void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1); /**\brief RRC UE task. \param void *args_p Pointer on arguments to start the task. */ From bfe77c7f296df0583910e45393e134ce997ad4e2 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 6 Oct 2023 17:36:53 +0200 Subject: [PATCH 15/35] Actions following cell selection while T311 is running --- openair2/RRC/NR_UE/rrc_UE.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 75f7e40fce..bee8e293c9 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -308,11 +308,10 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst) rrc->ue_id = nr_ue; // fill UE-NR-Capability @ UE-CapabilityRAT-Container here. rrc->selected_plmn_identity = 1; - + rrc->ra_trigger = RA_NOT_RUNNING; rrc->dl_bwp_id = 0; rrc->ul_bwp_id = 0; rrc->as_security_activated = false; - rrc->ra_trigger = RA_NOT_RUNNING; FILE *f = NULL; if (uecap_file) @@ -445,6 +444,20 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, return; } + // Actions following cell selection while T311 is running + NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; + if (is_nr_timer_active(timers->T311)) { + nr_timer_stop(&timers->T311); + nr_timer_start(&timers->T301); + rrc->ra_trigger = RRC_CONNECTION_REESTABLISHMENT; + + // apply the default MAC Cell Group configuration + // (done at MAC by calling nr_ue_mac_default_configs) + + // apply the timeAlignmentTimerCommon included in SIB1 + // not used + } + int get_sib = 0; if (get_softmodem_params()->sa && bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred && From bb19306797998ec707cf84caa1ab3f9a4e33396c Mon Sep 17 00:00:00 2001 From: francescomani Date: Sat, 7 Oct 2023 10:48:36 +0200 Subject: [PATCH 16/35] transmission of RRCReestablishmentRequest message --- .../SIMULATION/NR_PHY/nr_dummy_functions.c | 3 +- openair2/COMMON/mac_messages_types.h | 4 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 6 +-- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 38 +++++++++++++++++-- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h | 1 + openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 3 +- openair2/RRC/NR/MESSAGES/asn1_msg.c | 13 ++++--- openair2/RRC/NR/MESSAGES/asn1_msg.h | 5 ++- openair2/RRC/NR_UE/L2_interface_ue.c | 5 ++- openair2/RRC/NR_UE/rrc_UE.c | 37 +++++++++++++++--- openair2/RRC/NR_UE/rrc_defs.h | 5 ++- openair2/RRC/NR_UE/rrc_proto.h | 3 +- 12 files changed, 98 insertions(+), 25 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index ed72823789..3646e479d1 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -32,7 +32,7 @@ void nr_mac_rrc_sync_ind(const module_id_t module_id, const frame_t frame, const bool in_sync) {} -void nr_mac_rrc_msg3_ind(const module_id_t mod_id, int rnti) {} +void nr_mac_rrc_msg3_ind(const module_id_t mod_id, int rnti, int gnb_id) {} void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success) {} @@ -48,6 +48,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const frame_t frame, const int slot, const rnti_t rnti, + const uint32_t cellid, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; } diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index 9a6817a41c..79d483891d 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -76,7 +76,8 @@ typedef struct NRRrcMacRaInd_s { } NRRrcMacRaInd; typedef struct NRRrcMacMsg3Ind_s { - uint16_t rnti; + uint16_t rnti; + int gnb_id; } NRRrcMacMsg3Ind; typedef struct RrcMacInSyncInd_s { @@ -118,6 +119,7 @@ typedef struct NRRrcMacBcchDataInd_s { bool is_bch; uint8_t rsrq; uint8_t rsrp; + uint32_t phycellid; } NRRrcMacBcchDataInd; typedef struct NRRrcMacSBcchDataInd_s { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index f81a142cd4..2f6d5f084f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -264,7 +264,7 @@ int8_t nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, { if(ack_nack) { LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); - nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); + nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, mac->physCellId, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); mac->get_sib1 = false; mac->get_otherSI = false; } @@ -3774,7 +3774,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, // - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id) { - frame_t frame = dl_info->frame; + frame_t frame = dl_info->frame; int slot = dl_info->slot; if(dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.ack_nack == 0) { @@ -3976,7 +3976,7 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d if (!ra->cfra) { ra->t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); rnti = ra->t_crnti; - nr_mac_rrc_msg3_ind(mac->ue_id, rnti); + nr_mac_rrc_msg3_ind(mac->ue_id, rnti, dl_info->gNB_index); } fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); if (!pdu) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index f678b2a0ca..d1bda61f82 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -83,6 +83,24 @@ static void release_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t chan } } +logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id) +{ + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); + for (logical_chan_id_t id = 1; id <= 32; id++) { + nr_rlc_rb_t *rb = &ue->lcid2rb[id - 1]; + if (is_srb) { + if (rb->type == NR_RLC_SRB && rb->choice.srb_id == rb_id) + return id; + } else { + if (rb->type == NR_RLC_DRB && rb->choice.drb_id == rb_id) + return id; + } + } + LOG_E(RLC, "Couldn't find LCID corresponding to %s %d\n", is_srb ? "SRB" : "DRB", rb_id); + return 0; +} + static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t channel_id) { if (channel_id == 0) @@ -120,7 +138,7 @@ void nr_rlc_release_entity(int rnti, logical_chan_id_t channel_id) void mac_rlc_data_ind(const module_id_t module_idP, const rnti_t rntiP, const eNB_index_t eNB_index, - const frame_t rameP, + const frame_t frameP, const eNB_flag_t enb_flagP, const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP, @@ -631,9 +649,10 @@ void nr_rlc_reestablish_entity(int rnti, int lc_id) nr_rlc_manager_lock(nr_rlc_ue_manager); nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); - if (ue == NULL) + if (ue == NULL) { LOG_E(RLC, "RLC instance for the given UE was not found \n"); - + return; + } nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id); if (rb != NULL) { @@ -644,7 +663,6 @@ void nr_rlc_reestablish_entity(int rnti, int lc_id) } nr_rlc_manager_unlock(nr_rlc_ue_manager); } - void nr_rlc_reconfigure_entity(int rnti, int lc_id, NR_RLC_Config_t *rlc_Config) { nr_rlc_manager_lock(nr_rlc_ue_manager); @@ -703,6 +721,18 @@ void nr_rlc_reconfigure_entity(int rnti, int lc_id, NR_RLC_Config_t *rlc_Config) AssertFatal(um->ul_UM_RLC.sn_FieldLength == NULL, "Cannot handle different sn_FieldLength for DL and UL\n"); nr_rlc_entity_um_reconfigure(rb, t_reassembly, sn_field_length); } + } else { + AssertFatal(rb->stats.mode == NR_RLC_AM, "Invalid RLC mode\n"); + // default values as in 9.2.1 of 38.331 + int sn_field_length = 12; + nr_rlc_entity_am_reconfigure(rb, + 45, //t_poll_retransmit + 35, //t_reassembly + 0, //t_status_prohibit + -1, //poll_pdu + -1, //poll_byte + 8, //max_retx_threshold + &sn_field_length); } nr_rlc_manager_unlock(nr_rlc_ue_manager); } diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index 4f4578ec80..607538b15c 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -45,6 +45,7 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); void nr_rlc_reestablish_entity(int rnti, int lc_id); +logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id); void nr_rlc_remove_ue(int rnti); bool nr_rlc_update_rnti(int from_rnti, int to_rnti); diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 7f9f5aa55e..2f0892b66f 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -1048,7 +1048,8 @@ static int handle_bcch_bch(NR_UE_MAC_INST_t *mac, mac->frequency_range = FR2; else mac->frequency_range = FR1; - nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_BCH, (uint8_t *) pduP, 3); // fixed 3 bytes MIB PDU + // fixed 3 bytes MIB PDU + nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, cell_id, NR_BCCH_BCH, (uint8_t *) pduP, 3); return 0; } diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 5b50ecb44e..82798b4b75 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -979,7 +979,10 @@ uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8 return encoded; } -uint8_t do_RRCReestablishmentRequest(uint8_t *buffer, uint16_t c_rnti) +uint8_t do_RRCReestablishmentRequest(uint8_t *buffer, + NR_ReestablishmentCause_t cause, + uint32_t cell_id, + uint16_t c_rnti) { asn_enc_rval_t enc_rval; NR_UL_CCCH_Message_t ul_ccch_msg; @@ -994,16 +997,16 @@ uint8_t do_RRCReestablishmentRequest(uint8_t *buffer, uint16_t c_rnti) rrcReestablishmentRequest = ul_ccch_msg.message.choice.c1->choice.rrcReestablishmentRequest; // test - rrcReestablishmentRequest->rrcReestablishmentRequest.reestablishmentCause = NR_ReestablishmentCause_reconfigurationFailure; + rrcReestablishmentRequest->rrcReestablishmentRequest.reestablishmentCause = cause; rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.c_RNTI = c_rnti; - rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.physCellId = 0; + rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.physCellId = cell_id; + // TODO properly setting shortMAC-I (see 5.3.7.4 of 331) rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf = buf; rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[0] = 0x08; rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[1] = 0x32; rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.size = 2; - - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg); } diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 143717390c..de57a339d5 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -131,7 +131,10 @@ uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer); -uint8_t do_RRCReestablishmentRequest(uint8_t *buffer, uint16_t c_rnti); +uint8_t do_RRCReestablishmentRequest(uint8_t *buffer, + NR_ReestablishmentCause_t cause, + uint32_t cell_id, + uint16_t c_rnti); int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP, uint8_t *const buffer, diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index b3eac63e4c..1e93cc935e 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -54,6 +54,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const frame_t frame, const int slot, const rnti_t rnti, + const uint32_t cellid, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) @@ -84,6 +85,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, 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; + NR_RRC_MAC_BCCH_DATA_IND (message_p).phycellid = cellid; NR_RRC_MAC_BCCH_DATA_IND (message_p).is_bch = (channel == NR_BCCH_BCH); itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p); } @@ -122,10 +124,11 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, return(0); } -void nr_mac_rrc_msg3_ind(const module_id_t mod_id, const int rnti) +void nr_mac_rrc_msg3_ind(const module_id_t mod_id, const int rnti, int gnb_id) { MessageDef *message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_MSG3_IND); NR_RRC_MAC_MSG3_IND (message_p).rnti = rnti; + NR_RRC_MAC_MSG3_IND (message_p).gnb_id = gnb_id; itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(mod_id), message_p); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index bee8e293c9..2c45ce4526 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -428,10 +428,12 @@ int check_si_status(NR_UE_RRC_SI_INFO *SI_info) /*brief decode BCCH-BCH (MIB) message*/ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, const uint8_t gNB_index, + const uint32_t phycellid, uint8_t *const bufferP, const uint8_t buffer_len) { NR_BCCH_BCH_Message_t *bcch_message = NULL; + rrc->phyCellID = phycellid; asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, @@ -448,9 +450,17 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; if (is_nr_timer_active(timers->T311)) { nr_timer_stop(&timers->T311); - nr_timer_start(&timers->T301); rrc->ra_trigger = RRC_CONNECTION_REESTABLISHMENT; + // preparing MSG3 for re-establishment in advance + uint8_t buffer[1024]; + int buf_size = do_RRCReestablishmentRequest(buffer, + rrc->reestablishment_cause, + rrc->phyCellID, + rrc->rnti); // old rnti + + nr_rlc_srb_recv_sdu(rrc->ue_id, 0, buffer, buf_size); + // apply the default MAC Cell Group configuration // (done at MAC by calling nr_ue_mac_default_configs) @@ -590,16 +600,28 @@ static int nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si) static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti) { + NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; switch (rrc->ra_trigger) { case INITIAL_ACCESS_FROM_RRC_IDLE: // After SIB1 is received, prepare RRCConnectionRequest rrc->rnti = rnti; // start timer T300 - NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; nr_timer_start(&tac->T300); break; case RRC_CONNECTION_REESTABLISHMENT: - AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + rrc->rnti = rnti; + nr_timer_start(&tac->T301); + int srb_id = 1; + // re-establish PDCP for SRB1 + nr_pdcp_reestablishment(rrc->ue_id, srb_id, true); + // re-establish RLC for SRB1 + int lc_id = nr_rlc_get_lcid_from_rb(rrc->ue_id, true, 1); + nr_rlc_reestablish_entity(rrc->ue_id, lc_id); + // apply the specified configuration defined in 9.2.1 for SRB1 + nr_rlc_reconfigure_entity(rrc->ue_id, lc_id, NULL); + // TODO configure lower layers to suspend integrity protection and ciphering for SRB1 + // resume SRB1 + rrc->Srb[srb_id] = RB_ESTABLISHED; break; case DURING_HANDOVER: AssertFatal(1==0, "ra_trigger not implemented yet!\n"); @@ -750,7 +772,8 @@ static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, if (rrc->active_RLC_entity[lcid]) { if (rlc_bearer->reestablishRLC) nr_rlc_reestablish_entity(rrc->ue_id, lcid); - nr_rlc_reconfigure_entity(rrc->ue_id, lcid, rlc_bearer->rlc_Config); + if (rlc_bearer->rlc_Config) + nr_rlc_reconfigure_entity(rrc->ue_id, lcid, rlc_bearer->rlc_Config); } else { rrc->active_RLC_entity[lcid] = true; AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n"); @@ -1467,7 +1490,7 @@ void *rrc_nrue(void *notUsed) LOG_D(NR_RRC, "[UE %ld] Received %s: gNB %d\n", rrc->ue_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); if (bcch->is_bch) - nr_rrc_ue_decode_NR_BCCH_BCH_Message(rrc, bcch->gnb_index, bcch->sdu, bcch->sdu_size); + nr_rrc_ue_decode_NR_BCCH_BCH_Message(rrc, bcch->gnb_index, bcch->phycellid, bcch->sdu, bcch->sdu_size); else nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(rrc, bcch->gnb_index, bcch->sdu, bcch->sdu_size, bcch->rsrq, bcch->rsrp); break; @@ -1615,8 +1638,11 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa } void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, + NR_ReestablishmentCause_t cause, const int gnb_id) { + rrc->reestablishment_cause = cause; + NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; rrcPerNB_t *rrcNB = rrc->perNB + gnb_id; @@ -1645,7 +1671,6 @@ void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, } // release the MCG SCell(s), if configured // no SCell configured in our implementation - rrc->nrRrcState = RRC_STATE_REESTABLISHMENT; // reset MAC // release spCellConfig, if configured diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 448978a7d0..40cbca3ad5 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -56,6 +56,7 @@ #include "NR_UE-NR-Capability.h" #include "NR_SL-PreconfigurationNR-r16.h" #include "NR_MasterInformationBlockSidelink.h" +#include "NR_ReestablishmentCause.h" #include "RRC/NR/nr_rrc_common.h" #include "as_message.h" @@ -85,7 +86,6 @@ typedef enum Rrc_State_NR_e { RRC_STATE_INACTIVE_NR, RRC_STATE_CONNECTED_NR, RRC_STATE_DETACH_NR, - RRC_STATE_REESTABLISHMENT } Rrc_State_NR_t; typedef enum requested_SI_List_e { @@ -186,10 +186,13 @@ typedef struct NR_UE_RRC_INST_s { rrcPerNB_t perNB[NB_CNX_UE]; rnti_t rnti; + uint32_t phyCellID; OAI_NR_UECapability_t UECap; NR_UE_Timers_Constants_t timers_and_constants; + RA_trigger_t ra_trigger; + NR_ReestablishmentCause_t reestablishment_cause; plmn_t plmnID; NR_BWP_Id_t dl_bwp_id; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 9ce17336d2..fa8eee3830 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -73,6 +73,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const frame_t frame, const int slot, const rnti_t rnti, + const uint32_t cellid, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len); @@ -86,7 +87,7 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, NR_RRCRelease_t *RRCRelease); 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, const int rnti); +void nr_mac_rrc_msg3_ind(const module_id_t mod_id, const int rnti, int gnb_id); void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1); /**\brief RRC UE task. From 985802c06c4123891119bc441f702d67e4810704 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 12 Dec 2023 09:54:25 +0100 Subject: [PATCH 17/35] T301 expiry --- openair2/RRC/NR_UE/rrc_timers_and_constants.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c index 80f7007a2b..10f50dbf9b 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -121,10 +121,18 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc) bool t300_expired = nr_timer_tick(&timers->T300); if(t300_expired) { - LOG_W(NR_RRC, "Timer T300 expired\n"); + LOG_W(NR_RRC, "Timer T300 expired! No timely response to RRCSetupRequest\n"); handle_t300_expiry(rrc); } + bool t301_expired = nr_timer_tick(&timers->T301); + // Upon T301 expiry, the UE shall perform the actions upon going to RRC_IDLE + // with release cause 'RRC connection failure' + if(t301_expired) { + LOG_W(NR_RRC, "Timer T301 expired! No timely response to RRCReestabilshmentRequest\n"); + nr_rrc_going_to_IDLE(rrc, RRC_CONNECTION_FAILURE, NULL); + } + bool t304_expired = nr_timer_tick(&timers->T304); if(t304_expired) { LOG_W(NR_RRC, "Timer T304 expired\n"); @@ -146,7 +154,7 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc) bool t311_expired = nr_timer_tick(&timers->T311); if(t311_expired) { - LOG_W(NR_RRC, "Timer T311 expired\n"); + LOG_W(NR_RRC, "Timer T311 expired! No suitable cell found in time after initiation of re-establishment\n"); // Upon T311 expiry, the UE shall perform the actions upon going to RRC_IDLE // with release cause 'RRC connection failure' nr_rrc_going_to_IDLE(rrc, RRC_CONNECTION_FAILURE, NULL); From f31cf3a68f333e5ab47f2ed65c5d844e51ecdcae Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 12 Dec 2023 12:06:28 +0100 Subject: [PATCH 18/35] handling reception of RRCReestablishment --- openair2/RRC/NR_UE/rrc_UE.c | 39 ++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 2c45ce4526..a0d9120961 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -139,7 +139,7 @@ static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, NR_RadioBearerConfig_t *const radioBearerConfig); -static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment); +static void nr_rrc_ue_generate_rrcReestablishmentComplete(const NR_UE_RRC_INST_t *rrc, const 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 nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_index, @@ -1320,6 +1320,36 @@ static void nr_rrc_ue_generate_RRCReconfigurationComplete(NR_UE_RRC_INST_t *rrc, nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, size, buffer, deliver_pdu_srb_rlc, NULL); } +static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc, + const int gNB_index, + const NR_RRCReestablishment_t *rrcReestablishment) +{ + // implementign procedues as described in 38.331 section 5.3.7.5 + // stop timer T301 + NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; + nr_timer_stop(&timers->T301); + // store the nextHopChainingCount value + NR_RRCReestablishment_IEs_t *ies = rrcReestablishment->criticalExtensions.choice.rrcReestablishment; + AssertFatal(ies, "Not expecting RRCReestablishment_IEs to be NULL\n"); + int nh = rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount; + // TODO update the K gNB key based on the current K gNB key or the NH, using the stored nextHopChainingCount value + // TODO derive the K RRCenc and K UPenc keys associated with the previously configured cipheringAlgorithm + // TODO derive the K RRCint and K UPint keys associated with the previously configured integrityProtAlgorithm + // TODO request lower layers to verify the integrity protection of the RRCReestablishment message + // TODO if the integrity protection check of the RRCReestablishment message fails -> go to IDLE + // TODO configure lower layers to resume integrity protection for SRB1 + // TODO configure lower layers to resume ciphering for SRB1 + // release the measurement gap configuration indicated by the measGapConfig, if configured + rrcPerNB_t *rrcNB = rrc->perNB + gNB_index; + asn1cFreeStruc(asn_DEF_NR_MeasGapConfig, rrcNB->measGapConfig); + + // resetting the RA trigger state after receiving MSG4 with RRCReestablishment + rrc->ra_trigger = RA_NOT_RUNNING; + + // submit the RRCReestablishmentComplete message to lower layers for transmission + nr_rrc_ue_generate_rrcReestablishmentComplete(rrc, rrcReestablishment); +} + static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, const srb_id_t Srb_id, const uint8_t *const Buffer, @@ -1375,7 +1405,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, 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); + nr_rrc_ue_process_rrcReestablishment(rrc, gNB_indexP, c1->choice.rrcReestablishment); break; case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: { @@ -1678,12 +1708,15 @@ void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, nr_rrc_mac_config_req_reset(rrc->ue_id, RE_ESTABLISHMENT); } -static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment) +static void nr_rrc_ue_generate_rrcReestablishmentComplete(const NR_UE_RRC_INST_t *rrc, + const 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, "[RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes %d)\n", size); + int srb_id = 1; // RRC re-establishment complete on SRB1 + nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, size, buffer, deliver_pdu_srb_rlc, NULL); } void *recv_msgs_from_lte_ue(void *args_p) From a0e9716a5a00b68e70a3fa16563e8a34fddac6a1 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 11 Jan 2024 14:44:17 +0100 Subject: [PATCH 19/35] bugfix: using pusch_config_pdu->nr_of_symbols in pusch schedule before being assigned --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 02b4d38453..ec27e92030 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -553,6 +553,9 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart; pusch_config_pdu->bwp_size = current_UL_BWP->BWPSize; + pusch_config_pdu->start_symbol_index = tda_info->startSymbolIndex; + pusch_config_pdu->nr_of_symbols = tda_info->nrOfSymbols; + /* Transform precoding */ pusch_config_pdu->transform_precoding = get_transformPrecoding(current_UL_BWP, dci_format, 0); @@ -637,9 +640,6 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, return -1; } - pusch_config_pdu->start_symbol_index = tda_info->startSymbolIndex; - pusch_config_pdu->nr_of_symbols = tda_info->nrOfSymbols; - /* FREQ_HOPPING_FLAG */ if ((pusch_Config!=NULL) && (pusch_Config->frequencyHopping!=NULL) && (pusch_Config->resourceAllocation != NR_PUSCH_Config__resourceAllocation_resourceAllocationType0)){ pusch_config_pdu->frequency_hopping = dci->frequency_hopping_flag.val; From 72e10a0ee625468baaf39f418cd197b9a305e384 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 30 Jan 2024 17:05:45 +0100 Subject: [PATCH 20/35] nrUE: handle security settings for SRB1 and reestablishment For the moment absoluteFrequencySSB is hardcoded. Fixed in a following commit. --- openair2/RRC/NR_UE/rrc_UE.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index a0d9120961..069ac2c825 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -619,7 +619,8 @@ static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti) nr_rlc_reestablish_entity(rrc->ue_id, lc_id); // apply the specified configuration defined in 9.2.1 for SRB1 nr_rlc_reconfigure_entity(rrc->ue_id, lc_id, NULL); - // TODO configure lower layers to suspend integrity protection and ciphering for SRB1 + // suspend integrity protection and ciphering for SRB1 + nr_pdcp_config_set_security(rrc->ue_id, srb_id, 0, NULL, NULL, NULL); // resume SRB1 rrc->Srb[srb_id] = RB_ESTABLISHED; break; @@ -1331,14 +1332,36 @@ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc, // store the nextHopChainingCount value NR_RRCReestablishment_IEs_t *ies = rrcReestablishment->criticalExtensions.choice.rrcReestablishment; AssertFatal(ies, "Not expecting RRCReestablishment_IEs to be NULL\n"); - int nh = rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount; - // TODO update the K gNB key based on the current K gNB key or the NH, using the stored nextHopChainingCount value - // TODO derive the K RRCenc and K UPenc keys associated with the previously configured cipheringAlgorithm - // TODO derive the K RRCint and K UPint keys associated with the previously configured integrityProtAlgorithm + // TODO need to understand how to use nextHopChainingCount + // int nh = rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount; + + // update the K gNB key based on the current K gNB key or the NH, using the stored nextHopChainingCount value + /* TODO: retrieve absoluteFrequencySSB correctly */ + int absoluteFrequencySSB = 621312; + nr_derive_key_ng_ran_star(rrc->phyCellID, absoluteFrequencySSB, rrc->kgnb, rrc->kgnb); + + // derive the K RRCenc and K UPenc keys associated with the previously configured cipheringAlgorithm + // derive the K RRCint and K UPint keys associated with the previously configured integrityProtAlgorithm + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + uint8_t kUPenc[16] = {0}; + uint8_t kUPint[16] = {0}; + + nr_derive_key(UP_ENC_ALG, rrc->cipheringAlgorithm, rrc->kgnb, kUPenc); + nr_derive_key(UP_INT_ALG, rrc->integrityProtAlgorithm, rrc->kgnb, kUPint); + nr_derive_key(RRC_ENC_ALG, rrc->cipheringAlgorithm, rrc->kgnb, kRRCenc); + nr_derive_key(RRC_INT_ALG, rrc->integrityProtAlgorithm, rrc->kgnb, kRRCint); + // TODO request lower layers to verify the integrity protection of the RRCReestablishment message // TODO if the integrity protection check of the RRCReestablishment message fails -> go to IDLE - // TODO configure lower layers to resume integrity protection for SRB1 - // TODO configure lower layers to resume ciphering for SRB1 + + // configure lower layers to resume integrity protection for SRB1 + // configure lower layers to resume ciphering for SRB1 + int srb_id = 1; + int security_mode = (rrc->integrityProtAlgorithm << 4) + | rrc->cipheringAlgorithm; + nr_pdcp_config_set_security(rrc->ue_id, srb_id, security_mode, kRRCenc, kRRCint, kUPenc); + // release the measurement gap configuration indicated by the measGapConfig, if configured rrcPerNB_t *rrcNB = rrc->perNB + gNB_index; asn1cFreeStruc(asn_DEF_NR_MeasGapConfig, rrcNB->measGapConfig); From 37d3e5bb58b1f89a2fd23d2c18cdbbe17e917100 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 31 Jan 2024 13:47:46 +0100 Subject: [PATCH 21/35] get SSB ARFCN at RRC UE (needed to update k_gnb key according to 33.501) --- common/utils/nr/nr_common.c | 109 +++++++++++++++++ common/utils/nr/nr_common.h | 3 +- .../nfapi/public_inc/fapi_nr_ue_interface.h | 1 + .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 10 +- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 11 +- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 1 - openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 10 +- .../SIMULATION/NR_PHY/nr_dummy_functions.c | 1 + openair1/SIMULATION/NR_PHY/pbchsim.c | 10 +- openair2/COMMON/mac_messages_types.h | 1 + openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 112 ------------------ openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 4 - openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 +- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 4 +- openair2/RRC/NR_UE/L2_interface_ue.c | 2 + openair2/RRC/NR_UE/rrc_UE.c | 13 +- openair2/RRC/NR_UE/rrc_defs.h | 1 + openair2/RRC/NR_UE/rrc_proto.h | 1 + 18 files changed, 143 insertions(+), 153 deletions(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index f7811cb204..f7ea7304e4 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -376,6 +376,115 @@ int get_nb_periods_per_frame(uint8_t tdd_period) return nb_periods_per_frame; } +void get_delta_arfcn(int i, uint32_t nrarfcn, uint64_t N_OFFs) +{ + uint32_t delta_arfcn = nrarfcn - N_OFFs; + + if(delta_arfcn % (nr_bandtable[i].step_size) != 0) + LOG_E(NR_MAC, "nrarfcn %u is not on the channel raster for step size %lu\n", nrarfcn, nr_bandtable[i].step_size); +} + +uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw) +{ + uint64_t dl_CarrierFreq_by_1k = dl_CarrierFreq / 1000; + int bw_kHz = bw / 1000; + uint32_t nrarfcn; + int i = get_nr_table_idx(nr_bandP, scs_index); + + LOG_I(NR_MAC,"Searching for nr band %d DL Carrier frequency %llu bw %u\n", nr_bandP, (long long unsigned int)dl_CarrierFreq,bw); + + AssertFatal(dl_CarrierFreq_by_1k >= nr_bandtable[i].dl_min, + "Band %d, bw %u : DL carrier frequency %llu kHz < %llu\n", + nr_bandP, bw, (long long unsigned int)dl_CarrierFreq_by_1k, + (long long unsigned int)nr_bandtable[i].dl_min); + AssertFatal(dl_CarrierFreq_by_1k <= (nr_bandtable[i].dl_max - bw_kHz/2), + "Band %d, dl_CarrierFreq %llu bw %u: DL carrier frequency %llu kHz > %llu\n", + nr_bandP, (long long unsigned int)dl_CarrierFreq,bw, (long long unsigned int)dl_CarrierFreq_by_1k, + (long long unsigned int)(nr_bandtable[i].dl_max - bw_kHz/2)); + + int deltaFglobal = 60; + uint32_t N_REF_Offs = 2016667; + uint64_t F_REF_Offs_khz = 24250080; + + if (dl_CarrierFreq < 24.25e9) { + deltaFglobal = 15; + N_REF_Offs = 600000; + F_REF_Offs_khz = 3000000; + } + if (dl_CarrierFreq < 3e9) { + deltaFglobal = 5; + N_REF_Offs = 0; + F_REF_Offs_khz = 0; + } + + // This is equation before Table 5.4.2.1-1 in 38101-1-f30 + // F_REF=F_REF_Offs + deltaF_Global(N_REF-NREF_REF_Offs) + nrarfcn = (((dl_CarrierFreq_by_1k - F_REF_Offs_khz) / deltaFglobal) + N_REF_Offs); + //get_delta_arfcn(i, nrarfcn, nr_bandtable[i].N_OFFs_DL); + + return nrarfcn; +} + +// This function computes the RF reference frequency from the NR-ARFCN according to 5.4.2.1 of 3GPP TS 38.104 +// this function applies to both DL and UL +uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t nrarfcn) +{ + int deltaFglobal = 5; + uint32_t N_REF_Offs = 0; + uint64_t F_REF_Offs_khz = 0; + uint64_t N_OFFs, frequency, freq_min; + int i = get_nr_table_idx(nr_bandP, scs_index); + + if (nrarfcn > 599999 && nrarfcn < 2016667) { + deltaFglobal = 15; + N_REF_Offs = 600000; + F_REF_Offs_khz = 3000000; + } + if (nrarfcn > 2016666 && nrarfcn < 3279166) { + deltaFglobal = 60; + N_REF_Offs = 2016667; + F_REF_Offs_khz = 24250080; + } + + int32_t delta_duplex = get_delta_duplex(nr_bandP, scs_index); + + if (delta_duplex <= 0){ // DL band >= UL band + if (nrarfcn >= nr_bandtable[i].N_OFFs_DL){ // is TDD of FDD DL + N_OFFs = nr_bandtable[i].N_OFFs_DL; + freq_min = nr_bandtable[i].dl_min; + } else {// is FDD UL + N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal; + freq_min = nr_bandtable[i].ul_min; + } + } else { // UL band > DL band + if (nrarfcn >= nr_bandtable[i].N_OFFs_DL + delta_duplex / deltaFglobal){ // is FDD UL + N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex / deltaFglobal; + freq_min = nr_bandtable[i].ul_min; + } else { // is FDD DL + N_OFFs = nr_bandtable[i].N_OFFs_DL; + freq_min = nr_bandtable[i].dl_min; + } + } + + LOG_D(NR_MAC, "Frequency from NR-ARFCN for N_OFFs %lu, duplex spacing %d KHz, deltaFglobal %d KHz\n", + N_OFFs, + delta_duplex, + deltaFglobal); + + AssertFatal(nrarfcn >= N_OFFs,"nrarfcn %u < N_OFFs[%d] %llu\n", nrarfcn, nr_bandtable[i].band, (long long unsigned int)N_OFFs); + get_delta_arfcn(i, nrarfcn, N_OFFs); + + frequency = 1000 * (F_REF_Offs_khz + (nrarfcn - N_REF_Offs) * deltaFglobal); + + LOG_D(NR_MAC, "Computing frequency (nrarfcn %llu => %llu KHz (freq_min %llu KHz, NR band %d N_OFFs %llu))\n", + (unsigned long long)nrarfcn, + (unsigned long long)frequency/1000, + (unsigned long long)freq_min, + nr_bandP, + (unsigned long long)N_OFFs); + + return frequency; +} int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols) { diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 79e587221b..c76969a8e8 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -168,7 +168,8 @@ static inline int get_num_dmrs(uint16_t dmrs_mask ) { } uint64_t reverse_bits(uint64_t in, int n_bits); - +uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); +uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw); int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols); int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs); int get_SLIV(uint8_t S, uint8_t L); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 42090c2e9e..f370927378 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -132,6 +132,7 @@ typedef struct { uint16_t cell_id; uint16_t ssb_start_subcarrier; short rsrp_dBm; + long arfcn; rlm_t radiolink_monitoring; // -1 no monitoring, 0 out_of_sync, 1 in_sync } fapi_nr_ssb_pdu_t; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 9e6a8bf7e5..52fc2569bb 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -153,15 +153,7 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, stop_meas(&ue->dlsch_channel_estimation_stats); fapiPbch_t result = {0}; - ret = nr_rx_pbch(ue, - proc, - estimateSz, - dl_ch_estimates, - frame_parms, - temp_ptr->i_ssb, - SISO, - &result, - rxdataF); + ret = nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, temp_ptr->i_ssb, &result, rxdataF); if (DUMP_PBCH_CH_ESTIMATES && (ret == 0)) { write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, frame_parms->nb_antennas_rx*estimateSz, 1, 1); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index ed30c95fe0..52c9ec5394 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -361,7 +361,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, struct complex16 dl_ch_estimates[][estimateSz], NR_DL_FRAME_PARMS *frame_parms, uint8_t i_ssb, - MIMO_mode_t mimo_mode, fapiPbch_t *result, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { @@ -414,7 +413,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, symbol_offset, frame_parms); #ifdef DEBUG_PBCH - LOG_I(PHY,"[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size ); + LOG_I(PHY,"[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size); LOG_I(PHY,"[PHY] PBCH starting channel_level\n"); #endif @@ -441,14 +440,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, rxdataF_comp, symbol);*/ - /* - if (mimo_mode == ALAMOUTI) { - nr_pbch_alamouti(frame_parms,rxdataF_comp,symbol); - } else if (mimo_mode != SISO) { - LOG_I(PHY,"[PBCH][RX] Unsupported MIMO mode\n"); - return(-1); - } - */ int nb=symbol==2 ? 144 : 360; nr_pbch_quantize(pbch_e_rx+pbch_e_rx_idx, (short *)rxdataF_comp[0], diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 6888f36434..6e37549349 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -294,7 +294,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, struct complex16 dl_ch_estimates[][estimateSz], NR_DL_FRAME_PARMS *frame_parms, uint8_t i_ssb, - MIMO_mode_t mimo_mode, fapiPbch_t *result, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index be2c3b3093..7bb1683507 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -109,6 +109,14 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, } } +static uint32_t get_ssb_arfcn(NR_DL_FRAME_PARMS *frame_parms) +{ + uint32_t band_size_hz = frame_parms->N_RB_DL * 12 * frame_parms->subcarrier_spacing; + int ssb_center_sc = frame_parms->ssb_start_subcarrier + 120; // ssb is 20 PRBs -> 240 sub-carriers + uint64_t ssb_freq = frame_parms->dl_CarrierFreq - (band_size_hz / 2) + frame_parms->subcarrier_spacing * ssb_center_sc; + return to_nrarfcn(frame_parms->nr_band, ssb_freq, frame_parms->numerology_index, band_size_hz); +} + void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, uint8_t pdu_type, PHY_VARS_NR_UE *ue, @@ -168,6 +176,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, ssb_pdu->cell_id = frame_parms->Nid_cell; ssb_pdu->ssb_start_subcarrier = frame_parms->ssb_start_subcarrier; ssb_pdu->rsrp_dBm = ue->measurements.ssb_rsrp_dBm[frame_parms->ssb_index]; + ssb_pdu->arfcn = get_ssb_arfcn(frame_parms); ssb_pdu->radiolink_monitoring = RLM_in_sync; // TODO to be removed from here ssb_pdu->decoded_pdu = true; } @@ -384,7 +393,6 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, dl_ch_estimates, &ue->frame_parms, (ue->frame_parms.ssb_index)&7, - SISO, &result, rxdataF); diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index 3646e479d1..78906f5489 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -49,6 +49,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int slot, const rnti_t rnti, const uint32_t cellid, + const long arfcn, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; } diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index bfd23b7ffc..7d738c4ed7 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -797,15 +797,7 @@ int main(int argc, char **argv) } fapiPbch_t result; - ret = nr_rx_pbch(UE, - &proc, - estimateSz, - dl_ch_estimates, - frame_parms, - ssb_index%8, - SISO, - &result, - rxdataF); + ret = nr_rx_pbch(UE, &proc, estimateSz, dl_ch_estimates, frame_parms, ssb_index % 8, &result, rxdataF); if (ret==0) { //UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index 79d483891d..effdaacff3 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -120,6 +120,7 @@ typedef struct NRRrcMacBcchDataInd_s { uint8_t rsrq; uint8_t rsrp; uint32_t phycellid; + long ssb_arfcn; } NRRrcMacBcchDataInd; typedef struct NRRrcMacSBcchDataInd_s { diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index b2db504796..e9f052f20c 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2248,118 +2248,6 @@ static const uint16_t table_7_3_1_1_2_32[3][15] = { {0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }; -void get_delta_arfcn(int i, uint32_t nrarfcn, uint64_t N_OFFs) -{ - uint32_t delta_arfcn = nrarfcn - N_OFFs; - - if(delta_arfcn % (nr_bandtable[i].step_size) != 0) - LOG_E(NR_MAC, "nrarfcn %u is not on the channel raster for step size %lu\n", nrarfcn, nr_bandtable[i].step_size); -} - -uint32_t to_nrarfcn(int nr_bandP, - uint64_t dl_CarrierFreq, - uint8_t scs_index, - uint32_t bw) -{ - uint64_t dl_CarrierFreq_by_1k = dl_CarrierFreq / 1000; - int bw_kHz = bw / 1000; - uint32_t nrarfcn; - int i = get_nr_table_idx(nr_bandP, scs_index); - - LOG_I(NR_MAC,"Searching for nr band %d DL Carrier frequency %llu bw %u\n",nr_bandP,(long long unsigned int)dl_CarrierFreq,bw); - - AssertFatal(dl_CarrierFreq_by_1k >= nr_bandtable[i].dl_min, - "Band %d, bw %u : DL carrier frequency %llu kHz < %llu\n", - nr_bandP, bw, (long long unsigned int)dl_CarrierFreq_by_1k, - (long long unsigned int)nr_bandtable[i].dl_min); - AssertFatal(dl_CarrierFreq_by_1k <= (nr_bandtable[i].dl_max - bw_kHz/2), - "Band %d, dl_CarrierFreq %llu bw %u: DL carrier frequency %llu kHz > %llu\n", - nr_bandP, (long long unsigned int)dl_CarrierFreq,bw, (long long unsigned int)dl_CarrierFreq_by_1k, - (long long unsigned int)(nr_bandtable[i].dl_max - bw_kHz/2)); - - int deltaFglobal = 60; - uint32_t N_REF_Offs = 2016667; - uint64_t F_REF_Offs_khz = 24250080; - - if (dl_CarrierFreq < 24.25e9) { - deltaFglobal = 15; - N_REF_Offs = 600000; - F_REF_Offs_khz = 3000000; - } - if (dl_CarrierFreq < 3e9) { - deltaFglobal = 5; - N_REF_Offs = 0; - F_REF_Offs_khz = 0; - } - - // This is equation before Table 5.4.2.1-1 in 38101-1-f30 - // F_REF=F_REF_Offs + deltaF_Global(N_REF-NREF_REF_Offs) - nrarfcn = (((dl_CarrierFreq_by_1k - F_REF_Offs_khz)/deltaFglobal)+N_REF_Offs); - //get_delta_arfcn(i, nrarfcn, nr_bandtable[i].N_OFFs_DL); - - return nrarfcn; -} - -// This function computes the RF reference frequency from the NR-ARFCN according to 5.4.2.1 of 3GPP TS 38.104 -// this function applies to both DL and UL -uint64_t from_nrarfcn(int nr_bandP, - uint8_t scs_index, - uint32_t nrarfcn) -{ - int deltaFglobal = 5; - uint32_t N_REF_Offs = 0; - uint64_t F_REF_Offs_khz = 0; - uint64_t N_OFFs, frequency, freq_min; - int i = get_nr_table_idx(nr_bandP, scs_index); - - if (nrarfcn > 599999 && nrarfcn < 2016667) { - deltaFglobal = 15; - N_REF_Offs = 600000; - F_REF_Offs_khz = 3000000; - } - if (nrarfcn > 2016666 && nrarfcn < 3279166) { - deltaFglobal = 60; - N_REF_Offs = 2016667; - F_REF_Offs_khz = 24250080; - } - - int32_t delta_duplex = get_delta_duplex(nr_bandP, scs_index); - - if (delta_duplex <= 0){ // DL band >= UL band - if (nrarfcn >= nr_bandtable[i].N_OFFs_DL){ // is TDD of FDD DL - N_OFFs = nr_bandtable[i].N_OFFs_DL; - freq_min = nr_bandtable[i].dl_min; - } else {// is FDD UL - N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal; - freq_min = nr_bandtable[i].ul_min; - } - } else { // UL band > DL band - if (nrarfcn >= nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal){ // is FDD UL - N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal; - freq_min = nr_bandtable[i].ul_min; - } else { // is FDD DL - N_OFFs = nr_bandtable[i].N_OFFs_DL; - freq_min = nr_bandtable[i].dl_min; - } - } - - LOG_D(NR_MAC, "Frequency from NR-ARFCN for N_OFFs %lu, duplex spacing %d KHz, deltaFglobal %d KHz\n", N_OFFs, delta_duplex, deltaFglobal); - - AssertFatal(nrarfcn >= N_OFFs,"nrarfcn %u < N_OFFs[%d] %llu\n", nrarfcn, nr_bandtable[i].band, (long long unsigned int)N_OFFs); - get_delta_arfcn(i, nrarfcn, N_OFFs); - - frequency = 1000 * (F_REF_Offs_khz + (nrarfcn - N_REF_Offs) * deltaFglobal); - - LOG_D(NR_MAC, "Computing frequency (nrarfcn %llu => %llu KHz (freq_min %llu KHz, NR band %d N_OFFs %llu))\n", - (unsigned long long)nrarfcn, - (unsigned long long)frequency/1000, - (unsigned long long)freq_min, - nr_bandP, - (unsigned long long)N_OFFs); - - return frequency; -} - void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, int x_overhead, uint8_t numdmrscdmgroupnodata, diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 820cbfceeb..33077c6ce2 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -55,10 +55,6 @@ uint32_t get_Y(const NR_SearchSpace_t *ss, int slot, rnti_t rnti); uint8_t get_BG(uint32_t A, uint16_t R); -uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); - -uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw); - int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config, int dci_format, int dmrs_TypeA_Position, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 2f6d5f084f..f2db3cfa53 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -264,7 +264,7 @@ int8_t nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, { if(ack_nack) { LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); - nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, mac->physCellId, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); + nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); mac->get_sib1 = false; mac->get_otherSI = false; } diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 2f0892b66f..7557608bd4 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -1039,6 +1039,7 @@ static int handle_bcch_bch(NR_UE_MAC_INST_t *mac, uint32_t ssb_index, uint32_t ssb_length, uint16_t ssb_start_subcarrier, + long ssb_arfcn, uint16_t cell_id) { mac->mib_ssb = ssb_index; @@ -1049,7 +1050,7 @@ static int handle_bcch_bch(NR_UE_MAC_INST_t *mac, else mac->frequency_range = FR1; // fixed 3 bytes MIB PDU - nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, cell_id, NR_BCCH_BCH, (uint8_t *) pduP, 3); + nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, cell_id, ssb_arfcn, NR_BCCH_BCH, (uint8_t *) pduP, 3); return 0; } @@ -1228,6 +1229,7 @@ static uint32_t nr_ue_dl_processing(nr_downlink_indication_t *dl_info) rx_indication_body.ssb_pdu.ssb_index, rx_indication_body.ssb_pdu.ssb_length, rx_indication_body.ssb_pdu.ssb_start_subcarrier, + rx_indication_body.ssb_pdu.arfcn, rx_indication_body.ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB; } break; diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 1e93cc935e..2958609fda 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -55,6 +55,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int slot, const rnti_t rnti, const uint32_t cellid, + const long arfcn, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) @@ -86,6 +87,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index; NR_RRC_MAC_BCCH_DATA_IND (message_p).phycellid = cellid; + NR_RRC_MAC_BCCH_DATA_IND (message_p).ssb_arfcn = arfcn; NR_RRC_MAC_BCCH_DATA_IND (message_p).is_bch = (channel == NR_BCCH_BCH); 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_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 069ac2c825..9edf7d5c4e 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -429,11 +429,13 @@ int check_si_status(NR_UE_RRC_SI_INFO *SI_info) static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, const uint8_t gNB_index, const uint32_t phycellid, + const long ssb_arfcn, uint8_t *const bufferP, const uint8_t buffer_len) { NR_BCCH_BCH_Message_t *bcch_message = NULL; rrc->phyCellID = phycellid; + rrc->arfcn_ssb = ssb_arfcn; asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, @@ -800,6 +802,11 @@ void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t if(spCellConfig != NULL) { if (spCellConfig->reconfigurationWithSync != NULL) { NR_ReconfigurationWithSync_t *reconfigurationWithSync = spCellConfig->reconfigurationWithSync; + if (reconfigurationWithSync->spCellConfigCommon && + reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon && + reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon->frequencyInfoDL && + reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB) + rrc->arfcn_ssb = *reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB; // perform Reconfiguration with sync according to 5.3.5.5.2 if (!rrc->as_security_activated && rrc->nrRrcState != RRC_STATE_IDLE_NR) { // perform the actions upon going to RRC_IDLE as specified in 5.3.11 @@ -1336,9 +1343,7 @@ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc, // int nh = rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount; // update the K gNB key based on the current K gNB key or the NH, using the stored nextHopChainingCount value - /* TODO: retrieve absoluteFrequencySSB correctly */ - int absoluteFrequencySSB = 621312; - nr_derive_key_ng_ran_star(rrc->phyCellID, absoluteFrequencySSB, rrc->kgnb, rrc->kgnb); + nr_derive_key_ng_ran_star(rrc->phyCellID, rrc->arfcn_ssb, rrc->kgnb, rrc->kgnb); // derive the K RRCenc and K UPenc keys associated with the previously configured cipheringAlgorithm // derive the K RRCint and K UPint keys associated with the previously configured integrityProtAlgorithm @@ -1543,7 +1548,7 @@ void *rrc_nrue(void *notUsed) LOG_D(NR_RRC, "[UE %ld] Received %s: gNB %d\n", rrc->ue_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); if (bcch->is_bch) - nr_rrc_ue_decode_NR_BCCH_BCH_Message(rrc, bcch->gnb_index, bcch->phycellid, bcch->sdu, bcch->sdu_size); + nr_rrc_ue_decode_NR_BCCH_BCH_Message(rrc, bcch->gnb_index, bcch->phycellid, bcch->ssb_arfcn, bcch->sdu, bcch->sdu_size); else nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(rrc, bcch->gnb_index, bcch->sdu, bcch->sdu_size, bcch->rsrq, bcch->rsrp); break; diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 40cbca3ad5..df9533ce65 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -187,6 +187,7 @@ typedef struct NR_UE_RRC_INST_s { rnti_t rnti; uint32_t phyCellID; + long arfcn_ssb; OAI_NR_UECapability_t UECap; NR_UE_Timers_Constants_t timers_and_constants; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index fa8eee3830..556898c304 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -74,6 +74,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int slot, const rnti_t rnti, const uint32_t cellid, + const long arfcn, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len); From f15606e8ade1cece59c50443bfa1cde79de32c05 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 31 Jan 2024 16:03:34 +0100 Subject: [PATCH 22/35] handle reestablishPDCP in RadioBearerConfig --- openair2/RRC/NR_UE/rrc_UE.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 9edf7d5c4e..11b9f0102e 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1225,8 +1225,10 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, if (LOG_DEBUGFLAG(DEBUG_ASN1)) xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)radioBearerConfig); - if (radioBearerConfig->srb3_ToRelease) + if (radioBearerConfig->srb3_ToRelease) { nr_pdcp_release_srb(ue_rrc->ue_id, 3); + ue_rrc->Srb[3] = RB_NOT_PRESENT; + } uint8_t kRRCenc[NR_K_KEY_SIZE] = {0}; uint8_t kRRCint[NR_K_KEY_SIZE] = {0}; @@ -1251,7 +1253,8 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, 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]; - if (ue_rrc->Srb[srb->srb_Identity] == RB_NOT_PRESENT) + if (ue_rrc->Srb[srb->srb_Identity] == RB_NOT_PRESENT) { + ue_rrc->Srb[srb->srb_Identity] = RB_ESTABLISHED; add_srb(false, ue_rrc->ue_id, radioBearerConfig->srb_ToAddModList->list.array[cnt], @@ -1259,21 +1262,28 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, 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->reestablishPDCP) { + ue_rrc->Srb[srb->srb_Identity] = RB_ESTABLISHED; + nr_pdcp_reestablishment(ue_rrc->ue_id, srb->srb_Identity, true); + // TODO configure the PDCP entity to apply the integrity protection algorithm + // TODO configure the PDCP entity to apply the ciphering algorithm + } if (srb->pdcp_Config && srb->pdcp_Config->t_Reordering) nr_pdcp_reconfigure_srb(ue_rrc->ue_id, srb->srb_Identity, *srb->pdcp_Config->t_Reordering); } - ue_rrc->Srb[srb->srb_Identity] = 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) + if (DRB_id) { nr_pdcp_release_drb(ue_rrc->ue_id, *DRB_id); + set_DRB_status(ue_rrc, *DRB_id, RB_NOT_PRESENT); + } } } @@ -1285,9 +1295,13 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, 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; - /* DRB is already established and configured */ - if (get_DRB_status(ue_rrc, DRB_id) == RB_ESTABLISHED) { - AssertFatal(drb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n"); + if (get_DRB_status(ue_rrc, DRB_id) != RB_NOT_PRESENT) { + if (drb->reestablishPDCP) { + set_DRB_status(ue_rrc, DRB_id, RB_ESTABLISHED); + nr_pdcp_reestablishment(ue_rrc->ue_id, DRB_id, false); + // TODO configure the PDCP entity to apply the integrity protection algorithm + // TODO configure the PDCP entity to apply the ciphering algorithm + } AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n"); /* sdap-Config is included (SA mode) */ NR_SDAP_Config_t *sdap_Config = drb->cnAssociation ? drb->cnAssociation->choice.sdap_Config : NULL; From c9cf72b33fd974e6260848d5735de16d1fed2c84 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 4 Mar 2024 12:01:05 +0100 Subject: [PATCH 23/35] RRCSetup fallback after re-establishment not implemented -> go back to IDLE --- openair2/RRC/NR_UE/rrc_UE.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 11b9f0102e..50ca63e178 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -904,6 +904,11 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc, // if the RRCSetup is received in response to an RRCReestablishmentRequest // or RRCResumeRequest or RRCResumeRequest1 // TODO none of the procedures implemented yet + if (rrc->ra_trigger == RRC_CONNECTION_REESTABLISHMENT) { + LOG_E(NR_RRC, "Handling of RRCSetup in response of RRCReestablishment not implemented yet. Going back to IDLE.\n"); + nr_rrc_going_to_IDLE(rrc, OTHER, NULL); + return; + } // perform the cell group configuration procedure in accordance with the received masterCellGroup nr_rrc_ue_process_masterCellGroup(rrc, From 51d60c2daec3d2b1e0fc61965b878f9e08e9a3da Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 14 Mar 2024 13:54:23 +0100 Subject: [PATCH 24/35] let the gNB print a LOG with the UE command line parameters to simplfy the life of the users --- doc/RUNMODEM.md | 6 ++++ openair1/PHY/INIT/nr_parms.c | 13 +++----- openair1/PHY/INIT/nr_phy_init.h | 2 +- openair1/PHY/defs_nr_common.h | 1 + openair1/SCHED_NR/phy_procedures_nr_gNB.c | 40 +++++++++++++++++------ 5 files changed, 43 insertions(+), 19 deletions(-) diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index e3790114a3..d6f504af1b 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -102,6 +102,12 @@ 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. + +``` +[PHY] Command line parameters for the UE: -C 3319680000 -r 106 --numerology 1 --band 78 --ssb 516 +``` + You can run this, using USRPs, on two separate machines: ``` diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 02141f4ff3..5b45bbc8f9 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -212,22 +212,20 @@ uint32_t get_samples_slot_timestamp(int slot, const NR_DL_FRAME_PARMS *fp, uint8 return samp_count; } -int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, - NR_DL_FRAME_PARMS *fp) +void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS *fp) { - AssertFatal (cfg != NULL, "%s %s:%i Null pointer to cfg %p!\n", __FUNCTION__, __FILE__, __LINE__, cfg); + AssertFatal (cfg, "Null pointer to cfg!\n"); fp->frame_type = cfg->cell_config.frame_duplex_type.value; - fp->L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ; + fp->L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value) << 32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value; fp->N_RB_DL = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value; fp->N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; int Ncp = NFAPI_CP_NORMAL; int mu = cfg->ssb_config.scs_common.value; - - LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, fp->N_RB_DL, Ncp); + LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n", mu, fp->N_RB_DL, Ncp); if (Ncp == NFAPI_CP_EXTENDED) AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu); @@ -266,8 +264,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, for (int p=0; pN_ssb += ((fp->L_ssb >> (63-p)) & 0x01); - return 0; - + fp->print_ue_help_cmdline_log = true; } int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, diff --git a/openair1/PHY/INIT/nr_phy_init.h b/openair1/PHY/INIT/nr_phy_init.h index 0d5170b05e..5e36558e2b 100644 --- a/openair1/PHY/INIT/nr_phy_init.h +++ b/openair1/PHY/INIT/nr_phy_init.h @@ -26,7 +26,7 @@ #include "PHY/defs_nr_UE.h" int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb); -int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); +void nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band); void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band); void nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *frame_parms, uint64_t sidelink_frequency, uint16_t nr_band); diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 72233f58cf..e99bcddaba 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -261,6 +261,7 @@ struct NR_DL_FRAME_PARMS { uint32_t ofdm_offset_divisor; uint16_t tdd_slot_config; uint8_t tdd_period; + bool print_ue_help_cmdline_log; }; // PRS config structures diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 87cdff15ab..a7b9e5d120 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -45,26 +45,25 @@ extern uint8_t nfapi_mode; -void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu) { - - NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; +void nr_common_signal_procedures(PHY_VARS_gNB *gNB,int frame,int slot, nfapi_nr_dl_tti_ssb_pdu ssb_pdu) +{ + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; c16_t **txdataF = gNB->common_vars.txdataF; - uint8_t ssb_index, n_hf; - uint16_t ssb_start_symbol; + uint8_t n_hf; int txdataF_offset = slot*fp->samples_per_slot_wCP; - uint16_t slots_per_hf = (fp->slots_per_frame)>>1; + uint16_t slots_per_hf = (fp->slots_per_frame) >> 1; if (slotsymbols_per_slot; // start symbol wrt slot + int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp, ssb_index); // computing the starting symbol for current ssb + uint16_t ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot // Setting the first subcarrier // 3GPP TS 38.211 sections 7.4.3.1 and 4.4.4.2 @@ -77,6 +76,27 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_ const int sc_offset = (fp->freq_range == nr_FR1) ? ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset >> scs : ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset; fp->ssb_start_subcarrier = (12 * prb_offset + sc_offset); + + if (fp->print_ue_help_cmdline_log && get_softmodem_params()->sa) { + 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", + 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", + fp->dl_CarrierFreq, + fp->N_RB_DL, + scs, + fp->nr_band, + fp->ssb_start_subcarrier); + } LOG_D(PHY, "ssbOffsetPointA %d SSB SsbSubcarrierOffset %d prb_offset %d sc_offset %d scs %d ssb_start_subcarrier %d\n", ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA, From b7a98b77c39ce1b644361771cb987c6c339e097c Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 11 Mar 2024 17:26:55 +0100 Subject: [PATCH 25/35] Enhancements to traffic flow in SW architecture documentation --- doc/SW_archi.md | 142 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 120 insertions(+), 22 deletions(-) diff --git a/doc/SW_archi.md b/doc/SW_archi.md index 4f80c98dcd..277b4e3a9e 100644 --- a/doc/SW_archi.md +++ b/doc/SW_archi.md @@ -306,15 +306,6 @@ but it returns void. It could return the initialized pointer (as FILE* fopen() for example), then the RLC layer could have multiple instances in one process. Even, a future evolution could remove this global rlc layer: rlc can be only a library that we create a instance for each UE because it doesn't shareany data between UEs. -For DL (respectively from UL in UE), the scheduler need to know the quantity of data waitin to be sent: it calls mac_rlc_status_ind() -That "peek" the size of the waiting data for a UE. -The scheduler then push orders to lower layers. The transport layer will actually pull data from RLC with: mac_rlc_data_req() -the low layer push data into rlc by: mac_rlc_data_ind() -Still on DL (gNB side), PDCP push incoming data into RLC by calling: rlc_data_req() - -For UL, the low layer push data into rlc by: mac_rlc_data_ind() -Then, rlc push it to pdcp by calling pdcp_data_ind() from a complex rlc internal call back (deliver_sdu()) - When adding a UE, external code have to call `add_rlc_srb()` and/or `add_rlc_drb()`, to remove it: `rrc_rlc_remove_ue()` Inside UE, channels called drd or srb can be created: ??? and deleted: rrc_rlc_config_req() @@ -322,26 +313,133 @@ nr_rlc_tick() must be called periodically to manage the internal timers successful_delivery() and max_retx_reached(): in ??? trigger, the RLC sends a itti message to RRC: RLC_SDU_INDICATION (neutralized by #if 0 right now) -#PDCP +## RLC data flow -The PDCP implementation is also protected through a general mutex. -The design is very similar to rlc layer. The pdcp data is isolated and encapsulated. +### TX Flow -nr_pdcp_layer_init(): same as rlc init -we have to call a second init function: pdcp_module_init() +Incoming data to be transmitted is forwarded to RLC by PDCP via `rlc_data_req()`. -At Tx side (DL in gNB), `pdcp_data_req_drb()` and `pdcp_data_req_srb()` are the entry functions that the upper layer calls. -The upper layer can be GTP or a PDCP internal thread enb_tun_read_thread() that read directly from Linux socket in case we skip 3GPP core implementation. -PDCP internals for nr_pdcp_data_req_srb()/nr_pdcp_data_req_drb() are thread safe: inside them, the pdcp manager protects with the mutex the access to the SDU receiving function of PDCP (recv_sdu() callback, corresponding to nr_pdcp_entity_drb_am_recv_sdu() for DRBs). When it needs, the pdcp layer push this data to rlc by calling : rlc_data_req() +At the transport layer, in downlink (DL) at the gNB and uplink (UL) at UE, the scheduler relies on knowing the quantity of data awaiting transmissionis, therefore is using the following MAC/RLC interface functions: -At Rx side, pdcp_data_ind() is the entry point that receives the data from RLC. -- Inside pdcp_data_ind(), the pdcp manager mutex protects the access to the PDU receiving function of PDCP (recv_pdu() callback corresponding to nr_pdcp_entity_drb_am_recv_pdu() for DRBs) -- Then deliver_sdu_drb() function sends the received data to GTP thread through an ITTI message (GTPV1U_TUNNEL_DATA_REQ). +* `mac_rlc_data_req()` to retrieve data bytes to be transmitted by RLC and to fill the MAC SDU +* `mac_rlc_status_ind()` to request and set the number of bytes scheduled for transmission by the RLC + +Subsequently, the scheduler issues commands to lower layers. + +### RX Flow + +In the RX chain, in downlink (DL) at the UE and uplink (UL) at gNB, the transport layer pushes data into RLC through `mac_rlc_data_ind()`. Following this, RLC forwards the data to PDCP by invoking `pdcp_data_ind()` via a complex internal callback mechanism (`deliver_sdu()`). + +# PDCP + +The PDCP implementation is secured by a general mutex, akin to the design of the RLC layer. This setup ensures that PDCP data remains isolated and encapsulated. + +Initialization of the PDCP layer follows a structure similar to that of the RLC layer. The function `nr_pdcp_layer_init()` initializes PDCP, while a second initialization function, `pdcp_module_init()`, must also be invoked. + +To manage UE connections, `nr_pdcp_add_srbs()` is employed for adding UE SRBs in PDCP, while `nr_pdcp_remove_UE()` is used for their removal. Similarly, `nr_pdcp_add_drbs()` adds UE DRBs in PDCP, with `nr_pdcp_remove_UE()` handling their removal. + +## PDCP Tx flow + +On the Tx side (downlink in gNB), the entry functions `nr_pdcp_data_req_drb()` and `nr_pdcp_data_req_srb()` are called by the upper layer. The upper layer could be GTP or a PDCP internal thread like `enb_tun_read_thread()`, which reads directly from the Linux socket if the 3GPP core implementation is skipped. The PDCP internals for `nr_pdcp_data_req_srb()` and `nr_pdcp_data_req_drb()` are thread-safe. Within these functions, the PDCP manager protects access to the SDU receiving function of PDCP (`recv_sdu()` callback, corresponding to `nr_pdcp_entity_recv_pdu()` for DRBs) using mutex. When necessary, the PDCP layer pushes this data to RLC by calling `rlc_data_req()`. + +## PDCP Rx flow + +At the Rx side, `pdcp_data_ind()` serves as the entry point for receiving data from RLC. Within `pdcp_data_ind()`, the PDCP manager mutex protects access to the PDU receiving function of PDCP (`recv_pdu()` callback corresponding to `nr_pdcp_entity_recv_pdu()` for DRBs). Following this, the `deliver_sdu_drb()` function dispatches the received data to the GTP thread via an ITTI message (`GTPV1U_TUNNEL_DATA_REQ`). + +## PDCP security nr_pdcp_config_set_security(): sets the keys for AS security of a UE -nr_pdcp_add_srbs() adds UE SRBs in pdcp, nr_pdcp_remove_UE() removes it -nr_pdcp_add_drbs() adds UE DRBs in pdcp, nr_pdcp_remove_UE() removes it +# AM DRB traffic flow in OAI + +A sequence diagram of the traffic flow across PDCP and RLC layers. By default, data traffic is directed towards AM DRBs. + +This is the flow for downlink, involving MAC and upper layers: + +```mermaid + sequenceDiagram + title Downlink AM DRB traffic flow + box Purple gNB + participant GG as GTP / TUN + participant SG as SDAP + participant PG as PDCP + participant RG as RLC + participant MG as MAC + end + GG->>SG: sdap_data_req + note over SG: nr_sdap_tx_entity + SG->>PG: nr_pdcp_data_req_drb + note over PG: deliver_pdu_drb_gnb + note over PG: nr_pdcp_entity_process_sdu + note over PG: enqueue_rlc_data_req + PG->>RG: rlc_data_req via rlc_data_req_thread + note over RG: nr_rlc_entity_am_recv_sdu + MG-->>RG: mac_rlc_data_req + note over RG: nr_rlc_entity_am_generate_pdu + note over RG: generate_tx_pdu + note over RG: serialize_sdu + RG-->>MG: PDU to MAC + MG-->MUE: UL TX / RX procedures + box Blue UE + participant MUE as MAC + participant RUE as RLC + participant PUE as PDCP + participant SUE as SDAP + participant GUE as GTP / TUN + end + MUE-->>RUE: SDU to RLC + RUE->>PUE: pdcp_data_ind + note over PUE: nr_pdcp_entity_recv_pdu + note over PUE: deliver_sdu_drb + PUE->>SUE: sdap_data_ind + note over SUE: nr_sdap_rx_entity + SUE->>GUE: send to GTP-U +``` +and for uplink: + +```mermaid + sequenceDiagram + title Uplink AM DRB traffic flow + box Blue UE + participant GUE as GTP / TUN + participant SUE as SDAP + participant PUE as PDCP + participant RUE as RLC + participant MUE as MAC + end + GUE->>SUE: sdap_data_req + note over SUE: nr_sdap_tx_entity + SUE->>PUE: nr_pdcp_data_req_drb + note over PUE: process_sdu + note over PUE: deliver_pdu_drb_ue + note over PUE: enqueue_rlc_data_req + note over PUE: signal to rlc_data_req_thread + PUE->>RUE: rlc_data_req + note over RUE: nr_rlc_entity_am_recv_sdu + RUE-->>MUE: PDU to MAC + note over MUE: nr_ue_get_sdu + MUE-->MG: UL TX / RX procedures + box Purple gNB + participant MG as MAC + participant RG as RLC + participant PG as PDCP + participant SG as SDAP + participant GG as GTP / TUN + end + MG->>RG: mac_rlc_data_ind + note over RG: nr_rlc_entity_am_recv_pdu + note over RG: reception_actions + note over RG: reassemble_and_deliver + note over RG: deliver_sdu + RG->>PG: pdcp_data_ind + note over PG: enqueue_pdcp_data_ind + note over PG: do_pdcp_data_ind via pdcp_data_ind_thread + note over PG: nr_pdcp_entity_recv_pdu + note over PG: deliver_sdu_drb + PG->>SG: sdap_data_ind + note over SG: nr_sdap_rx_entity + SG->>GG: send to GTP-U +``` # GTP Gtp + UDP are two twin threads performing the data plane interface to the core network From a645e10ff56b2f956c3f3f54b2231e82131783a0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 14 Feb 2024 10:46:50 +0100 Subject: [PATCH 26/35] F1AP: message encoders should no trigger GTP The F1AP message encoders and decoders should do only that, encoding and decoding messages. For the actual logic handling, including set up and teardown of bearers, we should use the handlers. In this commit, delete GTP tunnel handling from encoders/decoders. For the CU, this happens already in the CU-UP/E1 handlers in cucp_cuup_handler.c. For the DU, add it in the handlers in mac_rrc_dl_handler.c. --- openair2/F1AP/f1ap_cu_ue_context_management.c | 29 +----- openair2/F1AP/f1ap_du_ue_context_management.c | 57 +++--------- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 88 ++++++++++++++++++- 3 files changed, 99 insertions(+), 75 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index cc29a92ebb..bed69ae455 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -38,8 +38,6 @@ #include "rrc_extern.h" #include "openair2/RRC/NR/rrc_gNB_NGAP.h" -#include -#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h" static void setQos(F1AP_NonDynamic5QIDescriptor_t **toFill) { @@ -503,19 +501,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { - /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/ - /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */ - transport_layer_addr_t addr = { .length= 32, .buffer= { 0 } }; - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst, - f1ap_ue_context_setup_req->gNB_CU_ue_id, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, - 0xFFFF, // We will set the right value from DU answer - -1, // no qfi - addr, // We will set the right value from DU answer - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port, - cu_f1u_data_req, - NULL); + DevAssert(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid > 0); /* 12.3.1 ULTunnels_ToBeSetup_Item */ asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list, F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); @@ -688,11 +674,6 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_ F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); - GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst, - f1ap_ue_context_setup_resp->gNB_DU_ue_id, - (ebi_t)drbs_setup_item_p->dRBID, - drb_p->up_dl_tnl[0].tl_address, - drb_p->up_dl_tnl[0].teid); } } @@ -1569,9 +1550,6 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte &drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item; /* dRBID */ drbs_toBeReleased_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id; - newGtpuDeleteOneTunnel(getCxt(0)->gtpInst, - f1ap_ue_context_modification_req->gNB_CU_ue_id, - f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id); } } @@ -1644,11 +1622,6 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); - GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst, - f1ap_ue_context_modification_resp->gNB_CU_ue_id, - (ebi_t)drbs_setupmod_item_p->dRBID, - drb_p->up_dl_tnl[0].tl_address, - drb_p->up_dl_tnl[0].teid); } } // SRBs_FailedToBeSetupMod_List diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index e306463b66..e175b215bb 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -40,24 +40,6 @@ #include #include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h" -bool DURecvCb(protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) -{ - // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue - uint8_t *sdu = malloc16(sdu_buffer_sizeP); - memcpy(sdu, sdu_buffer_pP, sdu_buffer_sizeP); - du_rlc_data_req(ctxt_pP, srb_flagP, false, rb_idP, muiP, confirmP, sdu_buffer_sizeP, sdu); - return true; -} - int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { F1AP_UEContextSetupRequest_t *container; @@ -305,6 +287,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set ie7->criticality = F1AP_Criticality_ignore; ie7->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List; for (int i=0; i< resp->drbs_to_be_setup_length; i++) { + f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i]; // asn1cSequenceAdd(ie7->value.choice.DRBs_Setup_List.list, F1AP_DRBs_Setup_ItemIEs_t, drbs_setup_item_ies); @@ -315,14 +298,17 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set /* ADD */ F1AP_DRBs_Setup_Item_t *drbs_setup_item=&drbs_setup_item_ies->value.choice.DRBs_Setup_Item; /* dRBID */ - drbs_setup_item->dRBID = resp->drbs_to_be_setup[i].drb_id; + drbs_setup_item->dRBID = drb->drb_id; /* OPTIONAL */ /* lCID */ //drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t)); //drbs_setup_item.lCID = 1L; - for (int j=0; jdrbs_to_be_setup[i].up_dl_tnl_length; j++) { + for (int j = 0; j < drb->up_dl_tnl_length; j++) { + const f1ap_up_tnl_t *tnl = &drb->up_dl_tnl[j]; + DevAssert(tnl->teid > 0); + /* ADD */ asn1cSequenceAdd(drbs_setup_item->dLUPTNLInformation_ToBeSetup_List.list, F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); @@ -330,12 +316,9 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set /* gTPTunnel */ asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); /* transportLayerAddress */ - struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, - &gTPTunnel->transportLayerAddress); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ - INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID); } // for j } // for i @@ -1008,7 +991,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t DevAssert(tbrel->id == F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item); DevAssert(tbrel->value.present == F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item); f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id = tbrel->value.choice.DRBs_ToBeReleased_Item.dRBID; - newGtpuDeleteOneTunnel(0, f1ap_ue_context_modification_req->gNB_DU_ue_id, f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id); } } @@ -1166,20 +1148,8 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_cont drbs_setupmod_item->dRBID = resp->drbs_to_be_setup[i].drb_id; for (int j=0; jdrbs_to_be_setup[i].up_dl_tnl_length; j++) { - f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i]; - transport_layer_addr_t tl_addr = {0}; - memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address)); - tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8; - drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst, - resp->gNB_DU_ue_id, - drb->drb_id, - drb->drb_id, - drb->up_ul_tnl[j].teid, - -1, // no qfi - tl_addr, - drb->up_ul_tnl[0].port, - DURecvCb, - NULL); + const f1ap_up_tnl_t *tnl = &resp->drbs_to_be_setup[i].up_dl_tnl[j]; + DevAssert(tnl->teid > 0); /* ADD */ asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list, @@ -1188,12 +1158,9 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_cont /* gTPTunnel */ asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); /* transportLayerAddress */ - struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, - &gTPTunnel->transportLayerAddress); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ - INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID); } // for j } // for i } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 04f2c2fdc9..44c7839463 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -23,8 +23,11 @@ #include "mac_proto.h" #include "openair2/F1AP/f1ap_ids.h" +#include "openair2/F1AP/f1ap_common.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "F1AP_CauseRadioNetwork.h" +#include "openair3/ocp-gtpu/gtp_itf.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h" #include "uper_decoder.h" #include "uper_encoder.h" @@ -34,6 +37,59 @@ const uint64_t qos_fiveqi[26] = {1, 2, 3, 4, 65, 66, 67, 71, 72, 73, 74, 76, 5, const uint64_t qos_priority[26] = {20, 40, 30, 50, 7, 20, 15, 56, 56, 56, 56, 56, 10, 60, 70, 80, 90, 5, 55, 65, 68, 19, 22, 24, 21, 18}; +static instance_t get_f1_gtp_instance(void) +{ + const f1ap_cudu_inst_t *inst = getCxt(0); + if (!inst) + return -1; // means no F1 + return inst->gtpInst; +} + +static int drb_gtpu_create(instance_t instance, + uint32_t ue_id, + int incoming_id, + int outgoing_id, + int qfi, + in_addr_t tlAddress, // only IPv4 now + teid_t outgoing_teid, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP, + gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp) +{ + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0}; + create_tunnel_req.incoming_rb_id[0] = incoming_id; + create_tunnel_req.pdusession_id[0] = outgoing_id; + memcpy(&create_tunnel_req.dst_addr[0].buffer, &tlAddress, sizeof(uint8_t) * 4); + create_tunnel_req.dst_addr[0].length = 32; + create_tunnel_req.outgoing_teid[0] = outgoing_teid; + create_tunnel_req.outgoing_qfi[0] = qfi; + create_tunnel_req.num_tunnels = 1; + create_tunnel_req.ue_id = ue_id; + + // we use gtpv1u_create_ngu_tunnel because it returns the interface + // address and port of the interface; apart from that, we also might call + // newGtpuCreateTunnel() directly + return gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, callBack, callBackSDAP); +} + +bool DURecvCb(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id) +{ + // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue + uint8_t *sdu = malloc16(sdu_buffer_sizeP); + memcpy(sdu, sdu_buffer_pP, sdu_buffer_sizeP); + du_rlc_data_req(ctxt_pP, srb_flagP, false, rb_idP, muiP, confirmP, sdu_buffer_sizeP, sdu); + return true; +} + static long get_lcid_from_drbid(int drb_id) { return drb_id + 3; /* LCID is DRB + 3 */ @@ -133,6 +189,7 @@ static int handle_ue_context_drbs_setup(int rnti, NR_CellGroupConfig_t *cellGroupConfig) { DevAssert(req_drbs != NULL && resp_drbs != NULL && cellGroupConfig != NULL); + instance_t f1inst = get_f1_gtp_instance(); /* Note: the actual GTP tunnels are created in the F1AP breanch of * ue_context_*_response() */ @@ -140,12 +197,32 @@ static int handle_ue_context_drbs_setup(int rnti, AssertFatal(*resp_drbs != NULL, "out of memory\n"); for (int i = 0; i < drbs_len; i++) { const f1ap_drb_to_be_setup_t *drb = &req_drbs[i]; + f1ap_drb_to_be_setup_t *resp_drb = &(*resp_drbs)[i]; NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb); nr_rlc_add_drb(rnti, drb->drb_id, rlc_BearerConfig); - (*resp_drbs)[i] = *drb; + *resp_drb = *drb; // just put same number of tunnels in DL as in UL - (*resp_drbs)[i].up_dl_tnl_length = drb->up_ul_tnl_length; + DevAssert(drb->up_ul_tnl_length == 1); + resp_drb->up_dl_tnl_length = drb->up_ul_tnl_length; + + if (f1inst >= 0) { // we actually use F1-U + int qfi = -1; // don't put PDU session marker in GTP + gtpv1u_gnb_create_tunnel_resp_t resp_f1 = {0}; + int ret = drb_gtpu_create(f1inst, + rnti, + drb->drb_id, + drb->drb_id, + qfi, + drb->up_ul_tnl[0].tl_address, + drb->up_ul_tnl[0].teid, + DURecvCb, + NULL, + &resp_f1); + AssertFatal(ret >= 0, "Unable to create GTP Tunnel for F1-U\n"); + memcpy(&resp_drb->up_dl_tnl[0].tl_address, &resp_f1.gnb_addr.buffer, 4); + resp_drb->up_dl_tnl[0].teid = resp_f1.gnb_NGu_teid[0]; + } int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); DevAssert(ret == 0); @@ -159,6 +236,7 @@ static int handle_ue_context_drbs_release(int rnti, NR_CellGroupConfig_t *cellGroupConfig) { DevAssert(req_drbs != NULL && cellGroupConfig != NULL); + instance_t f1inst = get_f1_gtp_instance(); cellGroupConfig->rlc_BearerToReleaseList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToReleaseList)); AssertFatal(cellGroupConfig->rlc_BearerToReleaseList != NULL, "out of memory\n"); @@ -178,6 +256,8 @@ static int handle_ue_context_drbs_release(int rnti, } if (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) { nr_rlc_release_entity(rnti, lcid); + if (f1inst >= 0) + newGtpuDeleteOneTunnel(f1inst, rnti, drb->rb_id); asn_sequence_del(&cellGroupConfig->rlc_BearerToAddModList->list, idx, 1); long *plcid = malloc(sizeof(*plcid)); AssertFatal(plcid != NULL, "out of memory\n"); @@ -557,6 +637,10 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) return; } + instance_t f1inst = get_f1_gtp_instance(); + if (f1inst >= 0) + newGtpuDeleteAllTunnels(f1inst, cmd->gNB_DU_ue_id); + if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) { /* The UE is already not connected anymore or we have nothing to forward*/ nr_mac_release_ue(mac, cmd->gNB_DU_ue_id); From a1f40006ce1a34155002d83d1bddf101dd7d96be Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 11 Mar 2024 11:49:23 +0100 Subject: [PATCH 27/35] Move GTP initialization to DU F1 initialization --- openair2/F1AP/f1ap_du_task.c | 14 ++++++++ openair2/F1AP/f1ap_du_ue_context_management.c | 32 ------------------- 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index d823a35092..c2f690107c 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -40,6 +40,16 @@ //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; +static instance_t du_create_gtpu_instance_to_cu(const f1ap_net_config_t *nc) +{ + openAddr_t tmp = {0}; + strncpy(tmp.originHost, nc->DU_f1_ip_address.ipv4_address, sizeof(tmp.originHost) - 1); + strncpy(tmp.destinationHost, nc->CU_f1_ip_address.ipv4_address, sizeof(tmp.destinationHost) - 1); + sprintf(tmp.originService, "%d", nc->DUport); + sprintf(tmp.destinationService, "%d", nc->CUport); + return gtpv1Init(tmp); +} + void du_task_send_sctp_association_req(instance_t instance, f1ap_net_config_t *nc) { DevAssert(nc != NULL); @@ -116,6 +126,10 @@ void *F1AP_DU_task(void *arg) { f1ap_net_config_t *nc = &F1AP_DU_REGISTER_REQ(msg).net_config; createF1inst(myInstance, msgSetup, nc); du_task_send_sctp_association_req(myInstance, nc); + instance_t gtpInst = du_create_gtpu_instance_to_cu(nc); + AssertFatal(gtpInst != 0, "cannot create DU F1-U GTP module\n"); + getCxt(myInstance)->gtpInst = gtpInst; + DUuniqInstance = gtpInst; } break; case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE: diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index e175b215bb..a8669e8b54 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -37,7 +37,6 @@ #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" -#include #include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h" int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) @@ -755,16 +754,6 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, f1ap_ue_context_r return 0; } -static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, char *DUaddr, uint16_t DUport) -{ - openAddr_t tmp = {0}; - strncpy(tmp.originHost, DUaddr, sizeof(tmp.originHost)-1); - strncpy(tmp.destinationHost, CUaddr, sizeof(tmp.destinationHost)-1); - sprintf(tmp.originService, "%d", DUport); - sprintf(tmp.destinationService, "%d", CUport); - return gtpv1Init(tmp); -} - int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { F1AP_UEContextModificationRequest_t *container; @@ -836,27 +825,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t // 3GPP assumes GTP-U is on port 2152, but OAI is configurable drb_p->up_ul_tnl[0].port = getCxt(instance)->net_config.CUport; - extern instance_t DUuniqInstance; - if (DUuniqInstance == 0) { - char gtp_tunnel_ip_address[32]; - snprintf(gtp_tunnel_ip_address, - sizeof(gtp_tunnel_ip_address), - "%d.%d.%d.%d", - drb_p->up_ul_tnl[0].tl_address & 0xff, - (drb_p->up_ul_tnl[0].tl_address >> 8) & 0xff, - (drb_p->up_ul_tnl[0].tl_address >> 16) & 0xff, - (drb_p->up_ul_tnl[0].tl_address >> 24) & 0xff); - getCxt(instance)->gtpInst = du_create_gtpu_instance_to_cu(gtp_tunnel_ip_address, - getCxt(instance)->net_config.CUport, - getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address, - getCxt(instance)->net_config.DUport); - AssertFatal(getCxt(instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener"); - // Fixme: fully inconsistent instances management - // dirty global var is a bad fix - extern instance_t legacyInstanceMapping; - legacyInstanceMapping = DUuniqInstance = getCxt(instance)->gtpInst; - } - switch (drbs_tobesetupmod_item_p->rLCMode) { case F1AP_RLCMode_rlc_am: drb_p->rlc_mode = RLC_MODE_AM; From 2fbb41ddc52ecb823d8381fbec558cc0d9cfee5c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 11 Mar 2024 11:56:19 +0100 Subject: [PATCH 28/35] Move GTP UE ID update out of message decoder --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 2 -- openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 3a2f7ce725..4a3526dd0a 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -50,7 +50,6 @@ #include "asn1_msg.h" #include "intertask_interface.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" -#include #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" @@ -83,7 +82,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id /* strange: it is not named OLD_GNB_DU_UE... */ old_gNB_DU_ue_id_stack = ie->value.choice.GNB_DU_UE_F1AP_ID_1; old_gNB_DU_ue_id = &old_gNB_DU_ue_id_stack; - gtpv1u_update_ue_id(getCxt(instance)->gtpInst, old_gNB_DU_ue_id_stack, du_ue_f1ap_id); } /* mandatory */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 44c7839463..d537865de5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -716,6 +716,9 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) pthread_mutex_unlock(&mac->sched_lock); nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id); nr_rlc_update_rnti(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); + instance_t f1inst = get_f1_gtp_instance(); + if (f1inst >= 0) // we actually use F1-U + gtpv1u_update_ue_id(f1inst, *dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); } /* the DU ue id is the RNTI */ From 200a408e0f5313498bb344593782aea76540e8b3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 11 Mar 2024 12:40:13 +0100 Subject: [PATCH 29/35] F1AP: factor DU QoS decoding into functions --- openair2/F1AP/f1ap_du_ue_context_management.c | 169 +++++++++--------- 1 file changed, 83 insertions(+), 86 deletions(-) diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index a8669e8b54..dd120f5d49 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -39,6 +39,82 @@ #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h" +static void f1ap_read_drb_qos_param(const F1AP_QoSFlowLevelQoSParameters_t *asn1_qos, f1ap_qos_flow_level_qos_parameters_t *drb_qos) +{ + f1ap_qos_characteristics_t *drb_qos_char = &drb_qos->qos_characteristics; + const F1AP_QoS_Characteristics_t *dRB_QoS_Char = &asn1_qos->qoS_Characteristics; + + if (dRB_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) { + drb_qos_char->qos_type = non_dynamic; + drb_qos_char->non_dynamic.fiveqi = dRB_QoS_Char->choice.non_Dynamic_5QI->fiveQI; + drb_qos_char->non_dynamic.qos_priority_level = (dRB_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel != NULL) + ? *dRB_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel + : -1; + } else { + drb_qos_char->qos_type = dynamic; + drb_qos_char->dynamic.fiveqi = + (dRB_QoS_Char->choice.dynamic_5QI->fiveQI != NULL) ? *dRB_QoS_Char->choice.dynamic_5QI->fiveQI : -1; + drb_qos_char->dynamic.qos_priority_level = dRB_QoS_Char->choice.dynamic_5QI->qoSPriorityLevel; + drb_qos_char->dynamic.packet_delay_budget = dRB_QoS_Char->choice.dynamic_5QI->packetDelayBudget; + drb_qos_char->dynamic.packet_error_rate.per_scalar = dRB_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Scalar; + drb_qos_char->dynamic.packet_error_rate.per_exponent = dRB_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Exponent; + } + + /* nGRANallocationRetentionPriority */ + drb_qos->alloc_reten_priority.priority_level = asn1_qos->nGRANallocationRetentionPriority.priorityLevel; + drb_qos->alloc_reten_priority.preemption_vulnerability = asn1_qos->nGRANallocationRetentionPriority.pre_emptionVulnerability; + drb_qos->alloc_reten_priority.preemption_capability = asn1_qos->nGRANallocationRetentionPriority.pre_emptionVulnerability; +} + +static void f1ap_read_flows_mapped(const F1AP_Flows_Mapped_To_DRB_List_t *asn1_flows_mapped, f1ap_flows_mapped_to_drb_t *flows_mapped, int n) +{ + for (int k = 0; k < n; k++) { + f1ap_flows_mapped_to_drb_t *flows_mapped_to_drb = flows_mapped + k; + const F1AP_Flows_Mapped_To_DRB_Item_t *flows_Mapped_To_Drb = asn1_flows_mapped->list.array[0] + k; + + flows_mapped_to_drb->qfi = flows_Mapped_To_Drb->qoSFlowIdentifier; + + /* QoS-Flow-Level-QoS-Parameters */ + { + f1ap_qos_flow_level_qos_parameters_t *flow_qos = &flows_mapped_to_drb->qos_params; + const F1AP_QoSFlowLevelQoSParameters_t *Flow_QoS = &flows_Mapped_To_Drb->qoSFlowLevelQoSParameters; + + /* QoS Characteristics*/ + f1ap_qos_characteristics_t *flow_qos_char = &flow_qos->qos_characteristics; + const F1AP_QoS_Characteristics_t *Flow_QoS_Char = &Flow_QoS->qoS_Characteristics; + + if (Flow_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) { + flow_qos_char->qos_type = non_dynamic; + flow_qos_char->non_dynamic.fiveqi = Flow_QoS_Char->choice.non_Dynamic_5QI->fiveQI; + flow_qos_char->non_dynamic.qos_priority_level = (Flow_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel != NULL) + ? *Flow_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel + : -1; + } else { + flow_qos_char->qos_type = dynamic; + flow_qos_char->dynamic.fiveqi = + (Flow_QoS_Char->choice.dynamic_5QI->fiveQI != NULL) ? *Flow_QoS_Char->choice.dynamic_5QI->fiveQI : -1; + flow_qos_char->dynamic.qos_priority_level = Flow_QoS_Char->choice.dynamic_5QI->qoSPriorityLevel; + flow_qos_char->dynamic.packet_delay_budget = Flow_QoS_Char->choice.dynamic_5QI->packetDelayBudget; + flow_qos_char->dynamic.packet_error_rate.per_scalar = Flow_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Scalar; + flow_qos_char->dynamic.packet_error_rate.per_exponent = Flow_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Exponent; + } + + /* nGRANallocationRetentionPriority */ + flow_qos->alloc_reten_priority.priority_level = Flow_QoS->nGRANallocationRetentionPriority.priorityLevel; + flow_qos->alloc_reten_priority.preemption_vulnerability = Flow_QoS->nGRANallocationRetentionPriority.pre_emptionVulnerability; + flow_qos->alloc_reten_priority.preemption_capability = Flow_QoS->nGRANallocationRetentionPriority.pre_emptionVulnerability; + } + } +} + +static void f1ap_read_drb_nssai(const F1AP_SNSSAI_t *asn1_nssai, nssai_t *nssai) +{ + OCTET_STRING_TO_INT8(&asn1_nssai->sST, nssai->sst); + nssai->sd = 0xffffff; + if (asn1_nssai->sD != NULL) + memcpy((uint8_t *)&nssai->sd, asn1_nssai->sD->buf, 3); +} + int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { F1AP_UEContextSetupRequest_t *container; @@ -845,101 +921,22 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t (F1AP_QoSInformation_ExtIEs_t *)drbs_tobesetupmod_item_p->qoSInformation.choice.choice_extension; if (ie->id == F1AP_ProtocolIE_ID_id_DRB_Information && ie->criticality == F1AP_Criticality_reject && ie->value.present == F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information) { - F1AP_DRB_Information_t *dRB_Info = &ie->value.choice.DRB_Information; - f1ap_drb_information_t *drb_info = &f1ap_ue_context_modification_req->drbs_to_be_setup->drb_info; - /* 12.1.2.1 dRB_QoS */ - { - /* QoS-Flow-Level-QoS-Parameters */ - f1ap_qos_flow_level_qos_parameters_t *drb_qos = &drb_info->drb_qos; - F1AP_QoSFlowLevelQoSParameters_t *dRB_QoS = &dRB_Info->dRB_QoS; - { - /* QoS Characteristics*/ - f1ap_qos_characteristics_t *drb_qos_char = &drb_qos->qos_characteristics; - F1AP_QoS_Characteristics_t *dRB_QoS_Char = &dRB_QoS->qoS_Characteristics; + const F1AP_DRB_Information_t *dRB_Info = &ie->value.choice.DRB_Information; + f1ap_drb_information_t *drb_info = &drb_p->drb_info; - if (dRB_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) { - drb_qos_char->qos_type = non_dynamic; - drb_qos_char->non_dynamic.fiveqi = dRB_QoS_Char->choice.non_Dynamic_5QI->fiveQI; - drb_qos_char->non_dynamic.qos_priority_level = (dRB_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel != NULL) - ? *dRB_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel - : -1; - } else { - drb_qos_char->qos_type = dynamic; - drb_qos_char->dynamic.fiveqi = - (dRB_QoS_Char->choice.dynamic_5QI->fiveQI != NULL) ? *dRB_QoS_Char->choice.dynamic_5QI->fiveQI : -1; - drb_qos_char->dynamic.qos_priority_level = dRB_QoS_Char->choice.dynamic_5QI->qoSPriorityLevel; - drb_qos_char->dynamic.packet_delay_budget = dRB_QoS_Char->choice.dynamic_5QI->packetDelayBudget; - drb_qos_char->dynamic.packet_error_rate.per_scalar = dRB_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Scalar; - drb_qos_char->dynamic.packet_error_rate.per_exponent = - dRB_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Exponent; - } - } - - /* nGRANallocationRetentionPriority */ - drb_qos->alloc_reten_priority.priority_level = dRB_QoS->nGRANallocationRetentionPriority.priorityLevel; - drb_qos->alloc_reten_priority.preemption_vulnerability = - dRB_QoS->nGRANallocationRetentionPriority.pre_emptionVulnerability; - drb_qos->alloc_reten_priority.preemption_capability = - dRB_QoS->nGRANallocationRetentionPriority.pre_emptionVulnerability; - } // dRB_QoS + /* QoS-Flow-Level-QoS-Parameters */ + /* QoS Characteristics*/ + f1ap_read_drb_qos_param(&dRB_Info->dRB_QoS, &drb_info->drb_qos); // 12.1.2.4 flows_Mapped_To_DRB_List drb_info->flows_to_be_setup_length = dRB_Info->flows_Mapped_To_DRB_List.list.count; drb_info->flows_mapped_to_drb = calloc(drb_info->flows_to_be_setup_length, sizeof(f1ap_flows_mapped_to_drb_t)); AssertFatal(drb_info->flows_mapped_to_drb, "could not allocate memory for drb_p->drb_info.flows_mapped_to_drb\n"); - - for (int k = 0; k < drb_p->drb_info.flows_to_be_setup_length; k++) { - f1ap_flows_mapped_to_drb_t *flows_mapped_to_drb = drb_info->flows_mapped_to_drb + k; - F1AP_Flows_Mapped_To_DRB_Item_t *flows_Mapped_To_Drb = dRB_Info->flows_Mapped_To_DRB_List.list.array[0] + k; - - flows_mapped_to_drb->qfi = flows_Mapped_To_Drb->qoSFlowIdentifier; - - /* QoS-Flow-Level-QoS-Parameters */ - { - f1ap_qos_flow_level_qos_parameters_t *flow_qos = &flows_mapped_to_drb->qos_params; - F1AP_QoSFlowLevelQoSParameters_t *Flow_QoS = &flows_Mapped_To_Drb->qoSFlowLevelQoSParameters; - - /* QoS Characteristics*/ - { - f1ap_qos_characteristics_t *flow_qos_char = &flow_qos->qos_characteristics; - F1AP_QoS_Characteristics_t *Flow_QoS_Char = &Flow_QoS->qoS_Characteristics; - - if (Flow_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) { - flow_qos_char->qos_type = non_dynamic; - flow_qos_char->non_dynamic.fiveqi = Flow_QoS_Char->choice.non_Dynamic_5QI->fiveQI; - flow_qos_char->non_dynamic.qos_priority_level = - (Flow_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel != NULL) - ? *Flow_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel - : -1; - } else { - flow_qos_char->qos_type = dynamic; - flow_qos_char->dynamic.fiveqi = - (Flow_QoS_Char->choice.dynamic_5QI->fiveQI != NULL) ? *Flow_QoS_Char->choice.dynamic_5QI->fiveQI : -1; - flow_qos_char->dynamic.qos_priority_level = Flow_QoS_Char->choice.dynamic_5QI->qoSPriorityLevel; - flow_qos_char->dynamic.packet_delay_budget = Flow_QoS_Char->choice.dynamic_5QI->packetDelayBudget; - flow_qos_char->dynamic.packet_error_rate.per_scalar = - Flow_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Scalar; - flow_qos_char->dynamic.packet_error_rate.per_exponent = - Flow_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Exponent; - } - } - - /* nGRANallocationRetentionPriority */ - flow_qos->alloc_reten_priority.priority_level = Flow_QoS->nGRANallocationRetentionPriority.priorityLevel; - flow_qos->alloc_reten_priority.preemption_vulnerability = - Flow_QoS->nGRANallocationRetentionPriority.pre_emptionVulnerability; - flow_qos->alloc_reten_priority.preemption_capability = - Flow_QoS->nGRANallocationRetentionPriority.pre_emptionVulnerability; - } - } + f1ap_read_flows_mapped(&dRB_Info->flows_Mapped_To_DRB_List, drb_info->flows_mapped_to_drb, drb_info->flows_to_be_setup_length); /* S-NSSAI */ - OCTET_STRING_TO_INT8(&dRB_Info->sNSSAI.sST, drb_p->nssai.sst); - if (dRB_Info->sNSSAI.sD != NULL) - memcpy((uint8_t *)&drb_p->nssai.sd, dRB_Info->sNSSAI.sD->buf, 3); - else - drb_p->nssai.sd = 0xffffff; + f1ap_read_drb_nssai(&dRB_Info->sNSSAI, &drb_p->nssai); } } } From 422d852bdbbe1a53f8626a65021145e3c8fbfa2b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 11 Mar 2024 12:43:40 +0100 Subject: [PATCH 30/35] F1AP: Decode DU QoS Info in UE context setup Request --- openair2/F1AP/f1ap_du_ue_context_management.c | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index dd120f5d49..3715c0ae5d 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -216,6 +216,36 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_i drb_p->rlc_mode = RLC_MODE_TM; break; } + + if (drbs_tobesetup_item_p->qoSInformation.present == F1AP_QoSInformation_PR_eUTRANQoS) { + AssertFatal(false, "Decode of eUTRANQoS is not implemented yet"); + } // EUTRAN QoS Information + else { + /* 12.1.2 DRB_Information */ + if (drbs_tobesetup_item_p->qoSInformation.present == F1AP_QoSInformation_PR_choice_extension) { + F1AP_QoSInformation_ExtIEs_t *ie = + (F1AP_QoSInformation_ExtIEs_t *)drbs_tobesetup_item_p->qoSInformation.choice.choice_extension; + if (ie->id == F1AP_ProtocolIE_ID_id_DRB_Information && ie->criticality == F1AP_Criticality_reject + && ie->value.present == F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information) { + + const F1AP_DRB_Information_t *dRB_Info = &ie->value.choice.DRB_Information; + f1ap_drb_information_t *drb_info = &drb_p->drb_info; + + /* QoS-Flow-Level-QoS-Parameters */ + /* QoS Characteristics*/ + f1ap_read_drb_qos_param(&dRB_Info->dRB_QoS, &drb_info->drb_qos); + + // 12.1.2.4 flows_Mapped_To_DRB_List + drb_info->flows_to_be_setup_length = dRB_Info->flows_Mapped_To_DRB_List.list.count; + drb_info->flows_mapped_to_drb = calloc(drb_info->flows_to_be_setup_length, sizeof(f1ap_flows_mapped_to_drb_t)); + AssertFatal(drb_info->flows_mapped_to_drb, "could not allocate memory for drb_p->drb_info.flows_mapped_to_drb\n"); + f1ap_read_flows_mapped(&dRB_Info->flows_Mapped_To_DRB_List, drb_info->flows_mapped_to_drb, drb_info->flows_to_be_setup_length); + + /* S-NSSAI */ + f1ap_read_drb_nssai(&dRB_Info->sNSSAI, &drb_p->nssai); + } + } + } } } From 2ae8a7b305550b21f18660e6c715ed3f19d20a19 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 11 Mar 2024 17:18:07 +0100 Subject: [PATCH 31/35] F1AP: CU UE Context Setup: create drb variables --- openair2/F1AP/f1ap_cu_ue_context_management.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index bed69ae455..26fcb5b9d6 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -273,7 +273,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu ie12->value.present = F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List; for (int i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; i++) { - // + const f1ap_drb_to_be_setup_t *drb = &f1ap_ue_context_setup_req->drbs_to_be_setup[i]; asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetup_List.list, F1AP_DRBs_ToBeSetup_ItemIEs_t, drbs_toBeSetup_item_ies); drbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item; drbs_toBeSetup_item_ies->criticality = F1AP_Criticality_reject; @@ -281,7 +281,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu /* 12.1 DRBs_ToBeSetup_Item */ F1AP_DRBs_ToBeSetup_Item_t *drbs_toBeSetup_item=&drbs_toBeSetup_item_ies->value.choice.DRBs_ToBeSetup_Item; /* 12.1.1 dRBID */ - drbs_toBeSetup_item->dRBID = f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id; // 9 + drbs_toBeSetup_item->dRBID = drb->drb_id; /* 12.1.2 qoSInformation */ int some_decide_qos = 0; // BK: Need Check @@ -1163,6 +1163,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte ie12->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List; for (int i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_setup_length; i++) { + const f1ap_drb_to_be_setup_t *drb = &f1ap_ue_context_modification_req->drbs_to_be_setup[i]; asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetupMod_List.list, F1AP_DRBs_ToBeSetupMod_ItemIEs_t, drbs_toBeSetupMod_item_ies); drbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item; @@ -1172,7 +1173,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte F1AP_DRBs_ToBeSetupMod_Item_t *drbs_toBeSetupMod_item= &drbs_toBeSetupMod_item_ies->value.choice.DRBs_ToBeSetupMod_Item; /* dRBID */ - drbs_toBeSetupMod_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id; + drbs_toBeSetupMod_item->dRBID = drb->drb_id; /* qoSInformation */ if(f1ap_ue_context_modification_req->QoS_information_type == EUTRAN_QoS){ From f660bd63528e74f7b458799ae164244d7784c359 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 11 Mar 2024 13:42:56 +0100 Subject: [PATCH 32/35] F1AP: CU QoS refactor NSSAI enc into function --- openair2/F1AP/f1ap_cu_ue_context_management.c | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 26fcb5b9d6..128149bde3 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -64,6 +64,15 @@ static void setQos(F1AP_NonDynamic5QIDescriptor_t **toFill) } } +static void f1ap_write_drb_nssai(const nssai_t *nssai, F1AP_SNSSAI_t *asn1_nssai) +{ + OCTET_STRING_fromBuf(&asn1_nssai->sST, (char *)&nssai->sst, 1); + + /* OPTIONAL */ + if (nssai->sd != 0xffffff) + OCTET_STRING_fromBuf(asn1_nssai->sD, (char *)&nssai->sd, 3); +} + int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *f1ap_ue_context_setup_req) { F1AP_F1AP_PDU_t pdu= {0}; @@ -393,16 +402,9 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); } } // dRB_QoS - /* 12.1.2.2 sNSSAI */ - { - /* sST */ - OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, (char *)&f1ap_ue_context_setup_req->drbs_to_be_setup[i].nssai.sst, 1); - /* OPTIONAL */ - const uint32_t sd = (f1ap_ue_context_setup_req->drbs_to_be_setup[i].nssai.sd & 0xffffff); - if (sd != 0xffffff) - OCTET_STRING_fromBuf(DRB_Information->sNSSAI.sD, (char *)&sd, 3); - } + /* 12.1.2.2 sNSSAI */ + f1ap_write_drb_nssai(&drb->nssai, &DRB_Information->sNSSAI); /* OPTIONAL */ /* 12.1.2.3 notificationControl */ @@ -1300,16 +1302,9 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); } } // dRB_QoS - /* 12.1.2.2 sNSSAI */ - { - /* sST */ - OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, (char *)&f1ap_ue_context_modification_req->drbs_to_be_setup[i].nssai.sst, 1); - /* OPTIONAL */ - const uint32_t sd = (f1ap_ue_context_modification_req->drbs_to_be_setup[i].nssai.sd & 0xffffff); - if (sd != 0xffffff) - OCTET_STRING_fromBuf(DRB_Information->sNSSAI.sD, (char *)&sd, 3); - } + /* 12.1.2.2 sNSSAI */ + f1ap_write_drb_nssai(&drb->nssai, &DRB_Information->sNSSAI); /* OPTIONAL */ /* 12.1.2.3 notificationControl */ From 8ce33f58a9080151800d0bcad3414650df8fff61 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 11 Mar 2024 17:22:39 +0100 Subject: [PATCH 33/35] F1AP: CU QoS refactor QoS Param enc into function --- openair2/F1AP/f1ap_cu_ue_context_management.c | 224 ++++++------------ 1 file changed, 69 insertions(+), 155 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 128149bde3..478e74d05f 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -64,6 +64,70 @@ static void setQos(F1AP_NonDynamic5QIDescriptor_t **toFill) } } +static void f1ap_write_drb_qos_param(const f1ap_qos_flow_level_qos_parameters_t *drb_qos_in, F1AP_QoSFlowLevelQoSParameters_t *asn1_qosparam) +{ + int type = drb_qos_in->qos_characteristics.qos_type; + + const f1ap_qos_characteristics_t *drb_qos_char_in = &drb_qos_in->qos_characteristics; + if (type == non_dynamic) { + asn1_qosparam->qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + asn1cCalloc(asn1_qosparam->qoS_Characteristics.choice.non_Dynamic_5QI, tmp); + + /* 5QI */ + tmp->fiveQI = drb_qos_char_in->non_dynamic.fiveqi; + } else { + asn1_qosparam->qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + asn1cCalloc(asn1_qosparam->qoS_Characteristics.choice.dynamic_5QI, tmp); + /* qoSPriorityLevel */ + tmp->qoSPriorityLevel = drb_qos_char_in->dynamic.qos_priority_level; + /* packetDelayBudget */ + tmp->packetDelayBudget = drb_qos_char_in->dynamic.packet_delay_budget; + /* packetErrorRate */ + tmp->packetErrorRate.pER_Scalar = drb_qos_char_in->dynamic.packet_error_rate.per_scalar; + tmp->packetErrorRate.pER_Exponent = drb_qos_char_in->dynamic.packet_error_rate.per_scalar; + + /* OPTIONAL delayCritical */ + // asn1cCallocOne(asn1_qosparam->qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); + + /* OPTIONAL averagingWindow */ + // asn1cCallocOne(asn1_qosparam->qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); + + /* OPTIONAL maxDataBurstVolume */ + // asn1cCallocOne(asn1_qosparam->qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); + } + + { + asn1_qosparam->nGRANallocationRetentionPriority.priorityLevel = drb_qos_in->alloc_reten_priority.priority_level; + asn1_qosparam->nGRANallocationRetentionPriority.pre_emptionCapability = drb_qos_in->alloc_reten_priority.preemption_capability; + asn1_qosparam->nGRANallocationRetentionPriority.pre_emptionVulnerability = + drb_qos_in->alloc_reten_priority.preemption_vulnerability; + } // nGRANallocationRetentionPriority + + /* OPTIONAL */ + /* gBR_QoS_Flow_Information */ + if (0) { + asn1cCalloc(asn1_qosparam->gBR_QoS_Flow_Information, tmp); + asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); + + /* OPTIONAL */ + /* maxPacketLossRateDownlink */ + // asn1cCallocOne(asn1_qosparam->gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); + + /* OPTIONAL */ + /* maxPacketLossRateUplink */ + //asn1cCallocOne(asn1_qosparam->gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); + } + + /* OPTIONAL */ + /* reflective_QoS_Attribute */ + if (0) { + asn1cCallocOne(asn1_qosparam->reflective_QoS_Attribute, 1L); + } +} + static void f1ap_write_drb_nssai(const nssai_t *nssai, F1AP_SNSSAI_t *asn1_nssai) { OCTET_STRING_fromBuf(&asn1_nssai->sST, (char *)&nssai->sst, 1); @@ -321,6 +385,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu } } else { /* 12.1.2 DRB_Information */ + const f1ap_drb_information_t *drb_info = &drb->drb_info; drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_choice_extension; F1AP_QoSInformation_ExtIEs_t *ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(*ie)); ie->id = F1AP_ProtocolIE_ID_id_DRB_Information; @@ -328,80 +393,9 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information; F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information; drbs_toBeSetup_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie; + /* 12.1.2.1 dRB_QoS */ - { - /* qoS_Characteristics */ - { - int some_decide_qoS_characteristics = 0; // BK: Need Check - - if (some_decide_qoS_characteristics) { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - setQos(&DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI); - } else { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI, tmp); - /* qoSPriorityLevel */ - tmp->qoSPriorityLevel = 1L; - /* packetDelayBudget */ - tmp->packetDelayBudget = 1L; - /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = 1L; - tmp->packetErrorRate.pER_Exponent = 6L; - - /* OPTIONAL */ - /* delayCritical */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); - } - - /* OPTIONAL */ - /* averagingWindow */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); - } - - /* OPTIONAL */ - /* maxDataBurstVolume */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); - } - } // if some_decide_qoS_characteristics - } // qoS_Characteristics - /* nGRANallocationRetentionPriority */ - { - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information, tmp); - asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); - - /* OPTIONAL */ - /* maxPacketLossRateDownlink */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - } - - /* OPTIONAL */ - /* maxPacketLossRateUplink */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } - } - - /* OPTIONAL */ - /* reflective_QoS_Attribute */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); - } - } // dRB_QoS + f1ap_write_drb_qos_param(&drb_info->drb_qos, &DRB_Information->dRB_QoS); /* 12.1.2.2 sNSSAI */ f1ap_write_drb_nssai(&drb->nssai, &DRB_Information->sNSSAI); @@ -1219,89 +1213,9 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information; F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information; drbs_toBeSetupMod_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie; + /* 12.1.2.1 dRB_QoS */ - { - /* qoS_Characteristics */ - f1ap_qos_flow_level_qos_parameters_t *drb_qos_in = &drb_info_in->drb_qos; - { - int some_decide_qoS_characteristics = drb_qos_in->qos_characteristics.qos_type; - - f1ap_qos_characteristics_t *drb_qos_char_in = &drb_qos_in->qos_characteristics; - if (some_decide_qoS_characteristics == non_dynamic) { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI, tmp); - - /* 5QI */ - tmp->fiveQI = drb_qos_char_in->non_dynamic.fiveqi; - } else { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI, tmp); - /* qoSPriorityLevel */ - tmp->qoSPriorityLevel = drb_qos_char_in->dynamic.qos_priority_level; - /* packetDelayBudget */ - tmp->packetDelayBudget = drb_qos_char_in->dynamic.packet_delay_budget; - /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = drb_qos_char_in->dynamic.packet_error_rate.per_scalar; - tmp->packetErrorRate.pER_Exponent = drb_qos_char_in->dynamic.packet_error_rate.per_scalar; - - /* OPTIONAL */ - /* delayCritical */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); - } - - /* OPTIONAL */ - /* averagingWindow */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); - } - - /* OPTIONAL */ - /* maxDataBurstVolume */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); - } - } // if some_decide_qoS_characteristics - - } // qoS_Characteristics - /* nGRANallocationRetentionPriority */ - { - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = - drb_qos_in->alloc_reten_priority.priority_level; - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = - drb_qos_in->alloc_reten_priority.preemption_capability; - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = - drb_qos_in->alloc_reten_priority.preemption_vulnerability; - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information, tmp); - asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); - - /* OPTIONAL */ - /* maxPacketLossRateDownlink */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - } - - /* OPTIONAL */ - /* maxPacketLossRateUplink */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } - } - - /* OPTIONAL */ - /* reflective_QoS_Attribute */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); - } - } // dRB_QoS + f1ap_write_drb_qos_param(&drb_info_in->drb_qos, &DRB_Information->dRB_QoS); /* 12.1.2.2 sNSSAI */ f1ap_write_drb_nssai(&drb->nssai, &DRB_Information->sNSSAI); From 73d21d6da02935847c389801865e8d2a92951610 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 11 Mar 2024 17:34:15 +0100 Subject: [PATCH 34/35] F1AP: CU QoS refactor Flows Mapped enc into function --- openair2/F1AP/f1ap_cu_ue_context_management.c | 284 +++++------------- 1 file changed, 78 insertions(+), 206 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 478e74d05f..6fe48ed611 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -39,31 +39,6 @@ #include "rrc_extern.h" #include "openair2/RRC/NR/rrc_gNB_NGAP.h" -static void setQos(F1AP_NonDynamic5QIDescriptor_t **toFill) -{ - asn1cCalloc(*toFill, tmp); - /* fiveQI */ - tmp->fiveQI = 1L; - - /* OPTIONAL */ - /* qoSPriorityLevel */ - if (0) { - asn1cCallocOne((*toFill)->qoSPriorityLevel, 1L); - } - - /* OPTIONAL */ - /* averagingWindow */ - if (0) { - asn1cCallocOne((*toFill)->averagingWindow, 1L); - } - - /* OPTIONAL */ - /* maxDataBurstVolume */ - if (0) { - asn1cCallocOne((*toFill)->maxDataBurstVolume, 1L); - } -} - static void f1ap_write_drb_qos_param(const f1ap_qos_flow_level_qos_parameters_t *drb_qos_in, F1AP_QoSFlowLevelQoSParameters_t *asn1_qosparam) { int type = drb_qos_in->qos_characteristics.qos_type; @@ -137,6 +112,82 @@ static void f1ap_write_drb_nssai(const nssai_t *nssai, F1AP_SNSSAI_t *asn1_nssai OCTET_STRING_fromBuf(asn1_nssai->sD, (char *)&nssai->sd, 3); } +static void f1ap_write_flows_mapped(const f1ap_flows_mapped_to_drb_t *flows_mapped, F1AP_Flows_Mapped_To_DRB_List_t *asn1_flows_mapped, int n) +{ + for (int k = 0; k < n; k++) { + asn1cSequenceAdd(asn1_flows_mapped->list, F1AP_Flows_Mapped_To_DRB_Item_t, flow_item); + + const f1ap_flows_mapped_to_drb_t *qos_flow_in = flows_mapped + k; + + /* qoSFlowIndicator */ + flow_item->qoSFlowIdentifier = qos_flow_in->qfi; + + /* qoSFlowLevelQoSParameters */ + const f1ap_qos_flow_level_qos_parameters_t *flow_qos_params_in = &qos_flow_in->qos_params; + /* qoS_Characteristics */ + + F1AP_QoS_Characteristics_t *QosParams = &flow_item->qoSFlowLevelQoSParameters.qoS_Characteristics; + const f1ap_qos_characteristics_t *flow_qos_char_in = &flow_qos_params_in->qos_characteristics; + + int type = flow_qos_params_in->qos_characteristics.qos_type; + if (type == non_dynamic) { + QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + asn1cCalloc(QosParams->choice.non_Dynamic_5QI, tmp); + + /* 5QI */ + tmp->fiveQI = flow_qos_char_in->non_dynamic.fiveqi; + } else { + QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); + /* qoSPriorityLevel */ + tmp->qoSPriorityLevel = flow_qos_char_in->dynamic.qos_priority_level; + /* packetDelayBudget */ + tmp->packetDelayBudget = flow_qos_char_in->dynamic.packet_delay_budget; + /* packetErrorRate */ + tmp->packetErrorRate.pER_Scalar = flow_qos_char_in->dynamic.packet_error_rate.per_scalar; + tmp->packetErrorRate.pER_Exponent = flow_qos_char_in->dynamic.packet_error_rate.per_exponent; + + /* OPTIONAL delayCritical */ + //asn1cCallocOne(QosParams->choice.dynamic_5QI->delayCritical, 1); + + /* OPTIONAL averagingWindow */ + //asn1cCallocOne(QosParams->choice.dynamic_5QI->averagingWindow, 1); + + /* OPTIONAL maxDataBurstVolume */ + //asn1cCallocOne(QosParams->choice.dynamic_5QI->maxDataBurstVolume, 1); + } + + /* nGRANallocationRetentionPriority */ + { + flow_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = + flow_qos_params_in->alloc_reten_priority.priority_level; + flow_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = + flow_qos_params_in->alloc_reten_priority.preemption_capability; + flow_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = + flow_qos_params_in->alloc_reten_priority.preemption_vulnerability; + } // nGRANallocationRetentionPriority + + /* OPTIONAL */ + /* gBR_QoS_Flow_Information */ + if (0) { + asn1cCalloc(flow_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp); + asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); + + /* OPTIONAL maxPacketLossRateDownlink */ + //asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); + + /* OPTIONAL maxPacketLossRateUplink */ + //asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); + } + + /* OPTIONAL reflective_QoS_Attribute */ + //asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); + } +} + int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *f1ap_ue_context_setup_req) { F1AP_F1AP_PDU_t pdu= {0}; @@ -408,91 +459,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu } /* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy - - for (int k = 0; k < 1; k ++) { - asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list, - F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item); - /* qoSFlowIndicator */ - flows_mapped_to_drb_item->qoSFlowIdentifier = 1L; - /* qoSFlowLevelQoSParameters */ - { - /* qoS_Characteristics */ - { - int some_decide_qoS_characteristics = 0; // BK: Need Check - F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics; - - if (some_decide_qoS_characteristics) { - QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - setQos(&QosParams->choice.non_Dynamic_5QI); - } else { - QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); - /* qoSPriorityLevel */ - tmp->qoSPriorityLevel = 1L; - /* packetDelayBudget */ - tmp->packetDelayBudget = 1L; - /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = 1L; - tmp->packetErrorRate.pER_Exponent = 6L; - - /* OPTIONAL */ - /* delayCritical */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp); - *tmp = 1L; - } - - /* OPTIONAL */ - /* averagingWindow */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp); - *tmp = 1L; - } - - /* OPTIONAL */ - /* maxDataBurstVolume */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp); - *tmp= 1L; - } - } // if some_decide_qoS_characteristics - } // qoS_Characteristics - /* nGRANallocationRetentionPriority */ - { - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp); - asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); - - /* OPTIONAL */ - /* maxPacketLossRateDownlink */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - } - - /* OPTIONAL */ - /* maxPacketLossRateUplink */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } - } - - /* OPTIONAL */ - /* reflective_QoS_Attribute */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); - } - } // qoSFlowLevelQoSParameters - } + f1ap_write_flows_mapped(drb_info->flows_mapped_to_drb, &DRB_Information->flows_Mapped_To_DRB_List, drb_info->flows_to_be_setup_length); } // if some_decide_qos /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ @@ -1228,102 +1195,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte } /* 12.1.2.4 flows_Mapped_To_DRB_List */ - for (int k = 0; k < drb_info_in->flows_to_be_setup_length; k++) { - asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list, - F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item); - - f1ap_flows_mapped_to_drb_t *qos_flow_in = drb_info_in->flows_mapped_to_drb + k; - - /* qoSFlowIndicator */ - flows_mapped_to_drb_item->qoSFlowIdentifier = qos_flow_in->qfi; - /* qoSFlowLevelQoSParameters */ - { - f1ap_qos_flow_level_qos_parameters_t *flow_qos_params_in = &qos_flow_in->qos_params; - /* qoS_Characteristics */ - { - int some_decide_qoS_characteristics = flow_qos_params_in->qos_characteristics.qos_type; - F1AP_QoS_Characteristics_t *QosParams = &flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics; - f1ap_qos_characteristics_t *flow_qos_char_in = &flow_qos_params_in->qos_characteristics; - - if (some_decide_qoS_characteristics == non_dynamic) { - QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - asn1cCalloc(QosParams->choice.non_Dynamic_5QI, tmp); - - /* 5QI */ - tmp->fiveQI = flow_qos_char_in->non_dynamic.fiveqi; - } else { - QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); - /* qoSPriorityLevel */ - tmp->qoSPriorityLevel = flow_qos_char_in->dynamic.qos_priority_level; - /* packetDelayBudget */ - tmp->packetDelayBudget = flow_qos_char_in->dynamic.packet_delay_budget; - /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = flow_qos_char_in->dynamic.packet_error_rate.per_scalar; - tmp->packetErrorRate.pER_Exponent = flow_qos_char_in->dynamic.packet_error_rate.per_exponent; - - /* OPTIONAL */ - /* delayCritical */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp); - *tmp = 1L; - } - - /* OPTIONAL */ - /* averagingWindow */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp); - *tmp = 1L; - } - - /* OPTIONAL */ - /* maxDataBurstVolume */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp); - *tmp= 1L; - } - } // if some_decide_qoS_characteristics - - } // qoS_Characteristics - /* nGRANallocationRetentionPriority */ - { - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = - flow_qos_params_in->alloc_reten_priority.priority_level; - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = - flow_qos_params_in->alloc_reten_priority.preemption_capability; - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = - flow_qos_params_in->alloc_reten_priority.preemption_vulnerability; - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp); - asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); - - /* OPTIONAL */ - /* maxPacketLossRateDownlink */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - } - - /* OPTIONAL */ - /* maxPacketLossRateUplink */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } - } - - /* OPTIONAL */ - /* reflective_QoS_Attribute */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); - } - } // qoSFlowLevelQoSParameters - } + f1ap_write_flows_mapped(drb_info_in->flows_mapped_to_drb, &DRB_Information->flows_Mapped_To_DRB_List, drb_info_in->flows_to_be_setup_length); } //QoS information From b97c70fd87db9d199b4de9e41c4659fc18bb64d5 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 28 Feb 2024 23:19:38 +0100 Subject: [PATCH 35/35] remove 5G dependency on 4G mac.h include, separate RA state enums between 4G/5G and UE/gNB add RA stat trace by enum name instead of integer printing fix minor a few minor typos --- nfapi/oai_integration/nfapi_vnf.c | 2 +- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 40 ++++++----- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 4 +- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 6 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 15 ++-- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 9 +-- openair2/LAYER2/MAC/mac.h | 6 +- openair2/LAYER2/NR_MAC_UE/config_ue.c | 2 +- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 19 ++--- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 4 +- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 19 +++-- .../NR_MAC_UE/nr_ue_dci_configuration.c | 22 +++--- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 10 ++- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 10 +-- openair2/LAYER2/NR_MAC_gNB/config.c | 3 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 72 ++++++++++++------- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 9 +-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 47 ++++++------ openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 56 ++++++--------- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 53 ++++++-------- openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c | 3 +- 22 files changed, 208 insertions(+), 205 deletions(-) diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index c01637c558..93666157d3 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -39,6 +39,7 @@ #include "PHY/defs_eNB.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "openair2/LAYER2/MAC/mac.h" #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include "executables/lte-softmodem.h" #include "openair1/PHY/defs_gNB.h" @@ -46,7 +47,6 @@ #include "common/ran_context.h" #include "openair2/PHY_INTERFACE/queue_t.h" #include "gnb_ind_vars.h" -#include "LAYER2/MAC/mac.h" #define TEST diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index e2f1916a5b..ac2c453fc5 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -873,7 +873,7 @@ int main(int argc, char **argv) asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, UE_CellGroup); UE_mac->state = UE_CONNECTED; - UE_mac->ra.ra_state = RA_SUCCEEDED; + UE_mac->ra.ra_state = nrRA_SUCCEEDED; nr_phy_data_t phy_data = {0}; fapi_nr_dl_config_request_t dl_config = {.sfn = frame, .slot = slot}; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 12984f299d..6c04abd104 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -108,8 +108,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, uint8_t pusch_maxNumRepetitionCEmodeA_r13; ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe]; ul_req_body = &ul_req->ul_config_request_body; - AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n", - ra->rnti); + AssertFatal(ra->eRA_state != IDLE, "RA is not active for RA %X\n", ra->rnti); if (ra->rach_resource_type > 0) { LOG_D (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n", @@ -448,7 +447,7 @@ void generate_Msg2(module_id_t module_idP, /* Program UL processing for Msg3, same as regular LTE */ get_Msg3alloc (&cc[CC_idP], subframeP, frameP, &ra->Msg3_frame, &ra->Msg3_subframe); add_msg3 (module_idP, CC_idP, ra, frameP, subframeP); - ra->state = WAITMSG3; + ra->eRA_state = WAITMSG3; /* DL request */ LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming TX Req\n", module_idP, @@ -467,8 +466,12 @@ void generate_Msg2(module_id_t module_idP, } else { if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) { LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, state %d\n", - module_idP, CC_idP, frameP, subframeP, ra->state); + "[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, state %s\n", + module_idP, + CC_idP, + frameP, + subframeP, + era_text[ra->eRA_state]); // Allocate 4 PRBS starting in RB 0 first_rb = 0; vrb_map[first_rb] = 1; @@ -537,7 +540,7 @@ void generate_Msg2(module_id_t module_idP, ra->Msg3_subframe); fill_rar(module_idP, CC_idP, ra, frameP, cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7); add_msg3(module_idP, CC_idP, ra, frameP, subframeP); - ra->state = WAITMSG3; + ra->eRA_state = WAITMSG3; LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP); T(T_ENB_MAC_UE_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_idP), T_INT(ra->RA_rnti), T_INT(frameP), @@ -819,7 +822,7 @@ generate_Msg4(module_id_t module_idP, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; dl_req_body->number_pdu++; - ra->state = WAITMSG4ACK; + ra->eRA_state = WAITMSG4ACK; lcid = 0; UE_info->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0; msg4_header = 1 + 6 + 1; // CR header, CR CE, SDU header @@ -975,7 +978,7 @@ generate_Msg4(module_id_t module_idP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->rnti)) { dl_req_body->number_dci++; dl_req_body->number_pdu++; - ra->state = WAITMSG4ACK; + ra->eRA_state = WAITMSG4ACK; LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG4ACK\n", module_idP, frameP, subframeP); // increment Absolute subframe by 8 for Msg4 retransmission LOG_D(MAC, @@ -1219,7 +1222,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n", module_idP, CC_idP, frameP, subframeP); - ra->state = IDLE; + ra->eRA_state = IDLE; LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:IDLE\n", module_idP, frameP, subframeP); UE_id = find_UE_id(module_idP, ra->rnti); DevAssert(UE_id != -1); @@ -1246,11 +1249,11 @@ schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { for (i = 0; i < NB_RA_PROC_MAX; i++) { ra = (RA_t *) & cc[CC_id].ra[i]; - if (ra->state == MSG2) + if (ra->eRA_state == MSG2) generate_Msg2(module_idP, CC_id, frameP, subframeP, ra); - else if (ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP ) + else if (ra->eRA_state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP) generate_Msg4(module_idP, CC_id, frameP, subframeP, ra); - else if (ra->state == WAITMSG4ACK) + else if (ra->eRA_state == WAITMSG4ACK) check_Msg4_retransmission(module_idP, CC_id, frameP, subframeP, ra); } // for i=0 .. N_RA_PROC-1 @@ -1309,11 +1312,11 @@ initiate_ra_proc(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); for (i = 0; i < NB_RA_PROC_MAX; i++) { - if (ra[i].state == IDLE) { + if (ra[i].eRA_state == IDLE) { int loop = 0; LOG_D(MAC, "Frame %d, Subframe %d: Activating RA process %d\n", frameP, subframeP, i); - ra[i].state = MSG2; + ra[i].eRA_state = MSG2; ra[i].Msg4_delay_cnt=0; ra[i].timing_offset = timing_offset; ra[i].preamble_subframe = subframeP; @@ -1410,7 +1413,8 @@ initiate_ra_proc(module_id_t module_idP, ra[i].preamble_index = preamble_index; failure_cnt = 0; LOG_I(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation in Frame %d, subframe %d for process %d, rnti %x, state %d\n", + "[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation in Frame %d, subframe %d for process %d, rnti %x, state " + "%d\n", module_idP, CC_id, frameP, @@ -1418,7 +1422,7 @@ initiate_ra_proc(module_id_t module_idP, ra[i].Msg2_subframe, i, ra[i].rnti, - ra[i].state); + ra[i].eRA_state); return; } } @@ -1445,7 +1449,7 @@ cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, for (i = 0; i < NB_RA_PROC_MAX; i++) { if (rnti == ra[i].rnti) { - ra[i].state = IDLE; + ra[i].eRA_state = IDLE; ra[i].timing_offset = 0; ra[i].RRC_timer = 20; ra[i].rnti = 0; @@ -1461,7 +1465,7 @@ void clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP) { for (i = 0; i < NB_RA_PROC_MAX; i++) { LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra[i].rnti); - ra[i].state = IDLE; + ra[i].eRA_state = IDLE; ra[i].timing_offset = 0; ra[i].RRC_timer = 20; ra[i].rnti = 0; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 395803b5f5..94eaeccaf6 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -428,11 +428,11 @@ void check_ra_rnti_mui(module_id_t mod_id, int CC_id, frame_t f, sub_frame_t sf, int harq_pid = frame_subframe2_dl_harq_pid(tdd_config, f, sf); RA_t *ra = &RC.mac[mod_id]->common_channels[CC_id].ra[0]; for (uint8_t ra_ii = 0; ra_ii < NB_RA_PROC_MAX; ra_ii++, ra++) { - if ((ra->rnti == rnti) && (ra->state == MSGCRNTI)) { + if ((ra->rnti == rnti) && (ra->eRA_state == MSGCRNTI)) { for (uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { if (ra->crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]) { ra->crnti_harq_pid = harq_pid; - ra->state = MSGCRNTI_ACK; + ra->eRA_state = MSGCRNTI_ACK; break; } } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index db3387198e..3d38a55421 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -1583,11 +1583,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, RA_t *ra = &eNB->common_channels[CC_id].ra[0]; for (uint8_t ra_ii = 0; ra_ii < NB_RA_PROC_MAX; ra_ii++) { - if((ra[ra_ii].rnti == rnti) && (ra[ra_ii].state == MSGCRNTI)) { + if ((ra[ra_ii].rnti == rnti) && (ra[ra_ii].eRA_state == MSGCRNTI)) { for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { if(ra[ra_ii].crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]) { ra[ra_ii].crnti_harq_pid = harq_pid; - ra[ra_ii].state = MSGCRNTI_ACK; + ra[ra_ii].eRA_state = MSGCRNTI_ACK; break; } } @@ -2869,7 +2869,7 @@ schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP, // Msg3 is using 1 PRB so we need to increase first_rb accordingly // not sure about the break (can there be more than 1 active RA procedure?) for (i=0; ira[i].state == WAITMSG3) &&(cc->ra[i].Msg3_subframe == sched_subframe)) { + if ((cc->ra[i].eRA_state == WAITMSG3) && (cc->ra[i].Msg3_subframe == sched_subframe)) { ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_MSG3; if (cc->tdd_Config == NULL) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index c21aac0b63..50c46b16e1 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -2005,12 +2005,9 @@ find_RA_id(module_id_t mod_idP, RA_t *ra = (RA_t *) &RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) { - LOG_D(MAC, "Checking RA_id %d for %x : state %d\n", - RA_id, - rntiP, - ra[RA_id].state); + LOG_D(MAC, "Checking RA_id %d for %x : state %s\n", RA_id, rntiP, era_text[ra[RA_id].eRA_state]); - if (ra[RA_id].state != IDLE && ra[RA_id].rnti == rntiP) + if (ra[RA_id].eRA_state != IDLE && ra[RA_id].rnti == rntiP) return RA_id; } @@ -3970,7 +3967,7 @@ extract_harq(module_id_t mod_idP, if (sched_ctl->round[CC_idP][harq_pid] == 8) { for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if (ra[ra_i].rnti == rnti && ra[ra_i].state == WAITMSG4ACK) { + if (ra[ra_i].rnti == rnti && ra[ra_i].eRA_state == WAITMSG4ACK) { //Msg NACK num to MAC ,remove UE // add UE info to freeList LOG_I(RRC, "put UE %x into freeList\n", @@ -3985,7 +3982,7 @@ extract_harq(module_id_t mod_idP, } for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if (ra[ra_i].rnti == rnti && ra[ra_i].state == MSGCRNTI_ACK && ra[ra_i].crnti_harq_pid == harq_pid) { + if (ra[ra_i].rnti == rnti && ra[ra_i].eRA_state == MSGCRNTI_ACK && ra[ra_i].crnti_harq_pid == harq_pid) { LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n", harq_indication_tdd->harq_data[0].bundling.value_0, rnti, @@ -4077,7 +4074,7 @@ extract_harq(module_id_t mod_idP, RA_t *ra = &eNB->common_channels[CC_idP].ra[0]; for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if (ra[ra_i].rnti == rnti && ra[ra_i].state == MSGCRNTI_ACK && ra[ra_i].crnti_harq_pid == harq_pid) { + if (ra[ra_i].rnti == rnti && ra[ra_i].eRA_state == MSGCRNTI_ACK && ra[ra_i].crnti_harq_pid == harq_pid) { LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n", pdu[0], rnti, @@ -4122,7 +4119,7 @@ extract_harq(module_id_t mod_idP, if (sched_ctl->round[CC_idP][harq_pid] == 8) { for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)) { + if ((ra[ra_i].rnti == rnti) && (ra[ra_i].eRA_state == WAITMSG4ACK)) { // Msg NACK num to MAC ,remove UE // add UE info to freeList LOG_I(RRC, "put UE %x into freeList\n", diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 167ac2628e..058ce4db34 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -522,7 +522,7 @@ rx_sdu(const module_id_t enb_mod_idP, /* Received a new rnti */ if (ret == 0) { - ra->state = MSGCRNTI; + ra->eRA_state = MSGCRNTI; LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Received rnti(Msg4)\n", enb_mod_idP, frameP, @@ -729,13 +729,14 @@ rx_sdu(const module_id_t enb_mod_idP, if (RA_id != -1) { RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]); - LOG_D(MAC, "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", + LOG_D(MAC, + "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %s\n", enb_mod_idP, CC_idP, RA_id, ra->rnti, current_rnti, - ra->state); + era_text[ra->eRA_state]); if (UE_id < 0) { memcpy(&(ra->cont_res_id[0]), payload_ptr, 6); @@ -788,7 +789,7 @@ rx_sdu(const module_id_t enb_mod_idP, } // prepare transmission of Msg4 - ra->state = MSG4; + ra->eRA_state = MSG4; if(mac->common_channels[CC_idP].tdd_Config != NULL) { switch(mac->common_channels[CC_idP].tdd_Config->subframeAssignment) { diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 3de061b07e..635155b5a2 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -505,7 +505,9 @@ typedef struct { } __attribute__ ((__packed__)) ULDCH_PDU; /*!\brief RA process state*/ -typedef enum { IDLE = 0, MSG2, WAITMSG3, MSG4, WAITMSG4ACK, MSGCRNTI, MSGCRNTI_ACK } RA_state; +typedef enum { IDLE = 0, MSG2, WAITMSG3, MSG4, WAITMSG4ACK, MSGCRNTI, MSGCRNTI_ACK } eRA_state; +static const char *const era_text[] = {"IDLE", "Ms2", "WAITMSG3", "WAITMSG4ACK", "MSGCRNTI", "MSGCRNTIACK"}; + /*!\brief UE DLSCH scheduling states*/ typedef enum { S_DL_NONE = 0, S_DL_SCHEDULED } UE_DLSCH_STATUS; /*!\brief scheduler mode */ @@ -1032,7 +1034,7 @@ typedef struct { /*! \brief eNB template for the Random access information */ typedef struct { /// Flag to indicate this process is active - RA_state state; + eRA_state eRA_state; /// Subframe where preamble was received uint8_t preamble_subframe; /// Subframe where Msg2 is to be sent diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 26ee87bacf..f72680bb2a 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1442,7 +1442,7 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, } mac->state = UE_NOT_SYNC; - ra->ra_state = RA_UE_IDLE; + ra->ra_state = nrRA_UE_IDLE; nr_ue_mac_default_configs(mac); if (!get_softmodem_params()->emulate_l1) { diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index e811948bc2..fda1857808 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -238,13 +238,16 @@ typedef struct { } NR_UE_SCHEDULING_INFO; typedef enum { - RA_UE_IDLE = 0, - GENERATE_PREAMBLE = 1, - WAIT_RAR = 2, - WAIT_CONTENTION_RESOLUTION = 3, - RA_SUCCEEDED = 4, - RA_FAILED = 5 -} RA_state_t; + nrRA_UE_IDLE = 0, + nrRA_GENERATE_PREAMBLE = 1, + nrRA_WAIT_RAR = 2, + nrRA_WAIT_CONTENTION_RESOLUTION = 3, + nrRA_SUCCEEDED = 4, + nrRA_FAILED = 5 +} nrRA_UE_state_t; + +static const char *const nrra_ue_text[] = + {"UE_IDLE", "GENERATE_PREAMBLE", "WAIT_RAR", "WAIT_CONTENTION_RESOLUTION", "RA_SUCCEEDED", "RA_FAILED"}; typedef struct { /// PRACH format retrieved from prach_ConfigIndex @@ -276,7 +279,7 @@ typedef struct { // pointer to RACH config dedicated NR_RACH_ConfigDedicated_t *rach_ConfigDedicated; /// state of RA procedure - RA_state_t ra_state; + nrRA_UE_state_t ra_state; /// RA contention type uint8_t cfra; /// RA rx frame offset: compensate RA rx offset introduced by OAI gNB. diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index c7e43e50f8..aa0d46034b 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -161,8 +161,8 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac) nr_mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value // stop any ongoing RACH procedure - if (nr_mac->ra.ra_state < RA_SUCCEEDED) - nr_mac->ra.ra_state = RA_UE_IDLE; + if (nr_mac->ra.ra_state < nrRA_SUCCEEDED) + nr_mac->ra.ra_state = nrRA_UE_IDLE; // discard explicitly signalled contention-free Random Access Resources // TODO not sure what needs to be done here diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 29080b824f..e6013fdc37 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -563,7 +563,7 @@ void nr_get_prach_resources(NR_UE_MAC_INST_t *mac, void nr_Msg1_transmitted(NR_UE_MAC_INST_t *mac) { RA_config_t *ra = &mac->ra; - ra->ra_state = WAIT_RAR; + ra->ra_state = nrRA_WAIT_RAR; ra->RA_attempt_number++; } @@ -580,7 +580,7 @@ void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, s nr_timer_setup(&ra->contention_resolution_timer, RA_contention_resolution_timer_subframes * subframes_per_slot, 1); nr_timer_start(&ra->contention_resolution_timer); - ra->ra_state = WAIT_CONTENTION_RESOLUTION; + ra->ra_state = nrRA_WAIT_CONTENTION_RESOLUTION; } void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max) @@ -645,10 +645,10 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB NR_PRACH_RESOURCES_t *prach_resources = &ra->prach_resources; // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side - if (ra->ra_state == RA_UE_IDLE) { + if (ra->ra_state == nrRA_UE_IDLE) { if ((mac->first_sync_frame > -1 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa) && ((MAX_FRAME_NUMBER + frame - mac->first_sync_frame) % MAX_FRAME_NUMBER) > 150) { - ra->ra_state = GENERATE_PREAMBLE; + ra->ra_state = nrRA_GENERATE_PREAMBLE; } else { LOG_D(NR_MAC,"PRACH Condition not met: ra state %d, frame %d, sync_frame %d\n", ra->ra_state, frame, mac->first_sync_frame); return; @@ -657,8 +657,7 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB LOG_D(NR_MAC, "[UE %d][%d.%d]: ra_state %d, RA_active %d\n", mac->ue_id, frame, nr_slot_tx, ra->ra_state, ra->RA_active); - if (ra->ra_state > RA_UE_IDLE && ra->ra_state < RA_SUCCEEDED) { - + if (ra->ra_state > nrRA_UE_IDLE && ra->ra_state < nrRA_SUCCEEDED) { if (ra->RA_active == 0) { NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; @@ -726,7 +725,7 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB // Fill in preamble and PRACH resources ra->RA_window_cnt--; - if (ra->ra_state == GENERATE_PREAMBLE) { + if (ra->ra_state == nrRA_GENERATE_PREAMBLE) { nr_get_prach_resources(mac, CC_id, gNB_id, prach_resources, rach_ConfigDedicated); } } else if (ra->RA_backoff_cnt > 0) { @@ -735,7 +734,7 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB ra->RA_backoff_cnt--; - if ((ra->RA_backoff_cnt > 0 && ra->ra_state == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0) { + if ((ra->RA_backoff_cnt > 0 && ra->ra_state == nrRA_GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0) { nr_get_prach_resources(mac, CC_id, gNB_id, prach_resources, rach_ConfigDedicated); } } @@ -828,7 +827,7 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame LOG_D(MAC, "[UE %d] clearing RA_active flag...\n", mac->ue_id); ra->RA_active = 0; - ra->ra_state = RA_SUCCEEDED; + ra->ra_state = nrRA_SUCCEEDED; mac->state = UE_CONNECTED; free_and_zero(ra->Msg3_buffer); nr_mac_rrc_ra_ind(mac->ue_id, frame, true); @@ -854,7 +853,7 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr ra->first_Msg3 = true; ra->ra_PreambleIndex = -1; - ra->ra_state = RA_UE_IDLE; + ra->ra_state = nrRA_UE_IDLE; prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 991328b18c..23eff8e129 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -160,7 +160,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, rel15->coreset.pdcch_dmrs_scrambling_id = mac->physCellId; } - rel15->num_dci_options = (mac->ra.ra_state == WAIT_RAR || rnti_type == TYPE_SI_RNTI_) ? 1 : 2; + rel15->num_dci_options = (mac->ra.ra_state == nrRA_WAIT_RAR || rnti_type == TYPE_SI_RNTI_) ? 1 : 2; if (ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) { if (ss->searchSpaceType->choice.ue_Specific->dci_Formats == @@ -406,11 +406,11 @@ bool is_ss_monitor_occasion(const int frame, const int slot, const int slots_per return monitor; } -bool monitior_dci_for_other_SI(NR_UE_MAC_INST_t *mac, - const NR_SearchSpace_t *ss, - const int slots_per_frame, - const int frame, - const int slot) +bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac, + const NR_SearchSpace_t *ss, + const int slots_per_frame, + const int frame, + const int slot) { const struct NR_SI_SchedulingInfo *si_SchedulingInfo = mac->si_SchedulingInfo; // 5.2.2.3.2 in 331 @@ -508,20 +508,18 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl // are same as PDCCH monitoring occasions for SIB1 const NR_SearchSpace_t *ss = pdcch_config->otherSI_SS ? pdcch_config->otherSI_SS : mac->search_space_zero; // TODO configure SI-window - if (monitior_dci_for_other_SI(mac, ss, slots_per_frame, frame, slot)) { + if (monitor_dci_for_other_SI(mac, ss, slots_per_frame, frame, slot)) { LOG_D(NR_MAC_DCI, "Monitoring DCI for other SIs in frame %d slot %d\n", frame, slot); config_dci_pdu(mac, dl_config, TYPE_SI_RNTI_, slot, ss); } } - if (mac->state == UE_PERFORMING_RA && - mac->ra.ra_state >= WAIT_RAR) { + if (mac->state == UE_PERFORMING_RA && mac->ra.ra_state >= nrRA_WAIT_RAR) { // if RA is ongoing use RA search space if (is_ss_monitor_occasion(frame, slot, slots_per_frame, pdcch_config->ra_SS)) { - int rnti_type = mac->ra.ra_state == WAIT_RAR ? TYPE_RA_RNTI_ : TYPE_TC_RNTI_; + int rnti_type = mac->ra.ra_state == nrRA_WAIT_RAR ? TYPE_RA_RNTI_ : TYPE_TC_RNTI_; config_dci_pdu(mac, dl_config, rnti_type, slot, pdcch_config->ra_SS); } - } - else if (mac->state == UE_CONNECTED) { + } else if (mac->state == UE_CONNECTED) { for (int i = 0; i < pdcch_config->list_SS.count; i++) { NR_SearchSpace_t *ss = pdcch_config->list_SS.array[i]; if (is_ss_monitor_occasion(frame, slot, slots_per_frame, ss)) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index f81a142cd4..1b0e9f2b77 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -178,7 +178,7 @@ int get_rnti_type(const NR_UE_MAC_INST_t *mac, const uint16_t rnti) if (rnti == ra->ra_rnti) { rnti_type = TYPE_RA_RNTI_; - } else if (rnti == ra->t_crnti && (ra->ra_state == WAIT_RAR || ra->ra_state == WAIT_CONTENTION_RESOLUTION)) { + } else if (rnti == ra->t_crnti && (ra->ra_state == nrRA_WAIT_RAR || ra->ra_state == nrRA_WAIT_CONTENTION_RESOLUTION)) { rnti_type = TYPE_TC_RNTI_; } else if (rnti == mac->crnti) { rnti_type = TYPE_C_RNTI_; @@ -3504,7 +3504,7 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i // MAC SDU: 6 bytes (UE Contention Resolution Identity) mac_len = 6; - if(ra->ra_state == WAIT_CONTENTION_RESOLUTION) { + if (ra->ra_state == nrRA_WAIT_CONTENTION_RESOLUTION) { LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution identity: 0x%02x%02x%02x%02x%02x%02x Terminating RA procedure\n", mac->ue_id, frameP, @@ -3530,7 +3530,7 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i } else if (!ra_success){ // TODO: Handle failure of RA procedure @ MAC layer // nr_ra_failed(module_idP, CC_id, prach_resources, frameP, slot); // prach_resources is a PHY structure - ra->ra_state = RA_UE_IDLE; + ra->ra_state = nrRA_UE_IDLE; ra->RA_active = 0; } } @@ -3609,8 +3609,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, pdu, mac_ce); } - if (crnti && (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != RA_SUCCEEDED)) { - + if (crnti && (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != nrRA_SUCCEEDED)) { LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, (*crnti)); // MAC CE fixed subheader @@ -3625,7 +3624,6 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, mac_ce_size = sizeof(uint16_t); mac_ce += mac_ce_size; mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); - } if (truncated_bsr) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 02b4d38453..ab5adeda51 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1075,7 +1075,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator, TBS_bytes, ra->ra_state); - if (ra->ra_state == WAIT_RAR && !ra->cfra) { + if (ra->ra_state == nrRA_WAIT_RAR && !ra->cfra) { nr_get_msg3_payload(mac, ulsch_input_buffer, TBS_bytes); for (int k = 0; k < TBS_bytes; k++) { LOG_D(NR_MAC, "(%i): 0x%x\n", k, ulsch_input_buffer[k]); @@ -1083,7 +1083,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) mac_pdu_exist = 1; } else { if (ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator - && (mac->state == UE_CONNECTED || (ra->ra_state == WAIT_RAR && ra->cfra))) { + && (mac->state == UE_CONNECTED || (ra->ra_state == nrRA_WAIT_RAR && ra->cfra))) { // Getting IP traffic to be transmitted nr_ue_get_sdu(mac, cc_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes); mac_pdu_exist = 1; @@ -1096,13 +1096,13 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) ulcfg_pdu->pusch_config_pdu.tx_request_body.pdu_length = TBS_bytes; number_of_pdus++; } - if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra) { + if (ra->ra_state == nrRA_WAIT_CONTENTION_RESOLUTION && !ra->cfra) { LOG_I(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 retransmitted\n", frame_tx, slot_tx); // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 // transmission nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index); } - if (ra->ra_state == WAIT_RAR && !ra->cfra) { + if (ra->ra_state == nrRA_WAIT_RAR && !ra->cfra) { LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index); } @@ -2501,7 +2501,7 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, sub_fra { RA_config_t *ra = &mac->ra; ra->RA_offset = 2; // to compensate the rx frame offset at the gNB - if(ra->ra_state != GENERATE_PREAMBLE) + if (ra->ra_state != nrRA_GENERATE_PREAMBLE) return; fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index dbfa073ae9..b2ba4c77a4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -942,7 +942,8 @@ bool nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig uint8_t ra_index = 0; /* checking for free RA process */ for(; ra_index < NR_NB_RA_PROC_MAX; ra_index++) { - if((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra)) break; + if ((cc->ra[ra_index].ra_state == nrRA_gNB_IDLE) && (!cc->ra[ra_index].cfra)) + break; } if (ra_index == NR_NB_RA_PROC_MAX) { LOG_E(NR_MAC, "RA processes are not available for CFRA RNTI %04x\n", rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 5c99093f47..1a940b2da0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -574,7 +574,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { NR_RA_t *ra = &cc->ra[i]; - if (ra->state != RA_IDLE) + if (ra->ra_state != nrRA_gNB_IDLE) continue; pr_found = 0; @@ -648,21 +648,26 @@ void nr_initiate_ra_proc(module_id_t module_idP, LOG_D(NR_MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); int loop = 0; + bool exist_connected_ue, exist_in_pending_ra_ue; if (ra->rnti == 0) { // This condition allows for the usage of a preconfigured rnti for the CFRA + rnti_t trial = 0; do { // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values - ra->rnti = (taus() % 0xffef) + 1; + while (trial < 1 || trial > 0xffef) + trial = (taus() % 0xffef) + 1; + exist_connected_ue = find_nr_UE(&nr_mac->UE_info, trial) != NULL; + exist_in_pending_ra_ue = find_nr_RA_id(module_idP, CC_id, trial) != -1; loop++; - } while (loop != 100 - && !((find_nr_UE(&nr_mac->UE_info, ra->rnti) == NULL) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) - && ra->rnti >= 0x1 && ra->rnti <= 0xffef)); + } while (loop < 100 && (exist_connected_ue || exist_in_pending_ra_ue) ); if (loop == 100) { - LOG_E(NR_MAC, "[RAPROC] initialisation random access aborted\n"); - abort(); + LOG_E(NR_MAC, "[RAPROC] initialisation random access: no more available RNTIs for new UE\n"); + NR_SCHED_UNLOCK(&nr_mac->sched_lock); + return; } + ra->rnti = trial; } - ra->state = Msg2; + ra->ra_state = nrRA_Msg2; ra->RA_rnti = ra_rnti; ra->preamble_index = preamble_index; ra->beam_id = cc->ssb_index[beam_index]; @@ -887,7 +892,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, ra->UL_BWP.scs); // reset state to wait msg3 - ra->state = WAIT_Msg3; + ra->ra_state = nrRA_WAIT_Msg3; ra->Msg3_frame = sched_frame; ra->Msg3_slot = sched_slot; @@ -951,7 +956,7 @@ static void nr_get_Msg3alloc(module_id_t module_id, NrOfSymbols <= Msg3maxsymb) { ra->Msg3_tda_id = i; ra->msg3_startsymb = StartSymbolIndex; - ra->msg3_nrsymb = NrOfSymbols; + ra->msg3_nbSymb = NrOfSymbols; ra->Msg3_slot = temp_slot; break; } @@ -1134,13 +1139,13 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_f NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; NR_UE_ServingCell_Info_t *sc_info = &ra->sc_info; - if (ra->state == RA_IDLE) { + if (ra->ra_state == nrRA_gNB_IDLE) { LOG_W(NR_MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti); return; } const int scs = ul_bwp->scs; - const uint16_t mask = SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nrsymb); + const uint16_t mask = SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb); int buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, scs, mac->vrb_map_UL_size); uint16_t *vrb_map_UL = &RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[buffer_index * MAX_BWP_SIZE]; for (int i = 0; i < ra->msg3_nb_rb; ++i) { @@ -1309,8 +1314,15 @@ static void nr_generate_Msg2(module_id_t module_idP, pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; - LOG_A(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n", - module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state,pdcch_pdu_rel15->CoreSetType); + LOG_A(NR_MAC, + "[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n", + module_idP, + CC_id, + frameP, + slotP, + ra->RA_rnti, + ra->ra_state, + pdcch_pdu_rel15->CoreSetType); // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control // information to data and is reset every slot. @@ -1483,8 +1495,14 @@ static void nr_generate_Msg2(module_id_t module_idP, vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); } - ra->state = WAIT_Msg3; - LOG_D(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: rnti %04x RA state %d\n", module_idP, frameP, slotP, ra->rnti, ra->state); + ra->ra_state = nrRA_WAIT_Msg3; + LOG_D(NR_MAC, + "[gNB %d][RAPROC] Frame %d, Subframe %d: rnti %04x RA state %s\n", + module_idP, + frameP, + slotP, + ra->rnti, + nrra_text[ra->ra_state]); } } @@ -1933,7 +1951,7 @@ static void nr_generate_Msg4(module_id_t module_idP, vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); } - ra->state = WAIT_Msg4_ACK; + ra->ra_state = nrRA_WAIT_Msg4_ACK; LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes, next state WAIT_Msg4_ACK\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size); } } @@ -1971,7 +1989,7 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s } } else { LOG_I(NR_MAC, "(UE %04x) Received Nack of RA-Msg4. Preparing retransmission!\n", ra->rnti); - ra->state = Msg4; + ra->ra_state = nrRA_Msg4; } } } @@ -1981,7 +1999,7 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t /* we assume that this function is mutex-protected from outside */ NR_SCHED_ENSURE_LOCKED(&RC.nrmac[module_idP]->sched_lock); LOG_D(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti); - ra->state = RA_IDLE; + ra->ra_state = nrRA_gNB_IDLE; ra->timing_offset = 0; ra->RRC_timer = 20; ra->msg3_round = 0; @@ -2122,10 +2140,10 @@ void nr_schedule_RA(module_id_t module_idP, NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { NR_RA_t *ra = &cc->ra[i]; - LOG_D(NR_MAC, "RA[state:%d]\n", ra->state); + LOG_D(NR_MAC, "RA[state:%d]\n", ra->ra_state); // Check RA Contention Resolution timer - if (ra->state >= WAIT_Msg3) { + if (ra->ra_state >= nrRA_WAIT_Msg3) { ra->contention_resolution_timer--; if (ra->contention_resolution_timer < 0) { LOG_W(NR_MAC, "(%d.%d) RA Contention Resolution timer expired for UE 0x%04x, RA procedure failed...\n", frameP, slotP, ra->rnti); @@ -2135,19 +2153,19 @@ void nr_schedule_RA(module_id_t module_idP, } } - switch (ra->state) { - case Msg2: + switch (ra->ra_state) { + case nrRA_Msg2: nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); break; - case Msg3_retransmission: + case nrRA_Msg3_retransmission: nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req); break; - case Msg3_dcch_dtch: + case nrRA_Msg3_dcch_dtch: /* fallthrough */ - case Msg4: + case nrRA_Msg4: nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); break; - case WAIT_Msg4_ACK: + case nrRA_WAIT_Msg4_ACK: nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra); break; default: diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 932e11035b..265d1e819b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2000,15 +2000,12 @@ NR_UE_info_t *find_nr_UE(NR_UEs_t *UEs, rnti_t rntiP) int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) { - NR_RA_t *ra = &RC.nrmac[mod_idP]->common_channels[CC_idP].ra[0]; + NR_RA_t *ra = RC.nrmac[mod_idP]->common_channels[CC_idP].ra; for (int RA_id = 0; RA_id < NR_NB_RA_PROC_MAX; RA_id++) { - LOG_D(NR_MAC, "Checking RA_id %d for %x : state %d\n", - RA_id, - rntiP, - ra[RA_id].state); + LOG_D(NR_MAC, "Checking RA_id %d for %x : state %s\n", RA_id, rntiP, nrra_text[ra[RA_id].ra_state]); - if (ra[RA_id].state != RA_IDLE && ra[RA_id].rnti == rntiP) + if (ra[RA_id].ra_state != nrRA_gNB_IDLE && ra[RA_id].rnti == rntiP) return RA_id; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 1aee6f613e..dede9f606b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -223,7 +223,7 @@ static int nr_process_mac_pdu(instance_t module_idP, for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i]; - if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) { + if (ra->ra_state >= nrRA_WAIT_Msg3 && ra->rnti == UE->rnti) { // remove UE context just created after Msg.3 in some milliseconds // as the UE is one already known (not now, as the UE context is // still needed for the moment) @@ -231,7 +231,7 @@ static int nr_process_mac_pdu(instance_t module_idP, //mac_remove_nr_ue(RC.nrmac[module_idP], ra->rnti); // this UE is the one identified by the RNTI in pduP ra->rnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF); - ra->state = Msg3_dcch_dtch; + ra->ra_state = nrRA_Msg3_dcch_dtch; break; } } @@ -315,7 +315,7 @@ static int nr_process_mac_pdu(instance_t module_idP, NR_UE_info_t* UE_idx = UE; for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i]; - if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) { + if (ra->ra_state >= nrRA_WAIT_Msg3 && ra->rnti == UE->rnti) { uint8_t *next_subpduP = pduP + mac_subheader_len + mac_len; if ((pduP[mac_subheader_len+mac_len] & 0x3F) == UL_SCH_LCID_C_RNTI) { crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF); @@ -488,7 +488,7 @@ static bool get_UE_waiting_CFRA_msg3(const gNB_MAC_INST *gNB_mac, const int CC_i bool UE_waiting_CFRA_msg3 = false; for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { const NR_RA_t *ra = &gNB_mac->common_channels[CC_id].ra[i]; - if (ra->cfra == true && ra->state == WAIT_Msg3 && frame == ra->Msg3_frame && slot == ra->Msg3_slot) { + if (ra->cfra == true && ra->ra_state == nrRA_WAIT_Msg3 && frame == ra->Msg3_frame && slot == ra->Msg3_slot) { UE_waiting_CFRA_msg3 = true; break; } @@ -512,7 +512,7 @@ void handle_nr_ul_harq(const int CC_idP, LOG_D(NR_MAC, "handle harq for rnti %04x, in RA process\n", crc_pdu->rnti); for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) { NR_RA_t *ra = &nrmac->common_channels[CC_idP].ra[i]; - if (ra->state >= WAIT_Msg3 && ra->rnti == crc_pdu->rnti) { + if (ra->ra_state >= nrRA_WAIT_Msg3 && ra->rnti == crc_pdu->rnti) { NR_SCHED_UNLOCK(&nrmac->sched_lock); return; } @@ -708,11 +708,11 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, * it. */ for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) { NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i]; - if (ra->state != WAIT_Msg3) + if (ra->ra_state != nrRA_WAIT_Msg3) continue; if(no_sig) { - LOG_D(NR_MAC, "Random Access %i failed at state %i (no signal)\n", i, ra->state); + LOG_D(NR_MAC, "Random Access %i failed at state %s (no signal)\n", i, nrra_text[ra->ra_state]); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); } else { @@ -724,7 +724,12 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, current_rnti); if( (frameP==ra->Msg3_frame) && (slotP==ra->Msg3_slot) ) { - LOG_D(NR_MAC, "Random Access %i failed at state %i (TC_RNTI %04x RNTI %04x)\n", i, ra->state,ra->rnti,current_rnti); + LOG_D(NR_MAC, + "Random Access %i failed at state %s (TC_RNTI %04x RNTI %04x)\n", + i, + nrra_text[ra->ra_state], + ra->rnti, + current_rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); } @@ -733,7 +738,12 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, NR_UE_info_t *UE_msg3_stage = UE ? UE : add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup); if (!UE_msg3_stage) { - LOG_W(NR_MAC, "Random Access %i discarded at state %i (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", i, ra->state, ra->rnti, current_rnti); + LOG_W(NR_MAC, + "Random Access %i discarded at state %s (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", + i, + nrra_text[ra->ra_state], + ra->rnti, + current_rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); return; @@ -789,8 +799,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, // harq_pid set a non valid value because it is not used in this call // the function is only called to decode the contention resolution sub-header if (nr_process_mac_pdu(gnb_mod_idP, UE_msg3_stage, CC_idP, frameP, slotP, sduP, sdu_lenP, -1) == 0) { - - if (ra->state == Msg3_dcch_dtch) { + if (ra->ra_state == nrRA_Msg3_dcch_dtch) { // Check if the UE identified by C-RNTI still exists at the gNB NR_UE_info_t * UE_C = find_nr_UE(&gNB_mac->UE_info, ra->rnti); if (!UE_C) { @@ -815,11 +824,9 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", UE_C->rnti); nr_mac_trigger_reconfiguration(RC.nrmac[gnb_mod_idP], UE_C); } - } - else { - LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %d)\n", - ra->rnti, ra->state); - ra->state = Msg4; + } else { + LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %s)\n", ra->rnti, nrra_text[ra->ra_state]); + ra->ra_state = nrRA_Msg4; } } else { @@ -832,7 +839,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, } else { for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) { NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i]; - if (ra->state != WAIT_Msg3) + if (ra->ra_state != nrRA_WAIT_Msg3) continue; if( (frameP!=ra->Msg3_frame) || (slotP!=ra->Msg3_slot)) @@ -840,13 +847,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, // for CFRA (NSA) do not schedule retransmission of msg3 if (ra->cfra) { - LOG_D(NR_MAC, "Random Access %i failed at state %i (NSA msg3 reception failed)\n", i, ra->state); + LOG_D(NR_MAC, "Random Access %i failed at state %s (NSA msg3 reception failed)\n", i, nrra_text[ra->ra_state]); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); return; } if (ra->msg3_round >= gNB_mac->ul_bler.harq_round_max - 1) { - LOG_W(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state); + LOG_W(NR_MAC, "Random Access %i failed at state %s (Reached msg3 max harq rounds)\n", i, nrra_text[ra->ra_state]); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); return; } @@ -854,7 +861,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i); ra->msg3_round++; - ra->state = Msg3_retransmission; + ra->ra_state = nrRA_Msg3_retransmission; } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 9028dbc797..a8fa48c849 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -85,6 +85,7 @@ /* MAC */ #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" +#include "NR_TAG.h" #include @@ -111,15 +112,16 @@ typedef struct { } NR_list_t; typedef enum { - RA_IDLE = 0, - Msg2 = 1, - WAIT_Msg3 = 2, - Msg3_retransmission = 3, - Msg3_dcch_dtch = 4, - Msg4 = 5, - WAIT_Msg4_ACK = 6 + nrRA_gNB_IDLE = 0, + nrRA_Msg2 = 1, + nrRA_WAIT_Msg3 = 2, + nrRA_Msg3_retransmission = 3, + nrRA_Msg3_dcch_dtch = 4, + nrRA_Msg4 = 5, + nrRA_WAIT_Msg4_ACK = 6 } RA_gNB_state_t; - +static const char *const nrra_text[] = + {"IDLE", "Msg2", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "WAIT_Msg4_ACK"}; typedef struct nr_pdsch_AntennaPorts_t { int N1; int N2; @@ -160,7 +162,7 @@ typedef struct NR_sched_pdcch { /*! \brief gNB template for the Random access information */ typedef struct { /// Flag to indicate this process is active - RA_gNB_state_t state; + RA_gNB_state_t ra_state; /// CORESET0 configured flag int coreset0_configured; /// Slot where preamble was received @@ -174,7 +176,7 @@ typedef struct { /// Frame where Msg3 is to be sent frame_t Msg3_frame; /// Msg3 time domain allocation index - uint8_t Msg3_tda_id; + int Msg3_tda_id; /// harq_pid used for Msg4 transmission uint8_t harq_pid; /// UE RNTI allocated during RAR @@ -190,25 +192,17 @@ typedef struct { /// Timeout for RRC connection int16_t RRC_timer; /// Msg3 first RB - uint8_t msg3_first_rb; + int msg3_first_rb; /// Msg3 number of RB - uint8_t msg3_nb_rb; + int msg3_nb_rb; /// Msg3 BWP start - uint8_t msg3_bwp_start; + int msg3_bwp_start; /// Msg3 TPC command uint8_t msg3_TPC; - /// Msg3 ULdelay command - uint8_t msg3_ULdelay; - /// Msg3 cqireq command - uint8_t msg3_cqireq; /// Round of Msg3 HARQ uint8_t msg3_round; int msg3_startsymb; - int msg3_nrsymb; - /// TBS used for Msg4 - int msg4_TBsize; - /// MCS used for Msg4 - int msg4_mcs; + int msg3_nbSymb; /// MAC PDU length for Msg4 int mac_pdu_length; /// RA search space @@ -233,17 +227,12 @@ typedef struct { /*! \brief gNB common channels */ typedef struct { - int Ncp; - int nr_band; frame_type_t frame_type; - uint64_t dl_CarrierFreq; NR_BCCH_BCH_Message_t *mib; NR_BCCH_DL_SCH_Message_t *sib1; NR_ServingCellConfigCommon_t *ServingCellConfigCommon; /// pre-configured ServingCellConfig that is default for every UE NR_ServingCellConfig_t *pre_ServingCellConfig; - NR_ARFCN_ValueEUTRA_t ul_CarrierFreq; - long ul_Bandwidth; /// Outgoing MIB PDU for PHY uint8_t MIB_pdu[3]; /// Outgoing BCCH pdu for PHY @@ -256,23 +245,20 @@ typedef struct { /// VRB map for common channels and PUSCH, dynamically allocated because /// length depends on number of slots and RBs uint16_t *vrb_map_UL; - /// number of subframe allocation pattern available for MBSFN sync area - uint8_t num_sf_allocation_pattern; ///Number of active SSBs - uint8_t num_active_ssb; + int num_active_ssb; //Total available prach occasions per configuration period - uint32_t total_prach_occasions_per_config_period; + int total_prach_occasions_per_config_period; //Total available prach occasions - uint32_t total_prach_occasions; + int total_prach_occasions; //Max Association period - uint8_t max_association_period; + int max_association_period; //SSB index uint8_t ssb_index[MAX_NUM_OF_SSB]; //CB preambles for each SSB - uint8_t cb_preambles_per_ssb; + int cb_preambles_per_ssb; } NR_COMMON_channels_t; - // SP ZP CSI-RS Resource Set Activation/Deactivation MAC CE typedef struct sp_zp_csirs { bool is_scheduled; //ZP CSI-RS ACT/Deact MAC CE is scheduled diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 7f9f5aa55e..60fdec5e23 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -348,13 +348,13 @@ static bool is_my_dci(NR_UE_MAC_INST_t *mac, nfapi_nr_dl_dci_pdu_t *received_pdu return false; if (received_pdu->RNTI == 0xFFFF && mac->phy_config_request_sent) return false; - if (received_pdu->RNTI != mac->crnti && mac->ra.ra_state == RA_SUCCEEDED) + if (received_pdu->RNTI != mac->crnti && mac->ra.ra_state == nrRA_SUCCEEDED) return false; - if (received_pdu->RNTI != mac->ra.t_crnti && mac->ra.ra_state == WAIT_CONTENTION_RESOLUTION) + if (received_pdu->RNTI != mac->ra.t_crnti && mac->ra.ra_state == nrRA_WAIT_CONTENTION_RESOLUTION) return false; - if (received_pdu->RNTI != 0x10b && mac->ra.ra_state == WAIT_RAR) + if (received_pdu->RNTI != 0x10b && mac->ra.ra_state == nrRA_WAIT_RAR) return false; - if (received_pdu->RNTI != 0xFFFF && mac->ra.ra_state <= GENERATE_PREAMBLE) + if (received_pdu->RNTI != 0xFFFF && mac->ra.ra_state <= nrRA_GENERATE_PREAMBLE) return false; } return true; @@ -477,8 +477,7 @@ static void fill_rx_ind(nfapi_nr_pdu_t *pdu_list, fapi_nr_rx_indication_t *rx_in pdu += pdu_list->TLVs[j].length; } bool ack_nack = true; - if (mac->ra.ra_state >= RA_SUCCEEDED && should_drop_transport_block(rx_ind->slot, mac->crnti)) - { + if (mac->ra.ra_state >= nrRA_SUCCEEDED && should_drop_transport_block(rx_ind->slot, mac->crnti)) { ack_nack = false; } rx_ind->rx_indication_body[pdu_idx].pdsch_pdu.ack_nack = ack_nack; @@ -742,10 +741,8 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, int slots_per_frame = 20; //30 kHZ subcarrier spacing int slot_ahead = 2; // TODO: Make this dynamic - if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon, - (slot + slot_ahead) % slots_per_frame, - mac->frame_type) - && mac->ra.ra_state != RA_SUCCEEDED) { + if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon, (slot + slot_ahead) % slots_per_frame, mac->frame_type) + && mac->ra.ra_state != nrRA_SUCCEEDED) { // If we filled dl_info AFTER we got the slot indication, we want to check if we should fill tx_req: nr_uplink_indication_t ul_info = {.slot = (slot + slot_ahead) % slots_per_frame, .frame = slot + slot_ahead >= slots_per_frame ? (frame + 1) % 1024 : frame}; @@ -873,25 +870,22 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE. If we have not yet completed the CBRA/ CFRA procedure, we need to queue all UL_TTI_REQs. */ for (int i = 0; i < ul_tti_request->n_pdus; i++) { - if (ul_tti_request->pdus_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE && - mac->ra.ra_state >= RA_SUCCEEDED) { - if (!put_queue(&nr_ul_tti_req_queue, ul_tti_request)) - { - LOG_D(NR_PHY, "put_queue failed for ul_tti_request, calling put_queue_replace.\n"); - nfapi_nr_ul_tti_request_t *evicted_ul_tti_req = put_queue_replace(&nr_ul_tti_req_queue, ul_tti_request); - free(evicted_ul_tti_req); - } - break; + if (ul_tti_request->pdus_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE + && mac->ra.ra_state >= nrRA_SUCCEEDED) { + if (!put_queue(&nr_ul_tti_req_queue, ul_tti_request)) { + LOG_D(NR_PHY, "put_queue failed for ul_tti_request, calling put_queue_replace.\n"); + nfapi_nr_ul_tti_request_t *evicted_ul_tti_req = put_queue_replace(&nr_ul_tti_req_queue, ul_tti_request); + free(evicted_ul_tti_req); } - else if (mac->ra.ra_state < RA_SUCCEEDED) { - if (!put_queue(&nr_ul_tti_req_queue, ul_tti_request)) - { - LOG_D(NR_PHY, "put_queue failed for ul_tti_request, calling put_queue_replace.\n"); - nfapi_nr_ul_tti_request_t *evicted_ul_tti_req = put_queue_replace(&nr_ul_tti_req_queue, ul_tti_request); - free(evicted_ul_tti_req); - } - break; + break; + } else if (mac->ra.ra_state < nrRA_SUCCEEDED) { + if (!put_queue(&nr_ul_tti_req_queue, ul_tti_request)) { + LOG_D(NR_PHY, "put_queue failed for ul_tti_request, calling put_queue_replace.\n"); + nfapi_nr_ul_tti_request_t *evicted_ul_tti_req = put_queue_replace(&nr_ul_tti_req_queue, ul_tti_request); + free(evicted_ul_tti_req); } + break; + } } break; } @@ -922,8 +916,7 @@ static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request) if (pdu_list->PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE) { const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu = &pdu_list->pdsch_pdu.pdsch_pdu_rel15; - if (pdsch_pdu->rnti == mac->crnti && mac->ra.ra_state == RA_SUCCEEDED) - { + if (pdsch_pdu->rnti == mac->crnti && mac->ra.ra_state == nrRA_SUCCEEDED) { read_channel_param(pdsch_pdu, dl_tti_request->Slot, count_sent); count_sent++; LOG_T(NR_MAC, "pdsch_pdu->rnti %x mac->crnti %x mac->ra.ra_state %d count_sent %d\n", @@ -1124,7 +1117,7 @@ void update_harq_status(NR_UE_MAC_INST_t *mac, uint8_t harq_pid, uint8_t ack_nac if (current_harq->active) { LOG_D(PHY,"Updating harq_status for harq_id %d, ack/nak %d\n", harq_pid, current_harq->ack); // we can prepare feedback for MSG4 in advance - if (mac->ra.ra_state == WAIT_CONTENTION_RESOLUTION) + if (mac->ra.ra_state == nrRA_WAIT_CONTENTION_RESOLUTION) prepare_msg4_feedback(mac, harq_pid, ack_nack); else { current_harq->ack = ack_nack; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c index 59d6b6b673..52aedfbccc 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c @@ -121,8 +121,7 @@ bool should_drop_transport_block(int slot, uint16_t rnti) /* We want to avoid dropping setup messages because this would be pathological. */ NR_UE_MAC_INST_t *mac = get_mac_inst(0); - if (mac->ra.ra_state < RA_SUCCEEDED) - { + if (mac->ra.ra_state < nrRA_SUCCEEDED) { LOG_D(NR_MAC, "Not dropping because MAC state: %d", mac->ra.ra_state); return false; }