/* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ /* \file nr_ue_dci_configuration.c * \brief functions for generating dci search procedures based on RRC Serving Cell Group Configuration * \author R. Knopp * \date 2020 * \version 0.1 * \company Eurecom * \email: knopp@eurecom.fr * \note * \warning */ #include "mac_proto.h" #include "mac_defs.h" #include "assertions.h" #include "LAYER2/NR_MAC_UE/mac_extern.h" #include "mac_defs.h" #include "common/utils/nr/nr_common.h" #include "executables/softmodem-common.h" #include <stdio.h> #ifdef NR_PDCCH_DCI_TOOLS_DEBUG #define LOG_DCI_D(a...) printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) ->" a) #else #define LOG_DCI_D(a...) #endif #define LOG_DCI_PARM(a...) LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci)" a) void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) { LOG_D(MAC,"Filling search candidates for DCI\n"); rel15->number_of_candidates=3; rel15->CCE[0]=0; rel15->L[0]=4; rel15->CCE[1]=4; rel15->L[1]=4; rel15->CCE[2]=8; rel15->L[2]=4; } void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, int slot) { // check if DL slot if (slot == 1 || slot == 7) { // get BWP 1, Coreset 0, SearchSpace 0 if (mac->DLbwp[0]==NULL) { AssertFatal(mac->scd->downlinkBWP_ToAddModList!=NULL,"downlinkBWP_ToAddModList is null\n"); AssertFatal(mac->scd->downlinkBWP_ToAddModList->list.count==1,"downlinkBWP_ToAddModList->list->count is %d\n", mac->scd->downlinkBWP_ToAddModList->list.count); mac->DLbwp[0] = mac->scd->downlinkBWP_ToAddModList->list.array[0]; AssertFatal(mac->DLbwp[0]->bwp_Dedicated!=NULL,"bwp_Dedicated is null\n"); AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config!=NULL,"pdcch_Config is null\n"); AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList!=NULL,"controlResourceSetToAddModList is null\n"); AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count==1,"controlResourceSetToAddModList->list.count=%d\n", mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count); mac->coreset[0][0] = mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[0]; AssertFatal(mac->coreset[0][0]!=NULL,"coreset[0][0] is null\n"); AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, "searchPsacesToAddModList is empty\n"); NR_SearchSpace_t *ss; int ss_id=0; AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count<FAPI_NR_MAX_SS_PER_CORESET, "too many searchpaces per coreset %d\n", mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count); for (int i=0;i<mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) { ss=mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n"); AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n"); AssertFatal(*ss->controlResourceSetId == mac->coreset[0][0]->controlResourceSetId,"ss->controlResourceSetId is unknown\n"); mac->SSpace[0][0][ss_id] = ss; ss_id++; } } if (mac->ULbwp[0]==NULL) { AssertFatal(mac->scd->uplinkConfig->uplinkBWP_ToAddModList!=NULL,"uplinkBWP_ToAddModList is null\n"); AssertFatal(mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.count==1,"uplinkBWP_ToAddModList->list->count is %d\n", mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.count); mac->ULbwp[0] = mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]; AssertFatal(mac->ULbwp[0]->bwp_Dedicated!=NULL,"bwp_Dedicated is null\n"); } // check search spaces int ss_id=0; fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; int sps =mac->DLbwp[0]->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12; while(mac->SSpace[0][0][ss_id]!=NULL && ss_id < mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count) { AssertFatal(mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n"); AssertFatal(mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n"); ss_id++; } if (mac->ra_state == WAIT_RAR) { // check for RAR rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; // rel15->rnti = 2;//get_RA_RNTI(mac,frame,slot); // WIP } else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION) { rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; rel15->rnti = mac->t_crnti; //dl_config->number_pdus = dl_config->number_pdus + 1; } if (mac->crnti>0) { rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; rel15->dci_format = NR_DL_DCI_FORMAT_1_0; if (slot == 0 || slot == 1){ rel15->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); rel15->dci_length = nr_dci_size(rel15->dci_format, NR_RNTI_C, rel15->BWPSize); } else if (slot == 7){ rel15->BWPSize = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); rel15->dci_length = nr_dci_size(rel15->dci_format, NR_RNTI_RA, rel15->BWPSize); } rel15->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); rel15->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; // get UE-specific search space for (ss_id=0;ss_id<FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[0][0][ss_id]!=NULL;ss_id++) if (mac->SSpace[0][0][ss_id]->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) break; AssertFatal(ss_id<FAPI_NR_MAX_SS_PER_CORESET,"couldn't find a UE-specific SS\n"); // for SPS=14 8 MSBs in positions 13 downto 6, uint16_t monitoringSymbolsWithinSlot = (mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); for (int i=0; i<sps; i++) if ((monitoringSymbolsWithinSlot>>(sps-1-i))&1) { rel15->coreset.StartSymbolIndex=i; break; } rel15->coreset.duration = mac->coreset[0][0]->duration; for (int i=0;i<6;i++) rel15->coreset.frequency_domain_resource[i] = mac->coreset[0][0]->frequencyDomainResources.buf[i]; rel15->coreset.CceRegMappingType = mac->coreset[0][0]->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved? FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED; if (rel15->coreset.CceRegMappingType == FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED) { rel15->coreset.RegBundleSize = (mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->reg_BundleSize); rel15->coreset.InterleaverSize = (mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->interleaverSize); AssertFatal(mac->scc->physCellId != NULL,"mac->scc->physCellId is null\n"); rel15->coreset.ShiftIndex = mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->shiftIndex : *mac->scc->physCellId; } else { rel15->coreset.RegBundleSize = 0; rel15->coreset.InterleaverSize = 0; rel15->coreset.ShiftIndex = 0; } rel15->coreset.CoreSetType = 1; rel15->coreset.precoder_granularity = mac->coreset[0][0]->precoderGranularity; if (mac->coreset[0][0]->pdcch_DMRS_ScramblingID) { rel15->coreset.pdcch_dmrs_scrambling_id = *mac->coreset[0][0]->pdcch_DMRS_ScramblingID; rel15->coreset.scrambling_rnti = mac->t_crnti; } else { rel15->coreset.pdcch_dmrs_scrambling_id = *mac->scc->physCellId; rel15->coreset.scrambling_rnti = 0; } if (get_softmodem_params()->do_ra && slot == 7) rel15->rnti = mac->ra_rnti; else rel15->rnti = mac->crnti; fill_dci_search_candidates(mac->SSpace[0][0][ss_id],rel15); dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; dl_config->number_pdus = dl_config->number_pdus + 1; } } }