config_ue.c 42.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * 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
 */

22
/* \file config_ue.c
23
 * \brief UE and eNB configuration performed by RRC or as a consequence of RRC procedures
24 25
 * \author R. Knopp, K.H. HSU
 * \date 2018
26
 * \version 0.1
27 28 29 30
 * \company Eurecom / NTUST
 * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr
 * \note
 * \warning
31
 */
32

33
//#include "mac_defs.h"
34
#include <NR_MAC_gNB/mac_proto.h>
35
#include "NR_MAC_UE/mac_proto.h"
36
#include "NR_MAC-CellGroupConfig.h"
37
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
38
#include <executables/softmodem-common.h>
39

40
extern uint32_t N_RB_DL;
41

42 43 44 45
int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
                         int mu,
                         int nrofDownlinkSlots, int nrofDownlinkSymbols,
                         int nrofUplinkSlots,   int nrofUplinkSymbols) {
46

47 48 49
  int slot_number = 0;
  int nb_periods_per_frame;
  int nb_slots_to_set = TDD_CONFIG_NB_FRAMES*(1<<mu)*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
50

51 52 53 54
  switch(cfg->tdd_table.tdd_period) {
    case 0:
      nb_periods_per_frame = 20; // 10ms/0p5ms
      break;
Raymond Knopp's avatar
Raymond Knopp committed
55

56 57 58
    case 1:
      nb_periods_per_frame = 16; // 10ms/0p625ms
      break;
Raymond Knopp's avatar
Raymond Knopp committed
59

60 61 62
    case 2:
      nb_periods_per_frame = 10; // 10ms/1ms
      break;
Raymond Knopp's avatar
Raymond Knopp committed
63

64 65 66
    case 3:
      nb_periods_per_frame = 8; // 10ms/1p25ms
      break;
Raymond Knopp's avatar
Raymond Knopp committed
67

68 69 70
    case 4:
      nb_periods_per_frame = 5; // 10ms/2ms
      break;
Raymond Knopp's avatar
Raymond Knopp committed
71

72 73 74
    case 5:
      nb_periods_per_frame = 4; // 10ms/2p5ms
      break;
Raymond Knopp's avatar
Raymond Knopp committed
75

76 77 78
    case 6:
      nb_periods_per_frame = 2; // 10ms/5ms
      break;
Raymond Knopp's avatar
Raymond Knopp committed
79

80 81 82
    case 7:
      nb_periods_per_frame = 1; // 10ms/10ms
      break;
Raymond Knopp's avatar
Raymond Knopp committed
83

84 85 86 87 88
    default:
      AssertFatal(1==0,"Undefined tdd period %d\n", cfg->tdd_table.tdd_period);
  }

  int nb_slots_per_period = ((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME)/nb_periods_per_frame;
Sakthivel Velumani's avatar
fixes  
Sakthivel Velumani committed
89
  cfg->tdd_table.tdd_period_in_slots = nb_slots_per_period;
90 91 92 93 94 95 96 97 98 99 100

  if ( (nrofDownlinkSymbols + nrofUplinkSymbols) == 0 )
    AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots),
                "set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, nrofUplinkSlots %d, nb_slots_per_period %d \n",
                nrofDownlinkSlots,nrofUplinkSlots,nb_slots_per_period);
  else {
    AssertFatal(nrofDownlinkSymbols + nrofUplinkSymbols < 14,"illegal symbol configuration DL %d, UL %d\n",nrofDownlinkSymbols,nrofUplinkSymbols);
    AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots + 1),
                "set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, nrofUplinkSlots %d, nrofMixed slots 1, nb_slots_per_period %d \n",
                nrofDownlinkSlots,nrofUplinkSlots,nb_slots_per_period);
  }
Raymond Knopp's avatar
Raymond Knopp committed
101

102
  cfg->tdd_table.max_tdd_periodicity_list = (fapi_nr_max_tdd_periodicity_t *) malloc(nb_slots_to_set*sizeof(fapi_nr_max_tdd_periodicity_t));
Raymond Knopp's avatar
Raymond Knopp committed
103

104 105 106
  for(int memory_alloc =0 ; memory_alloc<nb_slots_to_set; memory_alloc++)
    cfg->tdd_table.max_tdd_periodicity_list[memory_alloc].max_num_of_symbol_per_slot_list = (fapi_nr_max_num_of_symbol_per_slot_t *) malloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT*sizeof(
          fapi_nr_max_num_of_symbol_per_slot_t));
Raymond Knopp's avatar
Raymond Knopp committed
107

108 109 110 111
  while(slot_number != nb_slots_to_set) {
    if(nrofDownlinkSlots != 0) {
      for (int number_of_symbol = 0; number_of_symbol < nrofDownlinkSlots*NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
        cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config= 0;
Raymond Knopp's avatar
Raymond Knopp committed
112

113 114 115 116
        if((number_of_symbol+1)%NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
          slot_number++;
      }
    }
Raymond Knopp's avatar
Raymond Knopp committed
117

118 119 120 121
    if (nrofDownlinkSymbols != 0 || nrofUplinkSymbols != 0) {
      for(int number_of_symbol =0; number_of_symbol < nrofDownlinkSymbols; number_of_symbol++) {
        cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config= 0;
      }
Raymond Knopp's avatar
Raymond Knopp committed
122

123 124 125
      for(int number_of_symbol = nrofDownlinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT-nrofUplinkSymbols; number_of_symbol++) {
        cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config= 2;
      }
Raymond Knopp's avatar
Raymond Knopp committed
126

127 128 129
      for(int number_of_symbol = NR_NUMBER_OF_SYMBOLS_PER_SLOT-nrofUplinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
        cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config= 1;
      }
Raymond Knopp's avatar
Raymond Knopp committed
130

131 132
      slot_number++;
    }
Raymond Knopp's avatar
Raymond Knopp committed
133

134 135 136
    if(nrofUplinkSlots != 0) {
      for (int number_of_symbol = 0; number_of_symbol < nrofUplinkSlots*NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
        cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config= 1;
Raymond Knopp's avatar
Raymond Knopp committed
137

138 139 140 141 142
        if((number_of_symbol+1)%NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
          slot_number++;
      }
    }
  }
Raymond Knopp's avatar
Raymond Knopp committed
143

144 145
  return (0);
}
Raymond Knopp's avatar
Raymond Knopp committed
146 147


148 149 150
void config_common_ue(NR_UE_MAC_INST_t *mac,
		      module_id_t       module_id,
		      int               cc_idP) {
Raymond Knopp's avatar
Raymond Knopp committed
151

152 153
  fapi_nr_config_request_t        *cfg = &mac->phy_config.config_req;
  NR_ServingCellConfigCommon_t    *scc = mac->scc;
154
  NR_ServingCellConfigCommonSIB_t *scc_SIB = mac->scc_SIB;
155
  int i;
Raymond Knopp's avatar
Raymond Knopp committed
156

cig's avatar
cig committed
157 158
  mac->phy_config.Mod_id = module_id;
  mac->phy_config.CC_id = cc_idP;
159
  
160
  // carrier config
cig's avatar
cig committed
161
  LOG_D(MAC, "Entering UE Config Common\n");
162

163 164 165 166 167 168 169 170 171 172 173 174 175
  AssertFatal(scc==NULL || scc_SIB==NULL,"Both scc and scc_SIB cannot be null\n");

  if (scc) {
    cfg->carrier_config.dl_bandwidth = config_bandwidth(scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
							scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
							*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
    
    cfg->carrier_config.dl_frequency = from_nrarfcn(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],
						    *scc->ssbSubcarrierSpacing,
						    scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA)/1000; // freq in kHz
    
    for (i=0; i<5; i++) {
      if (i==scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
176 177
        cfg->carrier_config.dl_grid_size[i] = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
        cfg->carrier_config.dl_k0[i] = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
178 179
      }
      else {
180 181
        cfg->carrier_config.dl_grid_size[i] = 0;
        cfg->carrier_config.dl_k0[i] = 0;
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
      }
    }
    
    cfg->carrier_config.uplink_bandwidth = config_bandwidth(scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
							    scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
							    *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]);
    
    int UL_pointA;
    if (scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA == NULL)
      UL_pointA = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
    else
      UL_pointA = *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA; 
    
    cfg->carrier_config.uplink_frequency = from_nrarfcn(*scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0],
							*scc->ssbSubcarrierSpacing,
							UL_pointA)/1000; // freq in kHz
    
    
    for (i=0; i<5; i++) {
      if (i==scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
	cfg->carrier_config.ul_grid_size[i] = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
	cfg->carrier_config.ul_k0[i] = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
      }
      else {
	cfg->carrier_config.ul_grid_size[i] = 0;
	cfg->carrier_config.ul_k0[i] = 0;
      }
    }
    
    uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
212
    mac->frequency_range = band<100?FR1:FR2;
213 214
    
    lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
215

216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
    // cell config
    
    cfg->cell_config.phy_cell_id = *scc->physCellId;
    cfg->cell_config.frame_duplex_type = frame_type;
    
    // SSB config
    cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower;
    cfg->ssb_config.scs_common = *scc->ssbSubcarrierSpacing;
    
    // SSB Table config
    int scs_scaling = 1<<(cfg->ssb_config.scs_common);
    if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000)
      scs_scaling = scs_scaling*3;
    if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666)
      scs_scaling = scs_scaling>>2;
    uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
    cfg->ssb_table.ssb_offset_point_a = absolute_diff/(12*scs_scaling) - 10;
    cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell;
    cfg->ssb_table.ssb_subcarrier_offset = 0; // TODO currently not in RRC?
235

236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
    switch (scc->ssb_PositionsInBurst->present) {
    case 1 :
      cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0]<<24;
      cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
      break;
    case 2 :
      cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]<<24;
      cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
      break;
    case 3 :
      cfg->ssb_table.ssb_mask_list[0].ssb_mask = 0;
      cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
      for (i=0; i<4; i++) {
        cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[3-i]<<i*8);
        cfg->ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-i]<<i*8);
      }
      break;
    default:
      AssertFatal(1==0,"SSB bitmap size value %d undefined (allowed values 1,2,3) \n", scc->ssb_PositionsInBurst->present);
    }
    
    // TDD Table Configuration
    if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 == NULL)
      cfg->tdd_table.tdd_period = scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity;
    else {
      AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL,
		  "scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n");
      cfg->tdd_table.tdd_period = *scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
    }
    if(cfg->cell_config.frame_duplex_type == TDD){
      LOG_I(MAC,"Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period);
      int return_tdd = set_tdd_config_nr_ue(cfg,
					    scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
					    scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots,
					    scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,
					    scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
					    scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols
					    );
      
      if (return_tdd !=0)
	LOG_E(PHY,"TDD configuration can not be done\n");
      else
	LOG_I(PHY,"TDD has been properly configurated\n");
    }
    
    // PRACH configuration
    
    uint8_t nb_preambles = 64;
    if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
      nb_preambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
    
    cfg->prach_config.prach_sequence_length = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1;
    
    if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
      cfg->prach_config.prach_sub_c_spacing = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
    else 
      cfg->prach_config.prach_sub_c_spacing = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
    
    cfg->prach_config.restricted_set_config = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig;
    
    switch (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) {
    case 0 :
      cfg->prach_config.num_prach_fd_occasions = 1;
      break;
    case 1 :
      cfg->prach_config.num_prach_fd_occasions = 2;
      break;
    case 2 :
      cfg->prach_config.num_prach_fd_occasions = 4;
      break;
    case 3 :
      cfg->prach_config.num_prach_fd_occasions = 8;
      break;
    default:
      AssertFatal(1==0,"msg1 FDM identifier %ld undefined (0,1,2,3) \n", scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM);
    }
    
    cfg->prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t));
    for (i=0; i<cfg->prach_config.num_prach_fd_occasions; i++) {
      cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
      if (cfg->prach_config.prach_sequence_length)
rmagueta's avatar
rmagueta committed
317
	      cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139;
318
      else
rmagueta's avatar
rmagueta committed
319
	      cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
320 321 322
      
      cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart;
      cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
323 324
      cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup,
                                                                                                nb_preambles, frame_type,mac->frequency_range);
325 326 327 328 329 330
      //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ???
    }

    cfg->prach_config.ssb_per_rach = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
    
  } // scc
Raymond Knopp's avatar
Raymond Knopp committed
331

332 333 334 335 336 337 338
  else { // scc_SIB

  cfg->carrier_config.dl_bandwidth = config_bandwidth(scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
                                                      scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
                                                      *scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR);

  cfg->carrier_config.dl_frequency = downlink_frequency[0][0] - (10+scc_SIB->downlinkConfigCommon.frequencyInfoDL.offsetToPointA)*(15<<scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); 
Raymond Knopp's avatar
Raymond Knopp committed
339

340
  for (i=0; i<5; i++) {
341 342 343
    if (i==scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
      cfg->carrier_config.dl_grid_size[i] = scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
      cfg->carrier_config.dl_k0[i] = scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
344 345 346 347 348
    }
    else {
      cfg->carrier_config.dl_grid_size[i] = 0;
      cfg->carrier_config.dl_k0[i] = 0;
    }
Raymond Knopp's avatar
Raymond Knopp committed
349 350
  }

351 352
  cfg->carrier_config.uplink_bandwidth = config_bandwidth(scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
                                                          scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
353
                                                          scc_SIB->uplinkConfigCommon->frequencyInfoUL.frequencyBandList==NULL ? *scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR : *scc_SIB->uplinkConfigCommon->frequencyInfoUL.frequencyBandList->list.array[0]->freqBandIndicatorNR);
354 355


356 357 358 359 360 361 362
  if (scc_SIB->uplinkConfigCommon->frequencyInfoUL.absoluteFrequencyPointA == NULL)
    cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency;
  else  
    cfg->carrier_config.uplink_frequency = from_nrarfcn(*scc_SIB->uplinkConfigCommon->frequencyInfoUL.frequencyBandList->list.array[0]->freqBandIndicatorNR,
							scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
							*scc_SIB->uplinkConfigCommon->frequencyInfoUL.absoluteFrequencyPointA)/1000; // freq in kHz
    
363 364

  for (i=0; i<5; i++) {
365 366 367
    if (i==scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
      cfg->carrier_config.ul_grid_size[i] = scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
      cfg->carrier_config.ul_k0[i] = scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
368 369 370 371 372
    }
    else {
      cfg->carrier_config.ul_grid_size[i] = 0;
      cfg->carrier_config.ul_k0[i] = 0;
    }
Raymond Knopp's avatar
Raymond Knopp committed
373
  }
374

375
  uint32_t band = *scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR;
376 377
  frequency_range_t  frequency_range = band<100?FR1:FR2;
 
378
  lte_frame_type_t frame_type = get_frame_type(band, get_softmodem_params()->numerology);
Francesco Mani's avatar
Francesco Mani committed
379

380 381
  // cell config

382 383
  cfg->cell_config.phy_cell_id = mac->physCellId;
  cfg->cell_config.frame_duplex_type = frame_type;
384 385

  // SSB config
386 387
  cfg->ssb_config.ss_pbch_power = scc_SIB->ss_PBCH_BlockPower;
  cfg->ssb_config.scs_common = get_softmodem_params()->numerology;
388 389

  // SSB Table config
390 391 392

  cfg->ssb_table.ssb_offset_point_a = scc_SIB->downlinkConfigCommon.frequencyInfoDL.offsetToPointA;
  cfg->ssb_table.ssb_period = scc_SIB->ssb_PeriodicityServingCell;
393
  cfg->ssb_table.ssb_subcarrier_offset = 0; // TODO currently not in RRC?
394

395 396 397 398 399 400 401 402 403 404 405 406
  AssertFatal(scc_SIB->ssb_PositionsInBurst.groupPresence==NULL, "Cannot handle more than 8 SSBs for now (%x.%x.%x.%x.%x.%x.%x.%x)\n",
	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[0],
	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[1],
	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[2],
	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[3],
	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[4],
	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[5],
	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[6],
	      scc_SIB->ssb_PositionsInBurst.groupPresence->buf[7]);
  cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc_SIB->ssb_PositionsInBurst.inOneGroup.buf[0]<<24;
  cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
 
407 408

  // TDD Table Configuration
409 410
  if (scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 == NULL)
    cfg->tdd_table.tdd_period = scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity;
411
  else {
412 413 414
    AssertFatal(scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL,
		"scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n");
    cfg->tdd_table.tdd_period = *scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
415 416
  }
  if(cfg->cell_config.frame_duplex_type == TDD){
cig's avatar
cig committed
417
    LOG_I(MAC,"Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period);
418
    int return_tdd = set_tdd_config_nr_ue(cfg,
419 420 421 422 423
		     scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
                     scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots,
                     scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,
                     scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
                     scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols
424 425 426 427 428 429 430 431
                     );

    if (return_tdd !=0)
      LOG_E(PHY,"TDD configuration can not be done\n");
    else
      LOG_I(PHY,"TDD has been properly configurated\n");
  }

Francesco Mani's avatar
Francesco Mani committed
432 433 434
  // PRACH configuration

  uint8_t nb_preambles = 64;
435 436
  if(scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
     nb_preambles = *scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
Francesco Mani's avatar
Francesco Mani committed
437

438
  cfg->prach_config.prach_sequence_length = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1;
Francesco Mani's avatar
Francesco Mani committed
439

440 441
  if (scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
    cfg->prach_config.prach_sub_c_spacing = *scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
Francesco Mani's avatar
Francesco Mani committed
442
  else 
443
    cfg->prach_config.prach_sub_c_spacing = scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
Francesco Mani's avatar
Francesco Mani committed
444

445
  cfg->prach_config.restricted_set_config = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->restrictedSetConfig;
Francesco Mani's avatar
Francesco Mani committed
446

447
  switch (scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) {
Francesco Mani's avatar
Francesco Mani committed
448 449 450 451 452 453 454 455 456 457 458 459 460
    case 0 :
      cfg->prach_config.num_prach_fd_occasions = 1;
      break;
    case 1 :
      cfg->prach_config.num_prach_fd_occasions = 2;
      break;
    case 2 :
      cfg->prach_config.num_prach_fd_occasions = 4;
      break;
    case 3 :
      cfg->prach_config.num_prach_fd_occasions = 8;
      break;
    default:
461
      AssertFatal(1==0,"msg1 FDM identifier %ld undefined (0,1,2,3) \n", scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM);
Francesco Mani's avatar
Francesco Mani committed
462 463 464 465 466 467
  }

  cfg->prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t));
  for (i=0; i<cfg->prach_config.num_prach_fd_occasions; i++) {
    cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
    if (cfg->prach_config.prach_sequence_length)
468
      cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139; 
Francesco Mani's avatar
Francesco Mani committed
469
    else
470
      cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
471
    cfg->prach_config.num_prach_fd_occasions_list[i].k1 = NRRIV2PRBOFFSET(scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE) + scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing, scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
472
    cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
473
    cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup, nb_preambles, mac->frame_type, frequency_range);
Francesco Mani's avatar
Francesco Mani committed
474 475 476
    //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ???
  }

477 478 479 480 481
  cfg->prach_config.ssb_per_rach = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;


  }
    
Raymond Knopp's avatar
Raymond Knopp committed
482 483
}

484 485 486 487
/** \brief This function performs some configuration routines according to clause 12 "Bandwidth part operation" 3GPP TS 38.213 version 16.3.0 Release 16
    @param NR_UE_MAC_INST_t mac: pointer to local MAC instance
    @returns void
    */
488

489
void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format){
490

491
  NR_ServingCellConfig_t *scd = mac->cg->spCellConfig->spCellConfigDedicated;
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514

  if (bwp_ind && dci_format){

    switch(*dci_format){
    case NR_UL_DCI_FORMAT_0_1:
      mac->UL_BWP_Id = *bwp_ind;
      break;
    case NR_DL_DCI_FORMAT_1_1:
      mac->DL_BWP_Id = *bwp_ind;
      break;
    default:
      LOG_E(MAC, "In %s: failed to configure BWP Id from DCI with format %d \n", __FUNCTION__, *dci_format);
    }

  } else {

    if (scd->firstActiveDownlinkBWP_Id)
      mac->DL_BWP_Id = *scd->firstActiveDownlinkBWP_Id;
    else if (scd->defaultDownlinkBWP_Id)
      mac->DL_BWP_Id = *scd->defaultDownlinkBWP_Id;
    else
      mac->DL_BWP_Id = 1;

515 516 517 518
    if (scd->uplinkConfig && scd->uplinkConfig->firstActiveUplinkBWP_Id)
      mac->UL_BWP_Id = *scd->uplinkConfig->firstActiveUplinkBWP_Id;
    else
      mac->UL_BWP_Id = 1;
519 520 521 522 523 524 525

  }

  LOG_D(MAC, "In %s setting DL_BWP_Id %ld UL_BWP_Id %ld \n", __FUNCTION__, mac->DL_BWP_Id, mac->UL_BWP_Id);

}

526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589

void fill_default_coreset_zero(NR_UE_MAC_INST_t *mac) {

  // Search space zero

  if(mac->search_space_zero == NULL) mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero));
  if(mac->search_space_zero->controlResourceSetId == NULL) mac->search_space_zero->controlResourceSetId=calloc(1,sizeof(*mac->search_space_zero->controlResourceSetId));
  if(mac->search_space_zero->monitoringSymbolsWithinSlot == NULL) mac->search_space_zero->monitoringSymbolsWithinSlot = calloc(1,sizeof(*mac->search_space_zero->monitoringSymbolsWithinSlot));
  if(mac->search_space_zero->monitoringSymbolsWithinSlot->buf == NULL) mac->search_space_zero->monitoringSymbolsWithinSlot->buf = calloc(1,2);
  if(mac->search_space_zero->nrofCandidates == NULL) mac->search_space_zero->nrofCandidates = calloc(1,sizeof(*mac->search_space_zero->nrofCandidates));
  if(mac->search_space_zero->searchSpaceType == NULL) mac->search_space_zero->searchSpaceType = calloc(1,sizeof(*mac->search_space_zero->searchSpaceType));
  if(mac->search_space_zero->searchSpaceType->choice.common == NULL) mac->search_space_zero->searchSpaceType->choice.common=calloc(1,sizeof(*mac->search_space_zero->searchSpaceType->choice.common));
  if(mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 == NULL) mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0));
  mac->search_space_zero->searchSpaceId = 0;
  *mac->search_space_zero->controlResourceSetId = 0;
  mac->search_space_zero->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*mac->search_space_zero->monitoringSlotPeriodicityAndOffset));
  mac->search_space_zero->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1;
  mac->search_space_zero->duration=NULL;
  // should be '1100 0000 0000 00'B (LSB first!), first two symbols in slot, adjust if needed
  mac->search_space_zero->monitoringSymbolsWithinSlot->buf[1] = 0;
  mac->search_space_zero->monitoringSymbolsWithinSlot->buf[0] = (1<<7);
  mac->search_space_zero->monitoringSymbolsWithinSlot->size = 2;
  mac->search_space_zero->monitoringSymbolsWithinSlot->bits_unused = 2;

  // FIXME: update values from TS38.213 Section 10.1 Table 10.1-1: CCE aggregation levels and maximum number of PDCCH candidates per CCE aggregation level for CSS sets configured by searchSpaceSIB1
  mac->search_space_zero->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
  mac->search_space_zero->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
  mac->search_space_zero->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2;
  mac->search_space_zero->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
  mac->search_space_zero->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
  mac->search_space_zero->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common;

  // Coreset0
  if(mac->coreset0 == NULL) mac->coreset0 = calloc(1,sizeof(*mac->coreset0));
  mac->coreset0->controlResourceSetId = 0;
  // frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B,
  if(mac->coreset0->frequencyDomainResources.buf == NULL) mac->coreset0->frequencyDomainResources.buf = calloc(1,6);
  mac->coreset0->frequencyDomainResources.buf[0] = 0xff;
  mac->coreset0->frequencyDomainResources.buf[1] = 0;
  mac->coreset0->frequencyDomainResources.buf[2] = 0;
  mac->coreset0->frequencyDomainResources.buf[3] = 0;
  mac->coreset0->frequencyDomainResources.buf[4] = 0;
  mac->coreset0->frequencyDomainResources.buf[5] = 0;
  mac->coreset0->frequencyDomainResources.size = 6;
  mac->coreset0->frequencyDomainResources.bits_unused = 3;
  mac->coreset0->duration = 1;
  mac->coreset0->cce_REG_MappingType.present=NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved;
  mac->coreset0->cce_REG_MappingType.choice.interleaved=calloc(1,sizeof(*mac->coreset0->cce_REG_MappingType.choice.interleaved));
  mac->coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6;
  mac->coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2;
  mac->coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = NULL;
  mac->coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
  if(mac->coreset0->tci_StatesPDCCH_ToAddList == NULL) mac->coreset0->tci_StatesPDCCH_ToAddList = calloc(1,sizeof(*mac->coreset0->tci_StatesPDCCH_ToAddList));
  NR_TCI_StateId_t *tci[8];
  for (int i=0;i<8;i++) {
    tci[i]=calloc(1,sizeof(*tci[i]));
    *tci[i] = i;
    ASN_SEQUENCE_ADD(&mac->coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]);
  }
  mac->coreset0->tci_StatesPDCCH_ToReleaseList = NULL;
  mac->coreset0->tci_PresentInDCI = NULL;
  mac->coreset0->pdcch_DMRS_ScramblingID = NULL;
}

590 591 592 593 594 595 596
/** \brief This function is relavant for the UE procedures for control. It loads the search spaces, the BWPs and the CORESETs into the MAC instance and
    \brief performs assert checks on the relevant RRC configuration.
    @param NR_UE_MAC_INST_t mac: pointer to local MAC instance
    @returns void
    */
void config_control_ue(NR_UE_MAC_INST_t *mac){

597 598
  uint8_t coreset_id = 1, ss_id;

599
  NR_ServingCellConfig_t *scd = mac->cg->spCellConfig->spCellConfigDedicated;
600 601 602
  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);

603
  config_bwp_ue(mac, NULL, NULL);
604 605
  NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id;
  AssertFatal(dl_bwp_id != 0, "DL_BWP_Id is 0!");
606 607

  NR_BWP_DownlinkCommon_t *bwp_Common = scd->downlinkBWP_ToAddModList->list.array[dl_bwp_id - 1]->bwp_Common;
608 609
  AssertFatal(bwp_Common != NULL, "bwp_Common is null\n");

610
  NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated = scd->downlinkBWP_ToAddModList->list.array[dl_bwp_id - 1]->bwp_Dedicated;
611 612
  AssertFatal(dl_bwp_Dedicated != NULL, "dl_bwp_Dedicated is null\n");

613
  NR_SetupRelease_PDCCH_Config_t *pdcch_Config = dl_bwp_Dedicated->pdcch_Config;
614 615
  AssertFatal(pdcch_Config != NULL, "pdcch_Config is null\n");

616
  NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
617 618 619
  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");

620
  struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
621 622 623
  AssertFatal(commonSearchSpaceList != NULL, "commonSearchSpaceList is null\n");
  AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH CSS list has 0 elements\n");

624
  struct NR_PDCCH_Config__controlResourceSetToAddModList *controlResourceSetToAddModList = pdcch_Config->choice.setup->controlResourceSetToAddModList;
625 626 627 628
  AssertFatal(controlResourceSetToAddModList != NULL, "controlResourceSetToAddModList is null\n");
  AssertFatal(controlResourceSetToAddModList->list.count == 1, "controlResourceSetToAddModList->list.count=%d\n", controlResourceSetToAddModList->list.count);
  AssertFatal(controlResourceSetToAddModList->list.array[0] != NULL, "coreset[0][0] is null\n");

629
  struct NR_PDCCH_Config__searchSpacesToAddModList *searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList;
630 631 632 633
  AssertFatal(searchSpacesToAddModList != NULL, "searchSpacesToAddModList is null\n");
  AssertFatal(searchSpacesToAddModList->list.count > 0, "list of UE specifically configured Search Spaces is empty\n");
  AssertFatal(searchSpacesToAddModList->list.count < FAPI_NR_MAX_SS_PER_CORESET, "too many searchpaces per coreset %d\n", searchSpacesToAddModList->list.count);

634
  struct NR_UplinkConfig__uplinkBWP_ToAddModList *uplinkBWP_ToAddModList = scd->uplinkConfig->uplinkBWP_ToAddModList;
635 636
  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);
637 638

  // check pdcch_Config, pdcch_ConfigCommon and DL BWP
639 640
  mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[dl_bwp_id - 1];
  mac->coreset[dl_bwp_id - 1][coreset_id - 1] = controlResourceSetToAddModList->list.array[0];
641 642 643 644 645 646 647 648 649 650 651

  // Check dedicated UL BWP and pass to MAC
  mac->ULbwp[0] = uplinkBWP_ToAddModList->list.array[0];
  AssertFatal(mac->ULbwp[0]->bwp_Dedicated != NULL, "UL bwp_Dedicated is null\n");

  // check available Search Spaces in the searchSpacesToAddModList and pass to MAC
  // note: the network configures at most 10 Search Spaces per BWP per cell (including UE-specific and common Search Spaces).
  for (ss_id = 0; ss_id < searchSpacesToAddModList->list.count; ss_id++) {
    NR_SearchSpace_t *ss = searchSpacesToAddModList->list.array[ss_id];
    AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
    AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n");
652
    AssertFatal(*ss->controlResourceSetId == mac->coreset[dl_bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n");
653 654 655 656 657 658 659 660 661 662
    AssertFatal(ss->monitoringSymbolsWithinSlot != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot is null\n");
    AssertFatal(ss->monitoringSymbolsWithinSlot->buf != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot->buf is null\n");
    mac->SSpace[0][0][ss_id] = ss;
  }

  // Check available CSSs in the commonSearchSpaceList (list of additional common search spaces)
  // note: commonSearchSpaceList SIZE(1..4)
  for (int css_id = 0; css_id < commonSearchSpaceList->list.count; css_id++) {
    NR_SearchSpace_t *css = commonSearchSpaceList->list.array[css_id];
    AssertFatal(css->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
663
    AssertFatal(*css->controlResourceSetId == mac->coreset[dl_bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n");
664 665 666 667 668 669
    AssertFatal(css->searchSpaceType != NULL, "css->searchSpaceType is null\n");
    AssertFatal(css->monitoringSymbolsWithinSlot != NULL, "css->monitoringSymbolsWithinSlot is null\n");
    AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n");
    mac->SSpace[0][0][ss_id] = css;
    ss_id++;
  }
670

671
  fill_default_coreset_zero(mac);
672

673 674
}

675
int nr_rrc_mac_config_req_ue(
676
    module_id_t                     module_id,
677
    int                             cc_idP,
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
678
    uint8_t                         gNB_index,
679
    NR_MIB_t                        *mibP,
680
    NR_ServingCellConfigCommonSIB_t *sccP,
681 682
    //    NR_MAC_CellGroupConfig_t        *mac_cell_group_configP,
    //    NR_PhysicalCellGroupConfig_t    *phy_cell_group_configP,
683 684
    NR_CellGroupConfig_t            *cell_group_config,
    NR_CellGroupConfig_t            *scell_group_config){
685

686
    NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
687
    RA_config_t *ra = &mac->ra;
688

689
    //  TODO do something FAPI-like P5 L1/L2 config interface in config_si, config_mib, etc.
690

691
    if(mibP != NULL){
692 693 694 695

      // if this is the first MIB intialize coreset0 for SA
      if (mac->mib == NULL) fill_default_coreset_zero(mac);

696
      mac->mib = mibP;    //  update by every reception
697 698 699 700
      mac->phy_config.Mod_id = module_id;
      mac->phy_config.CC_id = cc_idP;
      mac->phy_config.config_req.ssb_table.ssb_subcarrier_offset = 0; // TODO currently not in RRC?
      mac->phy_config.config_req.tdd_table.tdd_period_in_slots=5<<get_softmodem_params()->numerology;
701
      mac->phy_config.config_req.ssb_table.ssb_offset_point_a = (N_RB_DL-20)>>1;
702
    }
703 704 705 706
    AssertFatal(scell_group_config == NULL || cell_group_config == NULL,
		"both scell_group_config and cell_group_config cannot be non-NULL\n");
    
    if (sccP != NULL) {
707

708 709
      mac->scc_SIB=sccP;
      LOG_I(MAC,"Keeping ServingCellConfigCommonSIB\n");
710
      config_common_ue(mac,module_id,cc_idP);
711 712 713 714 715 716 717 718
      int num_slots_ul = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
      if (mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols>0) num_slots_ul++;
      LOG_I(MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul);
      mac->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t));
      // Setup the SSB to Rach Occasions mapping according to the config
      build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type);
      mac->if_module->phy_config_request(&mac->phy_config);
      mac->common_configuration_complete = 1;
719 720
    }
    if(scell_group_config != NULL ){
rmagueta's avatar
rmagueta committed
721
      mac->cg = scell_group_config;
722
      mac->servCellIndex = *scell_group_config->spCellConfig->servCellIndex;
723
      config_control_ue(mac);
724 725 726
      if (scell_group_config->spCellConfig->reconfigurationWithSync) {
        if (scell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) {
          ra->rach_ConfigDedicated = scell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
727
        }
728
        mac->scc = scell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
rmagueta's avatar
rmagueta committed
729
	      mac->physCellId = *mac->scc->physCellId;
730
        config_common_ue(mac,module_id,cc_idP);
731
        mac->crnti = scell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity;
732
        LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
733 734
      }

735
      // Setup the SSB to Rach Occasions mapping according to the config
736
      build_ssb_to_ro_map(mac);
737
    }
738
    else if (cell_group_config != NULL){
739
      LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
740
      mac->cg = cell_group_config;
741
      mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0;
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
      if(get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) {
        config_control_ue(mac);
        if (cell_group_config->spCellConfig->reconfigurationWithSync) {
          if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) {
            ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
          }
          mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
          config_common_ue(mac,module_id,cc_idP);
          mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity;
          LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
        }

        // Setup the SSB to Rach Occasions mapping according to the config
        build_ssb_to_ro_map(mac);
      }

758 759 760 761 762 763 764 765 766 767 768 769 770 771 772
      /*      
      if(mac_cell_group_configP != NULL){
	if(mac_cell_group_configP->drx_Config != NULL ){
	  switch(mac_cell_group_configP->drx_Config->present){
	  case NR_SetupRelease_DRX_Config_PR_NOTHING:
	    break;
	  case NR_SetupRelease_DRX_Config_PR_release:
	    mac->drx_Config = NULL;
	    break;
	  case NR_SetupRelease_DRX_Config_PR_setup:
	    mac->drx_Config = mac_cell_group_configP->drx_Config->choice.setup;
	    break;
	  default:
	    break;
	  }
Raymond Knopp's avatar
Raymond Knopp committed
773
	}
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820
	
	if(mac_cell_group_configP->schedulingRequestConfig != NULL ){
	  mac->schedulingRequestConfig = mac_cell_group_configP->schedulingRequestConfig;
	}
	
	if(mac_cell_group_configP->bsr_Config != NULL ){
	  mac->bsr_Config = mac_cell_group_configP->bsr_Config;
	}
	
	if(mac_cell_group_configP->tag_Config != NULL ){
	  mac->tag_Config = mac_cell_group_configP->tag_Config;
	}
	
	if(mac_cell_group_configP->phr_Config != NULL ){
	  switch(mac_cell_group_configP->phr_Config->present){
	  case NR_SetupRelease_PHR_Config_PR_NOTHING:
	    break;
	  case NR_SetupRelease_PHR_Config_PR_release:
	    mac->phr_Config = NULL;
	    break;
	  case NR_SetupRelease_PHR_Config_PR_setup:
	    mac->phr_Config = mac_cell_group_configP->phr_Config->choice.setup;
	    break;
	  default:
	    break;
	  }        
	}
      }
      
      
      if(phy_cell_group_configP != NULL ){
	if(phy_cell_group_configP->cs_RNTI != NULL ){
	  switch(phy_cell_group_configP->cs_RNTI->present){
	  case NR_SetupRelease_RNTI_Value_PR_NOTHING:
	    break;
	  case NR_SetupRelease_RNTI_Value_PR_release:
	    mac->cs_RNTI = NULL;
	    break;
	  case NR_SetupRelease_RNTI_Value_PR_setup:
	    mac->cs_RNTI = &phy_cell_group_configP->cs_RNTI->choice.setup;
	    break;
	  default:
	    break;
	  }
	}
      }
      */
821 822
    }

823
    return 0;
824

825
}