nr_ue_dci_configuration.c 12.6 KB
Newer Older
Raymond Knopp's avatar
Raymond Knopp committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * 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
cig's avatar
cig committed
24
 * \author R. Knopp, G. Casati
Raymond Knopp's avatar
Raymond Knopp committed
25
 * \date 2020
cig's avatar
cig committed
26 27 28
 * \version 0.2
 * \company Eurecom, Fraunhofer IIS
 * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de
Raymond Knopp's avatar
Raymond Knopp committed
29 30 31 32 33 34 35 36 37
 * \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"
cig's avatar
cig committed
38
#include "common/utils/nr/nr_common.h"
cig's avatar
cig committed
39
#include "executables/softmodem-common.h"
Raymond Knopp's avatar
Raymond Knopp committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53
#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");
  
54
  rel15->number_of_candidates=3;
Raymond Knopp's avatar
Raymond Knopp committed
55 56
  rel15->CCE[0]=0;
  rel15->L[0]=4;
57 58 59 60 61
  rel15->CCE[1]=4;
  rel15->L[1]=4;
  rel15->CCE[2]=8;
  rel15->L[2]=4;

Raymond Knopp's avatar
Raymond Knopp committed
62 63
}

cig's avatar
cig committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot) {

  NR_ServingCellConfig_t *scd = mac->scd;
  NR_BWP_Downlink_t *bwp;
  NR_BWP_DownlinkCommon_t *bwp_Common;
  NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated;
  NR_SetupRelease_PDCCH_Config_t *pdcch_Config;
  NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon;
  struct NR_PDCCH_Config__controlResourceSetToAddModList *controlResourceSetToAddModList;
  struct NR_PDCCH_Config__searchSpacesToAddModList *searchSpacesToAddModList;
  struct NR_UplinkConfig__uplinkBWP_ToAddModList *uplinkBWP_ToAddModList;
  NR_SearchSpace_t *NR_SearchSpace;
  NR_ControlResourceSet_t *coreset;

  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;

  uint8_t bwp_id = 1;
  int ss_id, sps;

  // get PDCCH configuration(s) (Coreset, SearchSpace, etc...) from BWP Dedicated in serving cell config dedicated (scd)
  // get BWP 1, Coreset ID 0, SearchSpace ID 0 (i.e. configured in MIB and in ServingCellConfigCommon)

  // Check dedicated DL BWP
  if (mac->DLbwp[0] == NULL) {
    NR_SearchSpace_t *ss;
    int ss_id = 0;

    AssertFatal(scd->downlinkBWP_ToAddModList != NULL, "downlinkBWP_ToAddModList is null\n");
    AssertFatal(scd->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList->list->count is %d\n", scd->downlinkBWP_ToAddModList->list.count);
    mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1];

    dl_bwp_Dedicated = mac->DLbwp[0]->bwp_Dedicated;
    AssertFatal(dl_bwp_Dedicated != NULL, "dl_bwp_Dedicated is null\n");

    bwp_Common = mac->DLbwp[0]->bwp_Common;
    AssertFatal(bwp_Common != NULL, "bwp_Common is null\n");

    pdcch_Config = dl_bwp_Dedicated->pdcch_Config;
    AssertFatal(pdcch_Config != NULL, "pdcch_Config is null\n");

    pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
    AssertFatal(pdcch_ConfigCommon != NULL, "pdcch_ConfigCommon is null\n");
    AssertFatal(pdcch_ConfigCommon->choice.setup->ra_SearchSpace != NULL, "ra_SearchSpace must be available in DL BWP\n");
cig's avatar
cig committed
107

cig's avatar
cig committed
108 109 110 111 112 113 114 115
    controlResourceSetToAddModList = pdcch_Config->choice.setup->controlResourceSetToAddModList;
    AssertFatal(controlResourceSetToAddModList != NULL, "controlResourceSetToAddModList is null\n");

    AssertFatal(controlResourceSetToAddModList->list.count == 1, "controlResourceSetToAddModList->list.count=%d\n", controlResourceSetToAddModList->list.count);

    mac->coreset[0][0] = controlResourceSetToAddModList->list.array[0];
    coreset = mac->coreset[0][0];
    AssertFatal(coreset != NULL, "coreset[0][0] is null\n");
Raymond Knopp's avatar
Raymond Knopp committed
116
    
cig's avatar
cig committed
117 118 119 120 121 122 123 124 125 126 127
    searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList;
    AssertFatal(searchSpacesToAddModList != NULL, "searchSpacesToAddModList is null\n");
    AssertFatal(searchSpacesToAddModList->list.count > 0, "searchSpacesToAddModList is empty\n");
    AssertFatal(searchSpacesToAddModList->list.count < FAPI_NR_MAX_SS_PER_CORESET, "too many searchpaces per coreset %d\n", searchSpacesToAddModList->list.count);

    for (int i = 0; i < searchSpacesToAddModList->list.count; i++) {
      ss = 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 == coreset->controlResourceSetId, "ss->controlResourceSetId is unknown\n");
      mac->SSpace[0][0][ss_id] = ss;
Raymond Knopp's avatar
Raymond Knopp committed
128 129
      ss_id++;
    }
cig's avatar
cig committed
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
  }

  // Check dedicated UL BWP
  if (mac->ULbwp[0] == NULL) {
    uplinkBWP_ToAddModList = scd->uplinkConfig->uplinkBWP_ToAddModList;
    AssertFatal(uplinkBWP_ToAddModList != NULL, "uplinkBWP_ToAddModList is null\n");
    AssertFatal(uplinkBWP_ToAddModList->list.count == 1, "uplinkBWP_ToAddModList->list->count is %d\n", uplinkBWP_ToAddModList->list.count);
    mac->ULbwp[0] = uplinkBWP_ToAddModList->list.array[bwp_id - 1];
    AssertFatal(mac->ULbwp[0]->bwp_Dedicated != NULL, "UL bwp_Dedicated is null\n");
  }

  bwp = mac->DLbwp[0];
  bwp_Common = bwp->bwp_Common;
  pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
  dl_bwp_Dedicated = bwp->bwp_Dedicated;
  pdcch_Config = dl_bwp_Dedicated->pdcch_Config;
  searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList;

  // check USSs
  ss_id = 0;
  NR_SearchSpace = mac->SSpace[0][0][ss_id];
  while(NR_SearchSpace != NULL && ss_id < searchSpacesToAddModList->list.count) {
    AssertFatal(NR_SearchSpace->monitoringSymbolsWithinSlot != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot is null\n");
    AssertFatal(NR_SearchSpace->monitoringSymbolsWithinSlot->buf != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot->buf is null\n");
    ss_id++;
  }

  if (mac->crnti > 0) {

    NR_SearchSpace_t *css;
160
    NR_SearchSpace_t *uss = NULL;
cig's avatar
cig committed
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
    NR_ServingCellConfigCommon_t *scc;
    NR_SearchSpaceId_t ra_SearchSpaceId;
    rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
    uint16_t monitoringSymbolsWithinSlot;
    uint8_t add_dci = 1;

    AssertFatal(mac->scc != NULL, "scc is null\n");

    scc = mac->scc;
    rel15->dci_format = NR_DL_DCI_FORMAT_1_0;

    // CoReSet configuration
    coreset = mac->coreset[0][0];
    rel15->coreset.duration = coreset->duration;
    for (int i = 0; i < 6; i++)
      rel15->coreset.frequency_domain_resource[i] = coreset->frequencyDomainResources.buf[i];

    rel15->coreset.CceRegMappingType = coreset->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) {
      struct NR_ControlResourceSet__cce_REG_MappingType__interleaved *interleaved = coreset->cce_REG_MappingType.choice.interleaved;
      rel15->coreset.RegBundleSize = (interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2 + interleaved->reg_BundleSize);
      rel15->coreset.InterleaverSize = (interleaved->interleaverSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2 + interleaved->interleaverSize);
      AssertFatal(scc->physCellId != NULL, "mac->scc->physCellId is null\n");
      rel15->coreset.ShiftIndex = interleaved->shiftIndex != NULL ? *interleaved->shiftIndex : *scc->physCellId;
    } else {
      rel15->coreset.RegBundleSize = 0;
      rel15->coreset.InterleaverSize = 0;
      rel15->coreset.ShiftIndex = 0;
Raymond Knopp's avatar
Raymond Knopp committed
190
    }
cig's avatar
cig committed
191 192 193 194 195

    rel15->coreset.CoreSetType = 1;
    rel15->coreset.precoder_granularity = coreset->precoderGranularity;

    if (mac->ra_state == WAIT_RAR){
196

cig's avatar
cig committed
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
       NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP;
       struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
       AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH CSS list has 0 elements\n");

       ra_SearchSpaceId = *pdcch_ConfigCommon->choice.setup->ra_SearchSpace;

       // fetch the CSS for RA from the CSS list
       for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
         css = commonSearchSpaceList->list.array[i];
         if(css->searchSpaceId == ra_SearchSpaceId)
           break;
       }

       // check CSSs
       if(css != NULL) {
         AssertFatal(css->monitoringSymbolsWithinSlot != NULL, "css->monitoringSymbolsWithinSlot is null\n");
         AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n");
       }

      if (frame == mac->msg2_rx_frame && slot == mac->msg2_rx_slot){
        sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12;
        monitoringSymbolsWithinSlot = (css->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (css->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
        rel15->rnti = mac->ra_rnti;
        rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
        rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); // NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
        rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
        rel15->dci_length = nr_dci_size(rel15->dci_format, NR_RNTI_RA, rel15->BWPSize);
        for (int i = 0; i < sps; i++)
        if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) {
          rel15->coreset.StartSymbolIndex = i;
          break;
        }
        fill_dci_search_candidates(css, rel15);
230
      } else {
cig's avatar
cig committed
231
        add_dci = 0;
232
      }
cig's avatar
cig committed
233
    } else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION){
234

cig's avatar
cig committed
235 236 237
      rel15->rnti = mac->t_crnti;

    } else {
238

cig's avatar
cig committed
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
      rel15->rnti = mac->crnti;
      rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, 275);
      rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275);
      rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing;
      rel15->dci_length = nr_dci_size(rel15->dci_format, NR_RNTI_C, rel15->BWPSize);
      // 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++){
        uss = mac->SSpace[0][0][ss_id];
        if (uss->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");
      sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
      // for SPS=14 8 MSBs in positions 13 down to 6
      monitoringSymbolsWithinSlot = (uss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (uss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
      for (int i = 0; i < sps; i++)
        if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) {
          rel15->coreset.StartSymbolIndex = i;
          break;
        }
      fill_dci_search_candidates(uss, rel15);
    }
cig's avatar
cig committed
260 261 262 263 264 265 266 267 268 269 270 271 272

    // Scrambling RNTI
    if (coreset->pdcch_DMRS_ScramblingID) {
      rel15->coreset.pdcch_dmrs_scrambling_id = *coreset->pdcch_DMRS_ScramblingID;
      rel15->coreset.scrambling_rnti = mac->t_crnti;
    } else {
      rel15->coreset.pdcch_dmrs_scrambling_id = *scc->physCellId;
      if(mac->ra_state == WAIT_RAR)
        rel15->coreset.scrambling_rnti = 0;
      else
        rel15->coreset.scrambling_rnti = rel15->rnti;
    }

cig's avatar
cig committed
273
    if (add_dci){
Raymond Knopp's avatar
Raymond Knopp committed
274 275 276 277 278
      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;
    }
  }
}